问题描述
帮我写一个双均线交易策略,当短期均线上穿长期均线时买入,下穿时卖出。
解决方案
这是一个基于PTrade API实现的经典双均线(Dual Moving Average)交易策略。
策略逻辑
- 短期均线(Short MA):反应近期价格趋势(例如5日均线)。
- 长期均线(Long MA):反应长期价格趋势(例如10日均线)。
- 买入信号(金叉):当短期均线数值 大于 长期均线数值,且当前无持仓时,全仓买入。
- 卖出信号(死叉):当短期均线数值 小于 长期均线数值,且当前有持仓时,清仓卖出。
策略代码
def initialize(context):
"""
初始化函数,设置股票池和全局变量
"""
# 设定要交易的股票,这里以恒生电子(600570.SS)为例
g.security = '600570.SS'
# 设置股票池
set_universe(g.security)
# 设定均线周期
g.short_window = 5 # 短期均线周期
g.long_window = 10 # 长期均线周期
# 确保获取的历史数据长度足够计算长期均线
# 为了计算准确,多取几天数据作为缓冲
g.history_count = g.long_window + 2
def handle_data(context, data):
"""
盘中运行函数,每个单位时间(如每天)运行一次
"""
security = g.security
# 1. 过滤停牌股票,如果停牌则不进行操作
if data[security].is_open == 0:
return
# 2. 获取历史收盘价数据
# 获取过去 g.history_count 天的收盘价,不包含当前周期(避免未来函数,且通常均线计算基于昨日收盘)
# 注意:PTrade中get_history返回的是DataFrame,索引为时间
history = get_history(g.history_count, frequency='1d', field='close', security_list=security, include=False)
# 如果数据长度不足(例如刚上市的股票),则跳过
if len(history) < g.long_window:
log.info("历史数据不足,跳过计算")
return
# 提取收盘价序列
close_prices = history['close']
# 3. 计算均线值
# 计算短期均线(取最后 short_window 个数据求平均)
ma_short = close_prices[-g.short_window:].mean()
# 计算长期均线(取最后 long_window 个数据求平均)
ma_long = close_prices[-g.long_window:].mean()
# 获取当前持仓数量
current_position = context.portfolio.positions[security].amount
# 获取当前可用资金
available_cash = context.portfolio.cash
# 4. 交易逻辑判断
# 买入信号:短期均线 > 长期均线 (金叉状态) 且 当前空仓
if ma_short > ma_long and current_position == 0:
# 全仓买入
# order_value 按价值下单,传入当前所有可用资金
order_value(security, available_cash)
log.info("金叉出现 (MA%s=%.2f > MA%s=%.2f),买入 %s" % (g.short_window, ma_short, g.long_window, ma_long, security))
# 卖出信号:短期均线 < 长期均线 (死叉状态) 且 当前持有股票
elif ma_short < ma_long and current_position > 0:
# 清仓卖出
# order_target 将持仓调整为目标数量,0表示清仓
order_target(security, 0)
log.info("死叉出现 (MA%s=%.2f < MA%s=%.2f),卖出 %s" % (g.short_window, ma_short, g.long_window, ma_long, security))
代码关键点解析
-
initialize(context):- 使用
g.security定义全局变量存储股票代码。 - 使用
set_universe设置股票池,这是PTrade回测必须的步骤。 - 定义了
g.short_window和g.long_window,方便后续调整参数(如改为10日和20日均线)。
- 使用
-
get_history(...):count: 获取的数据长度。必须大于长期均线的周期,否则无法计算。frequency='1d': 获取日线数据。include=False: 重要。通常均线策略是基于昨天收盘后的均线形态来决定今天的操作。如果设为True,则包含了今天的实时价格,回测中可能会引入未来函数(除非你是做盘中实时分钟级策略)。
-
均线计算:
- 利用 Pandas 的切片功能
[-g.short_window:]获取最近N天的数据,然后调用.mean()计算平均值。
- 利用 Pandas 的切片功能
-
下单函数:
order_value(security, cash): 适合买入时使用,表示用多少钱买入,系统会自动计算股数(向下取整100股)。order_target(security, 0): 适合卖出时使用,表示将持仓调整为0,即清仓。
-
Python兼容性:
- 代码使用了
%s格式化字符串进行日志输出,完全兼容 Python 3.5 及以上版本(PTrade环境通常支持)。
- 代码使用了
如何使用
- 将上述代码复制到 PTrade 客户端的策略编辑区域。
- 在右侧设置回测参数(如资金、起止时间)。
- 点击“运行回测”即可看到策略表现。