ATR是Average True Range平均真实范围的简称,利用这个指标,可以构建一个基于价格波动的通道。
当价格往上突破通道上轨时,买入股票
当价格往下突破通道下轨时,卖出股票
# 1. 策略基本参数
def prepare(context):
# 策略比较参考标准,以沪深300为例
benchmark = '000300.INDX'
# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
# 设置是否是结算模式
context.set_need_settle(False)
# 设置手续费,PerContract 说明是每手手续费多少,分别是开仓、平昨、平今
context.set_commission(equities_commission=None, futures_commission=None) # 手续费按系统默认手续费设置
# 设置最大杠杆
context.set_max_leverage(0.6, 'fill_amap') # 这里能够设置最大杠杆
context.observation = 30
context.width = 2
context.ma_length = 25
def handle_data(context, data):
if context.trading_day_index < context.observation: # 在30个交易日以后才开始真正运行
return
today = data.current_dt.strftime('%Y-%m-%d') # 当前交易日期
instrument = context.future_symbol(context.instruments[0]) # 交易标的
curr_po=context.portfolio.positions[instrument] # 持仓
curr_position = curr_po.amount # 持仓数量
price = data.current(instrument, 'price') # 当前价格
high_price= np.array(data.history(instrument, 'high', context.observation, '1d')) # high
low_price= np.array(data.history(instrument, 'low', context.observation, '1d')) # low
close_price= np.array(data.history(instrument, 'close', context.observation, '1d')) # close_price
# 判断获取的数据中多少天是缺失数据,如果全是缺失数据,是不能计算ATR指标的
nan_num = [k for k in [np.isnan(i) for i in close_price] if k == True]
if len(nan_num) == context.observation:
return
# 创建ATR买卖信号,包括最高价,最低价,收盘价和参数timeperiod
# 注意:ATR函数使用的price必须是narray
import talib
atr = talib.ATR(high_price,low_price,close_price, timeperiod=context.ma_length)[-1]
ma = data.history(instrument, 'high', context.ma_length, '1d').mean()
high_line = ma + context.width * atr # 上轨
low_line = ma - context.width * atr # 下轨
# 交易逻辑
if price >= high_line and curr_position <=0 and data.can_trade(instrument): # 开多
order_target(instrument, 5) # order_target的含义是本次下单使得最终的仓位为目标仓位,如果是正数,那么就是多头仓位
print(today, '买入开仓')
elif price <= low_line and curr_position >= 0 and data.can_trade(instrument): # 开空
order_target(instrument, -5) # 下单后使得仓位为5手空单
print(today, '卖出开仓')
# 3. 启动回测
# 策略回测接口: https://v2.bigquant.com/docs/module_trade.html
m = M.trade.v4(
instruments= ['RU1809.SHF'],
start_date='2017-11-03',
end_date='2018-07-01',
prepare=prepare,
initialize=initialize,
handle_data=handle_data,
# 买入订单以开盘价成交
order_price_field_buy='open',
# 卖出订单以开盘价成交
order_price_field_sell='open',
capital_base=1000000,
benchmark='000300.SHA',
product_type = 'future',
m_deps=np.random.rand()
)