金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 579|回复: 7

无法发送邮件,无法回测请查看以下代码并回复谢谢

[复制链接]

1

主题

4

帖子

4

积分

Rank: 1

等级: 新手上路

注册:
2023-10-10
曾用名:
发表于 2025-2-21 08:30 | 显示全部楼层 |阅读模式
import pandas as pd
import talib
import smtplib
from email.mime.text import MIMEText
from email.header import Header


# 邮件配置
SMTP_SERVER = 'smtp.163.com'  # SMTP服务器地址
SMTP_PORT = 465                   # SMTP服务器端口
SENDER_EMAIL = 'ly8040661@163.com'  # 发件人邮箱
SENDER_PASSWORD = 'FXMAXTHKWDHETGOR'        # 发件人邮箱密码
RECEIVER_EMAIL = '188381294@qq.com'  # 收件人邮箱

# 关注的期货品种
TARGET_SYMBOLS = ['RB', 'I', 'SC']  # 例如:螺纹钢(RB)、铁矿石(I)、原油(SC)



def send_email(subject, body):
    """
    发送邮件
    :param subject: 邮件主题
    :param body: 邮件内容
    """
    try:
        # 创建邮件对象
        msg = MIMEText(body, 'plain', 'utf-8')
        msg['From'] = Header(SENDER_EMAIL)
        msg['To'] = Header(RECEIVER_EMAIL)
        msg['Subject'] = Header(subject, 'utf-8')

        # 连接SMTP服务器并发送邮件
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            server.starttls()  # 启用TLS加密
            server.login(SENDER_EMAIL, SENDER_PASSWORD)
            server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, msg.as_string())
        print("邮件发送成功!")
    except Exception as e:
        print(f"邮件发送失败: {e}")

# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
    # 在context中设置一些参数
    context.s1 = context.run_info.base_book_id  # 交易品种
    context.target_symbols = ['RB', 'I', 'SC']  # 关注的期货品种(螺纹钢、铁矿石、原油)

    # EMA周期
    context.ema_short_period = 13
    context.ema_long_period = 26

    # KD指标参数
    context.kd_fastk_period = 14
    context.kd_slowk_period = 3
    context.kd_slowd_period = 3

# before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次
def before_trading(context):
    pass

# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context):
    # 开始编写你的主要的算法逻辑
    for symbol in context.target_symbols:
        # 获取历史数据
        daily_data = history_bars(symbol, context.ema_long_period + 1, '1d', ['close', 'high', 'low'], True)
        min30_data = history_bars(symbol, context.ema_long_period + 1, '30m', ['close', 'high', 'low'], True)

        # if len(daily_data) < context.ema_long_period + 1 or len(min30_data) < context.ema_long_period + 1:
            # continue  # 数据不足,跳过

        # 计算EMA和KD指标
        daily_data['EMA13'] = ta.EMA(daily_data['close'], timeperiod=context.ema_short_period)
        daily_data['EMA26'] = ta.EMA(daily_data['close'], timeperiod=context.ema_long_period)
        daily_data['EMA26_slope'] = daily_data['EMA26'].diff()

        min30_data['EMA13'] = ta.EMA(min30_data['close'], timeperiod=context.ema_short_period)
        min30_data['EMA26'] = ta.EMA(min30_data['close'], timeperiod=context.ema_long_period)
        min30_data['slowk'], min30_data['slowd'] = ta.STOCH(
            min30_data['high'], min30_data['low'], min30_data['close'],
            fastk_period=context.kd_fastk_period,
            slowk_period=context.kd_slowk_period,
            slowd_period=context.kd_slowd_period
        )

        # 生成信号
        long_signal = False
        short_signal = False

        # 1.1 基于KD上穿的做多信号
        condition1_1 = (
            (daily_data['EMA13'][-1] > daily_data['EMA26'][-1]) and  # 日线EMA13 > EMA26
            (daily_data['EMA26_slope'][-1] > 0) and                  # 日线EMA26斜率 > 0
            (min30_data['EMA13'][-1] > min30_data['EMA26'][-1]) and  # 30分钟EMA13 > EMA26
            (min30_data['slowk'][-2] < min30_data['slowd'][-2]) and  # 30分钟KD上穿
            (min30_data['slowk'][-1] > min30_data['slowd'][-1])
        )

        # 1.2 基于KD超卖的做多信号
        condition1_2 = (
            (daily_data['EMA13'][-1] > daily_data['EMA26'][-1]) and  # 日线EMA13 > EMA26
            (daily_data['EMA26_slope'][-1] > 0) and                  # 日线EMA26斜率 > 0
            (min30_data['EMA13'][-1] > min30_data['EMA26'][-1]) and  # 30分钟EMA13 > EMA26
            (min30_data['slowk'][-1] < 20)                           # 30分钟K值 < 20
        )

        # 2.1 基于KD下穿的做空信号
        condition2_1 = (
            (daily_data['EMA13'][-1] < daily_data['EMA26'][-1]) and  # 日线EMA13 < EMA26
            (daily_data['EMA26_slope'][-1] < 0) and                  # 日线EMA26斜率 < 0
            (min30_data['EMA13'][-1] < min30_data['EMA26'][-1]) and  # 30分钟EMA13 < EMA26
            (min30_data['slowk'][-2] > min30_data['slowd'][-2]) and  # 30分钟KD下穿
            (min30_data['slowk'][-1] < min30_data['slowd'][-1])
        )

        # 2.2 基于KD超买的做空信号
        condition2_2 = (
            (daily_data['EMA13'][-1] < daily_data['EMA26'][-1]) and  # 日线EMA13 < EMA26
            (daily_data['EMA26_slope'][-1] < 0) and                  # 日线EMA26斜率 < 0
            (min30_data['EMA13'][-1] < min30_data['EMA26'][-1]) and  # 30分钟EMA13 < EMA26
            (min30_data['slowk'][-1] > 80)                           # 30分钟K值 > 80
        )

        if condition1_1 or condition1_2:
            long_signal = True
        if condition2_1 or condition2_2:
            short_signal = True

        # 执行交易
        portfolio = get_portfolio(symbol, 0)
        if long_signal:
            #buy_open(symbol, "market", volume=100)  # 做多
            subject = f"{symbol} 做多信号通知"
            body = f"品种: {symbol}\n" \
                    f"检测到做多信号,时间:{index}\n" \
                    f"日线EMA13: {daily_data.loc[index, 'EMA13']}, 日线EMA26: {daily_data.loc[index, 'EMA26']}\n" \
                    f"30分钟K值: {min30_data.loc[index, 'slowk']}, 30分钟D值: {min30_data.loc[index, 'slowd']}"
            send_email(subject, body)
        elif short_signal:
            #if portfolio.buy_quantity > 0:
                #sell_close(symbol, "market", volume=portfolio.buy_quantity)  # 平多
            # sell_open(symbol, "market", volume=100)  # 做空
            subject = f"{symbol} 做空信号通知"
            body = f"品种: {symbol}\n" \
                    f"检测到做空信号,时间:{index}\n" \
                    f"日线EMA13: {daily_data.loc[index, 'EMA13']}, 日线EMA26: {daily_data.loc[index, 'EMA26']}\n" \
                    f"30分钟K值: {min30_data.loc[index, 'slowk']}, 30分钟D值: {min30_data.loc[index, 'slowd']}"
            send_email(subject, body)

# after_trading函数会在每天交易结束后被调用,当天只会被调用一次
def after_trading(context):
    pass

回复

使用道具 举报

37

主题

9824

帖子

5万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
wenarm
发表于 2025-2-21 08:58 | 显示全部楼层
1.
163邮箱的465端口支持的ssl协议,代码要改成
    try:
        # 创建邮件对象
        msg = MIMEText(body, 'plain', 'utf-8')
        msg['From'] = Header(SENDER_EMAIL)
        msg['To'] = Header(RECEIVER_EMAIL)
        msg['Subject'] = Header(subject, 'utf-8')


        # 使用SSL连接到SMTP服务器并发送邮件
        with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
            server.login(SENDER_EMAIL, SENDER_PASSWORD)
            server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, msg.as_string())
        print("邮件发送成功!")
    except Exception as e:
        print(f"邮件发送失败: {e}")

