3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 Heikin-Ashi (平均K线) 的交易策略。
Heikin-Ashi(平均K线)是一种对标准K线(OHLC)进行平滑处理的技术,旨在过滤市场噪音,更清晰地展示趋势。
计算公式:
交易逻辑:
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
策略初始化函数
"""
# 设置资金账号 (请替换为您自己的资金账号)
ContextInfo.account_id = '6000000000'
ContextInfo.account_type = 'STOCK'
ContextInfo.set_account(ContextInfo.account_id)
# 设置股票池 (示例:平安银行)
ContextInfo.stock_code = '000001.SZ'
ContextInfo.set_universe([ContextInfo.stock_code])
# 策略参数
ContextInfo.period = '1d' # 周期:日线
ContextInfo.lookback = 100 # 回溯K线数量,用于计算HA值的稳定性
def calculate_heikin_ashi(df):
"""
计算 Heikin-Ashi 数据
"""
ha_df = df.copy()
# 1. 计算 HA_Close
ha_df['HA_Close'] = (df['open'] + df['high'] + df['low'] + df['close']) / 4
# 2. 计算 HA_Open
# HA_Open 依赖于前一根 K 线的 HA 数据,需要迭代计算
# 初始化列表,第一根 K 线的 HA_Open 设为普通 Open
ha_open_list = [df['open'].iloc[0]]
# 获取原始 Open 和 High, Low 数据用于后续计算(虽然 HA_Open 只依赖前值)
# 注意:这里为了效率使用循环,对于极长序列可能需要优化,但对于 lookback=100 很快
ha_close_values = ha_df['HA_Close'].values
for i in range(1, len(df)):
# HA_Open = (Prev_HA_Open + Prev_HA_Close) / 2
prev_ha_open = ha_open_list[-1]
prev_ha_close = ha_close_values[i-1]
current_ha_open = (prev_ha_open + prev_ha_close) / 2
ha_open_list.append(current_ha_open)
ha_df['HA_Open'] = ha_open_list
# 3. 计算 HA_High 和 HA_Low (本策略逻辑主要依赖 Open 和 Close,High/Low 可选)
ha_df['HA_High'] = ha_df[['high', 'HA_Open', 'HA_Close']].max(axis=1)
ha_df['HA_Low'] = ha_df[['low', 'HA_Open', 'HA_Close']].min(axis=1)
return ha_df
def handlebar(ContextInfo):
"""
K线运行函数
"""
# 获取当前 bar 的索引
index = ContextInfo.barpos
# 获取当前时间
realtime = ContextInfo.get_bar_timetag(index)
# 获取股票代码
stock = ContextInfo.stock_code
# 获取历史行情数据 (多取一些数据以确保 HA 计算收敛)
# 注意:get_market_data_ex 返回的是 {code: dataframe}
data_map = ContextInfo.get_market_data_ex(
['open', 'high', 'low', 'close'],
[stock],
period=ContextInfo.period,
count=ContextInfo.lookback,
dividend_type='front' # 前复权
)
if stock not in data_map:
return
df = data_map[stock]
if len(df) < 2:
return
# 计算 Heikin-Ashi
ha_df = calculate_heikin_ashi(df)
# 获取当前 K 线的 HA 数据 (Series对象)
current_bar = ha_df.iloc[-1]
# 获取上一根 K 线的 HA 数据 (用于判断反转)
prev_bar = ha_df.iloc[-2]
# 定义颜色:True 为阳线(绿/涨),False 为阴线(红/跌)
# 注意:国内习惯 红涨绿跌,但 HA 逻辑通常指 Close > Open 为强势
is_bullish = current_bar['HA_Close'] > current_bar['HA_Open']
is_bearish = current_bar['HA_Close'] < current_bar['HA_Open']
# 获取当前持仓
positions = ContextInfo.get_trade_detail_data(ContextInfo.account_id, ContextInfo.account_type, 'POSITION')
current_holding = 0
for pos in positions:
if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock:
current_holding = pos.m_nVolume
break
# --- 交易逻辑 ---
# 信号:HA 阳线 (看涨)
if is_bullish:
# 如果当前空仓或持仓不足,则买入
# 这里简单演示全仓买入,实际需计算资金
if current_holding == 0:
# 获取账户可用资金
account_info = ContextInfo.get_trade_detail_data(ContextInfo.account_id, ContextInfo.account_type, 'ACCOUNT')
if account_info:
available_cash = account_info[0].m_dAvailable
# 预留一点资金防止手续费不足,取 95%
target_value = available_cash * 0.95
print(f"[{stock}] HA转强 (Close: {current_bar['HA_Close']:.2f} > Open: {current_bar['HA_Open']:.2f}) -> 买入")
# 使用 order_target_value 调整持仓市值
order_target_value(stock, target_value, ContextInfo, ContextInfo.account_id)
# 信号:HA 阴线 (看跌)
elif is_bearish:
# 如果有持仓,则清仓
if current_holding > 0:
print(f"[{stock}] HA转弱 (Close: {current_bar['HA_Close']:.2f} < Open: {current_bar['HA_Open']:.2f}) -> 卖出")
order_target_value(stock, 0, ContextInfo, ContextInfo.account_id)
# 绘图 (可选,用于回测界面观察)
# 绘制 HA 的收盘价趋势
ContextInfo.paint('HA_Close', current_bar['HA_Close'], -1, 0)
数据获取 (get_market_data_ex):
get_market_data_ex 获取历史数据。count=100:Heikin-Ashi 的 HA_Open 依赖于前一根 K 线的值。为了让计算结果准确(收敛),我们需要获取一定长度的历史数据进行迭代计算,而不是仅获取当前一根 K 线。HA 计算逻辑 (calculate_heikin_ashi):
HA_Close 可以直接向量化计算。HA_Open 必须通过循环计算,因为 t 时刻的值依赖于 t-1 时刻的值。交易信号:
HA_Close > HA_Open。这表示平均价格在上升,动能向上。HA_Close < HA_Open。这表示平均价格在下降。下单函数 (order_target_value):
order_target_value 是最方便的仓位管理方式。ContextInfo.account_id 替换为真实账号)。HA_Open 被强制设为普通 Open,这会导致前几根 K 线的 HA 值不完全准确。这就是为什么我们在 get_market_data_ex 中读取 100 根 K 线的原因——经过几十根 K 线的迭代,数值会趋于精确。Q: 为什么不直接用 QMT 自带的指标计算?
A: QMT 的 Python API 主要提供原始行情数据。虽然部分技术指标库(如 TA-Lib)可以集成,但 Heikin-Ashi 这种特殊的 K 线形态构造通常需要手动计算,这样可以更灵活地控制逻辑(例如添加 HA_High/HA_Low 的过滤条件)。
Q: 如何增加过滤条件,例如只有“无下影线的阳线”才买入?
A: 您可以在 handlebar 函数的 is_bullish 判断中增加条件:
# 无下影线意味着 HA_Low 等于 HA_Open
is_strong_bullish = (current_bar['HA_Close'] > current_bar['HA_Open']) and \
(abs(current_bar['HA_Low'] - current_bar['HA_Open']) < 0.01)
Q: 这个策略适合什么周期?
A: Heikin-Ashi 在趋势明显的周期表现更好,通常建议用于 日线 或 小时线。在分钟级震荡市中可能会产生较多磨损。