3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 估波曲线 (Coppock Curve) 的长线交易策略实现。
估波曲线(Coppock Curve)是一种主要用于识别股票市场长期底部动量指标。它的计算逻辑如下:
交易信号:
本策略以 沪深300 ETF (510300.XSHG) 为标的,每月第一个交易日运行一次,捕捉长期趋势。
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
def initialize(context):
"""
初始化函数
"""
# 设定标的:这里使用沪深300ETF作为长线投资标的
g.security = '510300.XSHG'
# 设定基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设定ETF交易手续费(模拟真实ETF费率)
set_order_cost(OrderCost(close_tax=0, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='fund')
# 设定按月运行:每月第一个交易日开盘运行
run_monthly(trade_logic, 1, time='open')
def calculate_wma(series, weights):
"""
计算加权移动平均 (WMA)
"""
if len(series) != len(weights):
return None
return np.average(series, weights=weights)
def get_coppock_curve(security, context):
"""
计算估波曲线指标
"""
# 获取过去 30 个月的收盘价数据 (14个月ROC + 10个月WMA + 缓冲)
# unit='1M' 获取的是过去每个月的月线数据
h = attribute_history(security, 30, '1M', ['close'], df=True)
if len(h) < 25:
return None, None
close = h['close']
# 1. 计算 14个月 和 11个月 的 ROC (Rate of Change)
# pct_change(N) 计算的是 (现价 - N天前价格) / N天前价格 * 100
roc_14 = close.pct_change(14) * 100
roc_11 = close.pct_change(11) * 100
# 2. 将两个 ROC 相加
roc_sum = roc_14 + roc_11
# 去除前面的 NaN 值
roc_sum = roc_sum.dropna()
# 3. 计算 10 个月的 WMA (加权移动平均)
# 权重为 1, 2, 3, ..., 10 (越近的数据权重越大)
weights = np.arange(1, 11)
if len(roc_sum) < 11:
return None, None
# 计算当前的 Coppock 值 (使用最近10个数据)
current_series = roc_sum.iloc[-10:]
coppock_curr = calculate_wma(current_series, weights)
# 计算上个月的 Coppock 值 (使用倒数第11到倒数第2个数据)
prev_series = roc_sum.iloc[-11:-1]
coppock_prev = calculate_wma(prev_series, weights)
return coppock_curr, coppock_prev
def trade_logic(context):
"""
交易逻辑函数
"""
security = g.security
# 获取当前和上期的估波值
cc_curr, cc_prev = get_coppock_curve(security, context)
if cc_curr is None or cc_prev is None:
log.info("数据不足,跳过计算")
return
# 记录指标值以便在回测图中查看
record(Coppock=cc_curr)
# 获取当前持仓
position = context.portfolio.positions[security].total_amount
cash = context.portfolio.available_cash
# --- 交易信号判断 ---
# 信号1:买入
# 逻辑:曲线拐头向上 (当前值 > 上期值) 且 上期值 < 0 (经典用法是在零轴下方金叉,也可去掉 <0 限制做趋势跟随)
# 这里采用经典用法:底部反转
if cc_curr > cc_prev and cc_prev < 0:
if position == 0:
log.info("估波曲线底部拐头向上 (Curr: %.2f, Prev: %.2f),全仓买入" % (cc_curr, cc_prev))
order_value(security, cash)
# 信号2:卖出
# 逻辑:曲线拐头向下 (当前值 < 上期值)
elif cc_curr < cc_prev:
if position > 0:
log.info("估波曲线拐头向下 (Curr: %.2f, Prev: %.2f),清仓卖出" % (cc_curr, cc_prev))
order_target(security, 0)
数据频率 (1M):
attribute_history(security, 30, '1M', ...) 获取过去30个月的收盘价。run_monthly 确保策略只在每月的第一个交易日运行,避免日内波动干扰。WMA (加权移动平均) 实现:
calculate_wma 函数,利用 numpy.average 配合 weights 参数(权重序列为 1 到 10)来实现线性加权。买卖逻辑:
cc_curr > cc_prev and cc_prev < 0。这表示曲线在负值区域(通常意味着市场处于低估或熊市底部)开始向上转折。这是 Coppock Curve 最核心的用法。cc_curr < cc_prev。当动量减弱,曲线开始掉头向下时离场。标的选择:
510300.XSHG (沪深300 ETF)。估波曲线最适合用于大盘指数或宽基 ETF,用于判断宏观市场的牛熊转换,而不适合波动剧烈的小盘股。Q: 为什么买入条件要加上 cc_prev < 0?
A: 估波曲线的设计初衷是寻找熊市底部。在零轴下方的拐头通常代表市场极度悲观后的复苏。如果在零轴上方拐头向上,可能只是上涨中继,虽然也可以买入,但风险收益比通常不如底部反转高。
Q: 这个策略的缺点是什么?
A: 这是一个极其滞后的指标。因为它使用了14个月和11个月的ROC,再加上10个月的平滑,它对市场反应很慢。它能让你吃到牛市中间最肥美的一段,但绝对买不到最低点,也卖不到最高点。在震荡市中可能会失效。
Q: 可以应用在个股上吗?
A: 可以,但建议选择大盘蓝筹股。对于妖股或小盘股,由于波动率过大,ROC指标会产生剧烈抖动,导致WMA平滑后依然产生虚假信号。