版本 v1.0
交易逻辑在HFTrade模块中实现: 1.在初始化函数中,设置需要处理的合约,并初始化分钟以及30分钟大周期K线序号,最后设置 30分钟大周期K线的最短移动平均周期数,这里默认值为26; 2.在K线处理函数中,通过合并30个分钟K线的信息,得到一个30分钟K线信息,合并原理为:取30个分钟K线的最高价和最低价为该30分钟K线的最高价与最低价,取第一根分钟K线的开盘价与最后一根K线的收盘价为该30分钟K线的对应价; 3.求30分钟大周期K线的默认周期(此处默认周期为26)移动平均的均值; 4.最后,通过传统的金叉死叉原则确定买卖出逻辑,具体为:在无持仓的时候,如果最后一根大周期K线收盘价大于大周期K线的平均收盘价(金叉),则下单买入; 在有持仓,且最后一根分钟K线收盘价小于大周期K线的平均收盘价(死叉),则下单卖出。
通过证券代码列表输入要回测的股票,这里以贵州茅台(600519.SHA)为例,以及回测的起止日期。
通过传统的金叉死叉原则确定买卖逻辑,具体为:在无持仓的时候,如果最后一根大周期K线收盘价大于大周期K线的平均收盘价(金叉),则下单买入; 在有持仓,且最后一根分钟K线收盘价小于大周期K线的平均收盘价(死叉),则下单卖出。
HFTrade模块中的初始化函数已经设置了默认的交易手续费和滑点,要修改手续费可在初始化函数内修改;
通过HFTrade模块中K线处理函数实现交易规则,并打印交易日志。
# 本代码由可视化策略环境自动生成 2022年3月15日 15:08
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m3_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.subscribe(context.instruments[0])
context.set_universe(context.instruments[0]) # 设置需要处理的合约
context.bar_series = NumPyDeque(200, dtype='object') # 20个分钟 K线 (包括OHLC)
context.bar_index = 0 # 分钟K线序号
context.big_cycle_bar_index = 0 #30分钟大周期K线序号
context.ma_periods = 26
# 交易引擎:每个单位时间开盘前调用一次。
def m3_before_trading_start_bigquant_run(context, data):
pass
# 交易引擎:tick数据处理函数,每个tick执行一次
def m3_handle_tick_bigquant_run(context, tick):
pass
# 回测引擎:每日数据处理函数,每天执行一次
def m3_handle_data_bigquant_run(context, data):
import talib as ta
context.bar_index += 1
cur_date = data.current_dt
cur_hm = cur_date.strftime('%H:%M')
if context.bar_index % 30 == 0: # 30m k线
context.big_cycle_bar_index += 1
sid = context.symbol(context.instruments[0])# 标的为字符串格式
hist = data.history(sid, ["open","high","low","close"], 30, "1m")
big_cycle_bar_data = {'datetime':hist.index[-1],'high':hist.high.max(),'open':hist.open.values[0],'low':hist.low.min(),'close':hist.close.values[-1]}
context.bar_series.append(big_cycle_bar_data)
if context.big_cycle_bar_index > context.ma_periods : # 30分钟大周期K线的移动平均26个周期的均值
price_data = pd.DataFrame(list(context.bar_series))
sma = talib.SMA(price_data['close'], timeperiod=context.ma_periods ).values[-1]
cur_price = price_data['close'].values[-1]
cur_position = context.portfolio.positions[sid].amount # 持仓
if cur_position==0 and cur_price>sma:
context.order(sid, 100)
print('buy'*5, cur_date)
elif cur_position>0 and cur_price<sma:
context.order_target_percent(sid, 0)
print('sell'*5, cur_date)
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m3_handle_trade_bigquant_run(context, trade):
pass
# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m3_handle_order_bigquant_run(context, order):
pass
# 交易引擎:盘后处理函数,每日盘后执行一次
def m3_after_trading_bigquant_run(context, data):
pass
m1 = M.instruments.v2(
start_date='2022-01-01',
end_date=T.live_run_param('trading_date', '2022-03-11'),
market='CN_STOCK_A',
instrument_list='600519.SHA',
max_count=0,
m_cached=False
)
m3 = M.hftrade.v2(
instruments=m1.data,
start_date='',
end_date='',
initialize=m3_initialize_bigquant_run,
before_trading_start=m3_before_trading_start_bigquant_run,
handle_tick=m3_handle_tick_bigquant_run,
handle_data=m3_handle_data_bigquant_run,
handle_trade=m3_handle_trade_bigquant_run,
handle_order=m3_handle_order_bigquant_run,
after_trading=m3_after_trading_bigquant_run,
capital_base=500000,
frequency='minute',
price_type='真实价格',
product_type='股票',
before_start_days='0',
order_price_field_buy='open',
order_price_field_sell='open',
benchmark='000300.HIX',
plot_charts=True,
disable_cache=False,
replay_bdb=True,
show_debug_info=False,
backtest_only=False
)
[2022-03-15 15:07:58.392677] INFO: moduleinvoker: instruments.v2 开始运行..
[2022-03-15 15:07:58.418844] INFO: moduleinvoker: instruments.v2 运行完成[0.026166s].
[2022-03-15 15:07:58.446917] INFO: moduleinvoker: hfbacktest.v1 开始运行..
[2022-03-15 15:07:58.463195] INFO: moduleinvoker: 命中缓存
[2022-03-15 15:07:59.270816] INFO: moduleinvoker: hfbacktest.v1 运行完成[0.823895s].
[2022-03-15 15:07:59.272817] INFO: moduleinvoker: hftrade.v2 运行完成[0.845747s].