2.
下面这句话不对,这种行为的定义不会获取到对应合约的品种代码。你要么直接通过设置监控这种品种的具体合约,要么直接修改代码。
context.target_symbols = ['RB', 'I', 'SC']  # 关注的期货品种(螺纹钢、铁矿石、原油)

代码修改示例如下:
context.target_symbols = ['RB00', 'I00', 'SC00']  # 关注的期货品种(螺纹钢、铁矿石、原油)
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

1

主题

4

帖子

4

积分

Rank: 1

等级: 新手上路

注册:
2023-10-10
曾用名:
 楼主| 发表于 2025-2-23 17:52 | 显示全部楼层
收到,感谢,我下周试试
回复

使用道具 举报

1

主题

4

帖子

4

积分

Rank: 1

等级: 新手上路

注册:
2023-10-10
曾用名:
 楼主| 发表于 2025-2-25 22:32 | 显示全部楼层
import pandas as pd
import talib as ta
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import numpy as np

# 邮件配置
SMTP_SERVER = 'smtp.163.com'  # SMTP服务器地址
SMTP_PORT = 465                   # SMTP服务器端口
SENDER_EMAIL = 'ly8040661@163.com'  # 发件人邮箱
SENDER_PASSWORD = 'FXMAXTHKWDHETGOR'        # 发件人邮箱密码
RECEIVER_EMAIL = '188381294@qq.com'  # 收件人邮箱

# 关注的期货品种
#TARGET_SYMBOLS = ['RB00', 'I', 'SC']  # 例如:螺纹钢(RB)、铁矿石(I)、原油(SC)



def send_email(subject, body):
    """
    发送邮件
    :param subject: 邮件主题
    :param body: 邮件内容
    """
    try:
        # 创建邮件对象
        msg = MIMEText(body, 'plain', 'utf-8')
        msg['From'] = Header(SENDER_EMAIL)
        msg['To'] = Header(RECEIVER_EMAIL)
        msg['Subject'] = Header(subject, 'utf-8')

        # 连接SMTP服务器并发送邮件
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            #server.starttls()  # 启用TLS加密
            server.login(SENDER_EMAIL, SENDER_PASSWORD)
            server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, msg.as_string())
        print("邮件发送成功!")
    except Exception as e:
        print(f"邮件发送失败: {e}")
        
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
    # 在context中设置一些参数
    context.s1 = context.run_info.base_book_id  # 交易品种
    context.target_symbols = [
    'AG04',
    'AL04',
    'BUY04',
    'RB05',
    'RU05',
    'SP05',
    'C05',
    'JD05',
    'M05',
    'P05',
    'PG04',
    'V05',
    'Y05',
    'FG05',
    'MA05',
    'SA05',
    'SRY05',
    'TA05',
    'OI05',
    'PF04',
    'CF05',
    'L05',
    'JM05',
    'I05',
    'FB05',
    'AL04',]  # 关注的期货品种(螺纹钢、铁矿石、原油)
   
    # EMA周期
    context.ema_short_period = 13
    context.ema_long_period = 26
   
    # KD指标参数
    context.kd_fastk_period = 14
    context.kd_slowk_period = 3
    context.kd_slowd_period = 3

# before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次
def before_trading(context):
    pass

# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context):
    # 开始编写你的主要的算法逻辑
    for symbol in context.target_symbols:
        # 获取历史数据
        daily_data = history_bars(symbol, context.ema_long_period + 1, '1d', ['close', 'high', 'low'], True)
        min30_data = history_bars(symbol, context.ema_long_period + 1, '30m', ['close', 'high', 'low'], True)
        daily_df = pd.DataFrame(daily_data)
        min30_df = pd.DataFrame(min30_data)
        # if len(daily_data) < context.ema_long_period + 1 or len(min30_data) < context.ema_long_period + 1:
            # continue  # 数据不足,跳过
        
        # 计算EMA和KD指标
        daily_df['EMA13'] = ta.EMA(np.array(daily_data['close']), timeperiod=context.ema_short_period)
        daily_df['EMA26'] = ta.EMA(np.array(daily_data['close']), timeperiod=context.ema_long_period)
        daily_df['EMA26_slope'] = daily_data['EMA26'].diff()
        
        min30_df['EMA13'] = ta.EMA(min30_data['close'], timeperiod=context.ema_short_period)
        min30_df['EMA26'] = ta.EMA(min30_data['close'], timeperiod=context.ema_long_period)
        min30_df['slowk'], min30_data['slowd'] = ta.STOCH(
            min30_df['high'], min30_data['low'], min30_data['close'],
            fastk_period=context.kd_fastk_period,
            slowk_period=context.kd_slowk_period,
            slowd_period=context.kd_slowd_period
        )
        
        # 生成信号
        long_signal = False
        short_signal = False
        
        # 1.1 基于KD上穿的做多信号
        # condition1_1 = (
        #      (daily_data['EMA13'][-1] > daily_data['EMA26'][-1]) and  # 日线EMA13 > EMA26
        #      (daily_data['EMA26_slope'][-1] > 0) and                  # 日线EMA26斜率 > 0
        #      (min30_data['EMA13'][-1] > min30_data['EMA26'][-1]) and  # 30分钟EMA13 > EMA26
        #      (min30_data['slowk'][-2] < min30_data['slowd'][-2]) and  # 30分钟KD上穿
        #      (min30_data['slowk'][-1] > min30_data['slowd'][-1])
        #  )
        
        condition1_1 = (
        (daily_df['EMA13'].iloc[-1] > daily_df['EMA26'].iloc[-1]) and
        (daily_df['EMA26_slope'].iloc[-1] > 0) and
        (min30_df['EMA13'].iloc[-1] > min30_df['EMA26'].iloc[-1]) and
        (min30_df['slowk'].iloc[-2] < min30_df['slowd'].iloc[-2]) and
        (min30_df['slowk'].iloc[-1] > min30_df['slowd'].iloc[-1])
        )
        
        # 1.2 基于KD超卖的做多信号
        # condition1_2 = (
        #     (daily_data['EMA13'][-1] > daily_data['EMA26'][-1]) and  # 日线EMA13 > EMA26
        #      (daily_data['EMA26_slope'][-1] > 0) and                  # 日线EMA26斜率 > 0
        #     (min30_data['EMA13'][-1] > min30_data['EMA26'][-1]) and  # 30分钟EMA13 > EMA26
        #      (min30_data['slowk'][-1] < 20)                           # 30分钟K值 < 20
        #  )
        
        condition1_2 = (
        (daily_df['EMA13'].iloc[-1] > daily_df['EMA26'].iloc[-1]) and
        (daily_df['EMA26_slope'].iloc[-1] > 0) and
        (min30_df['EMA13'].iloc[-1] > min30_df['EMA26'].iloc[-1]) and           
        (min30_df['slowk'].iloc[-1]<20)
        )
        
        # 2.1 基于KD下穿的做空信号
        #  condition2_1 = (
        #      (daily_data['EMA13'][-1] < daily_data['EMA26'][-1]) and  # 日线EMA13 < EMA26
        #      (daily_data['EMA26_slope'][-1] < 0) and                  # 日线EMA26斜率 < 0
        #      (min30_data['EMA13'][-1] < min30_data['EMA26'][-1]) and  # 30分钟EMA13 < EMA26
        #       (min30_data['slowk'][-2] > min30_data['slowd'][-2]) and  # 30分钟KD下穿
        #       (min30_data['slowk'][-1] < min30_data['slowd'][-1])
        #  )
        
        condition2_1 = (
        (daily_df['EMA13'].iloc[-1] < daily_df['EMA26'].iloc[-1]) and
        (daily_df['EMA26_slope'].iloc[-1] < 0) and
        (min30_df['EMA13'].iloc[-1] < min30_df['EMA26'].iloc[-1]) and
        (min30_df['slowk'].iloc[-2] > min30_df['slowd'].iloc[-2]) and
        (min30_df['slowk'].iloc[-1] > min30_df['slowd'].iloc[-1])
        )
        
        # 2.2 基于KD超买的做空信号
        # condition2_2 = (
        #     (daily_data['EMA13'][-1] < daily_data['EMA26'][-1]) and  # 日线EMA13 < EMA26
        #     (daily_data['EMA26_slope'][-1] < 0) and                  # 日线EMA26斜率 < 0
        #      (min30_data['EMA13'][-1] < min30_data['EMA26'][-1]) and  # 30分钟EMA13 < EMA26
        #      (min30_data['slowk'][-1] > 80)                           # 30分钟K值 > 80
        #  )
        
        condition2_2 = (
        (daily_df['EMA13'].iloc[-1] < daily_df['EMA26'].iloc[-1]) and
        (daily_df['EMA26_slope'].iloc[-1] < 0) and
        (min30_df['EMA13'].iloc[-1] < min30_df['EMA26'].iloc[-1]) and           
        (min30_df['slowk'].iloc[-1]>80)
        )
        
        if condition1_1 or condition1_2:
            long_signal = True
        if condition2_1 or condition2_2:
            short_signal = True
        
        # 执行交易
        portfolio = get_portfolio(symbol, 0)
        if long_signal:
            #buy_open(symbol, "market", volume=100)  # 做多
            subject = f"{symbol} 做多信号通知"
            body = f"品种: {symbol}\n" \
                    f"检测到做多信号,时间:{index}\n" \
                    f"日线EMA13: {daily_data.loc[index, 'EMA13']}, 日线EMA26: {daily_data.loc[index, 'EMA26']}\n" \
                    f"30分钟K值: {min30_data.loc[index, 'slowk']}, 30分钟D值: {min30_data.loc[index, 'slowd']}"
            send_email(subject, body)
        elif short_signal:
            #if portfolio.buy_quantity > 0:
                #sell_close(symbol, "market", volume=portfolio.buy_quantity)  # 平多
            # sell_open(symbol, "market", volume=100)  # 做空
            subject = f"{symbol} 做空信号通知"
            body = f"品种: {symbol}\n" \
                    f"检测到做空信号,时间:{index}\n" \
                    f"日线EMA13: {daily_data.loc[index, 'EMA13']}, 日线EMA26: {daily_data.loc[index, 'EMA26']}\n" \
                    f"30分钟K值: {min30_data.loc[index, 'slowk']}, 30分钟D值: {min30_data.loc[index, 'slowd']}"
            send_email(subject, body)

