3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
基于线性回归斜率的趋势策略是一种经典的动量策略。其核心逻辑是利用统计学中的线性回归方法,计算过去一段时间内价格走势的斜率(Slope)。
以下是完整的 Python 策略代码。该代码使用了 numpy 库来进行线性拟合计算,并使用 get_market_data_ex 获取历史数据。
# -*- coding: gbk -*-
import numpy as np
import pandas as pd
def init(ContextInfo):
"""
策略初始化函数
"""
# 1. 设置策略参数
ContextInfo.N = 20 # 线性回归计算周期(如过去20天)
ContextInfo.slope_threshold = 0.1 # 斜率阈值,用于过滤震荡噪音
ContextInfo.stock_list = ['600000.SH', '000001.SZ'] # 股票池示例
# 2. 设置股票池
ContextInfo.set_universe(ContextInfo.stock_list)
# 3. 设置资金账号 (请替换为您的真实资金账号)
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.set_account(ContextInfo.account_id)
# 4. 设置回测参数 (仅回测有效)
ContextInfo.set_commission(0, [0.0001, 0.0001, 0.0003, 0.0003, 0, 5]) # 设置费率
ContextInfo.capital = 1000000 # 初始资金
def handlebar(ContextInfo):
"""
K线逐根运行函数
"""
# 获取当前设置的股票池
stock_list = ContextInfo.get_universe()
# 获取当前周期 (例如 '1d')
period = ContextInfo.period
# 批量获取历史行情数据
# 我们需要 N 个数据点来进行回归计算
# count = ContextInfo.N 表示获取过去 N 根K线
market_data = ContextInfo.get_market_data_ex(
fields=['close'],
stock_code=stock_list,
period=period,
count=ContextInfo.N,
dividend_type='front' # 前复权
)
# 遍历每一只股票进行计算
for stock in stock_list:
# 获取该股票的 DataFrame 数据
if stock not in market_data:
continue
df = market_data[stock]
# 数据长度校验,如果数据不足 N 个,无法计算回归,跳过
if len(df) < ContextInfo.N:
continue
# 提取收盘价序列
close_prices = df['close'].values
# --- 核心逻辑:计算线性回归斜率 ---
# 创建 X 轴序列 [0, 1, 2, ..., N-1]
x = np.arange(len(close_prices))
# 创建 Y 轴序列 (收盘价)
y = close_prices
# 使用 numpy 的 polyfit 进行一次多项式拟合 (线性回归)
# deg=1 表示一次方程 y = kx + b
# 返回值 fit[0] 是斜率 k,fit[1] 是截距 b
try:
fit = np.polyfit(x, y, 1)
slope = fit[0]
except Exception as e:
print(f"计算斜率出错 {stock}: {e}")
continue
# --- 交易逻辑 ---
# 获取当前持仓信息
position = get_position(stock, ContextInfo)
# 1. 买入逻辑:斜率 > 阈值 且 当前无持仓
if slope > ContextInfo.slope_threshold and position == 0:
print(f"[{stock}] 触发买入信号,当前斜率: {slope:.4f} > 阈值: {ContextInfo.slope_threshold}")
# 目标市值买入,例如调整仓位到 20% (假设资金足够分散)
# 这里简单演示,全仓买入或固定比例买入
order_target_percent(stock, 0.2, ContextInfo, ContextInfo.account_id)
# 2. 卖出逻辑:斜率 < -阈值 (或跌破0) 且 当前有持仓
# 这里设置为斜率转负即卖出,或者小于负阈值卖出,取决于激进程度
elif slope < -ContextInfo.slope_threshold and position > 0:
print(f"[{stock}] 触发卖出信号,当前斜率: {slope:.4f} < 阈值: -{ContextInfo.slope_threshold}")
# 清仓
order_target_percent(stock, 0, ContextInfo, ContextInfo.account_id)
def get_position(stock_code, ContextInfo):
"""
辅助函数:获取某只股票的当前持仓数量
"""
# 获取持仓对象列表
positions = get_trade_detail_data(ContextInfo.account_id, 'stock', 'position')
for pos in positions:
if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock_code:
# 返回当前持仓量
return pos.m_nVolume
return 0
数据获取 (get_market_data_ex):
get_market_data_ex 是 QMT 推荐的方式,效率比旧接口高。count=ContextInfo.N 确保我们获取了足够的数据点来进行回归分析。dividend_type='front' 使用前复权数据,这对于计算历史趋势至关重要,避免因分红除权导致的价格跳空影响斜率计算。线性回归计算 (np.polyfit):
numpy.polyfit(x, y, 1)。其中 x 是时间序列(0 到 N-1),y 是价格序列。1 代表拟合一次函数(直线)。阈值设定 (ContextInfo.slope_threshold):
交易执行 (order_target_percent):
order_target_percent 可以方便地管理仓位。0.2 表示将该股票仓位调整至总资产的 20%。0 表示清仓。Q: 为什么我的策略在回测时没有交易?
A: 请检查以下几点:
ContextInfo.stock_list 是否包含了有效的股票代码。ContextInfo.slope_threshold 设置是否过大,导致很难触发信号。Q: 如何让策略对高价股和低价股一视同仁?
A: 修改计算逻辑,对价格进行归一化。将 y = close_prices 改为 y = close_prices / close_prices[0](以区间第一天价格为基准)。这样计算出的斜率代表的是相对于起始价格的增长率。
Q: 这个策略适合什么周期?
A: 线性回归策略通常在趋势明显的周期表现较好,如日线(1d)或 60分钟线(60m)。在震荡市或极短周期(如 1分钟)中可能会产生大量假信号。