# after_trading函数会在每天交易结束后被调用,当天只会被调用一次
def after_trading(context):
    pass

代码修改成这样以后,报下面这个错,请帮忙看下,另外请教一下金字塔里面如何进行debug,谢谢!

执行Python脚本时遇到错误。
策略: <MyStrategy>
运行: <策略MyStrategy>
类型: IndexError
   行: 100
描述: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices


执行Python脚本时遇到错误。
策略: <MyStrategy>
运行: <策略MyStrategy>
类型: IndexError
   行: 100
描述: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
回复

使用道具 举报

20

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-2-26 09:16 | 显示全部楼层
“only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices”
这说明你在用一个错误的方式 进行索引取值。

daily_data['close']  你直接对一个numpy数组这样取值 肯定不行的.
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

1

主题

1026

帖子

1036

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
发表于 2025-2-26 11:33 来自手机 | 显示全部楼层
要学会用print函数做调试这个技巧的
回复

使用道具 举报

1

主题

4

帖子

4

积分

Rank: 1

等级: 新手上路

注册:
2023-10-10
曾用名:
 楼主| 发表于 2025-3-17 09:55 | 显示全部楼层
那么应该如何取值呢
回复

使用道具 举报

20

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-3-17 09:56 | 显示全部楼层
建议你看下numpy的官方文档。

如何对numpy数组取值,文档有范例的。
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2025-4-18 14:47 , Processed in 0.157874 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表