from bigtrader.constant import Direction, OrderType
#给每个策略取一个名字
STRATEGY_NAME = "STRATEGY_1"
def initialize(context):
"""策略初始化函数,只触发一次。可以在该函数中初始化一些变量,如读取配置和全局使用数据"""
#输出关键日志
msg = "initialize:"
context.write_log(msg, stdout=1)
#从传入参数中获取需要字段
context.my_instrument = context.get_conf_param("instrument")
context.opentime_day = context.get_conf_param('opentime_day')
context.closetime_day = context.get_conf_param('closetime_day')
context.closetime_night = context.get_conf_param('closetime_night')
#设置需要处理的股票池或者合约集合
context.set_universe(context.my_instrument)
def before_trading(context, data):
"""盘前处理,策略盘前交易函数,每日盘前触发一次。可以在该函数中一些启动前的准备,如订阅行情等"""
# 输出关键日志
msg = "before_trading"
context.write_log(msg, stdout=1)
# 订阅要交易的合约的行情
context.subscribe(context.my_instrument)
# 如果需要处理tick数据,需要添加tick处理函数:handle_tick(context, tick):
def handle_data(context, data):
"""Bars行情通知函数,每个bar时间周期会触发,包括日线和分钟"""
print("handle_data:", data.current_dt)
# 分别获取多头持仓,和空头持仓,主要使用 current_qty 和 avail_qty 两个属性
position_long = context.get_position(context.my_instrument, Direction.LONG)
position_short = context.get_position(context.my_instrument, Direction.SHORT)
# 获取账户资金,主要使用 balance 和 available 两个属性
trading_account = context.get_trading_account()
# 获取当前k线最新收盘价格
price = data.current(context.my_instrument, "close")
#获取30根1m历史数据数据
hist = context.history_data(context.my_instrument, ["open","high","low","close"], 30, "1m")
#计算20均线
hist['ma'] = hist['close'].rolling(20).mean()
cur_hm = data.current_dt.strftime('%H:%M')
#价格向上穿越20均线
# if cur_hm <= context.closetime_day and cur_hm >= context.opentime_day:
if(hist.iloc[-2]['close']<hist.iloc[-2]['ma'] and price>=hist.iloc[-1]['ma']):
#有空单的先平掉
if (position_short.avail_qty != 0):
rv = context.buy_close(context.my_instrument, position_short.avail_qty, price, order_type=OrderType.MARKET)
if rv != 0:
context.write_log("buy_close error={}".format(context.get_error_msg(rv)), stdout=1)
msg = str(data.current_dt) + " 平空 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
context.write_log(msg, stdout=1)
#没有多单则开多1手
if (position_long.current_qty == 0):
rv = context.buy_open(context.my_instrument, 1, price, order_type=OrderType.MARKET)
msg = str(data.current_dt) + " 开多 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
context.write_log(msg, stdout=1)
#价格向下穿越20均线
if (hist.iloc[-2]['close']>hist.iloc[-2]['ma'] and price<hist.iloc[-1]['ma']):
#有多单的先平掉
if (position_long.avail_qty != 0):
rv = context.sell_close(context.my_instrument, position_long.avail_qty, price, order_type=OrderType.MARKET)
msg = str(data.current_dt) + " 平多 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
context.write_log(msg, stdout=1)
#没有空单则开空1手
if (position_short.current_qty == 0):
rv = context.sell_open(context.my_instrument, 1, price, order_type=OrderType.MARKET)
msg = str(data.current_dt) + " 开空 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
context.write_log(msg, stdout=1)
def handle_order(context, order):
"""委托回报通知函数,每个订单状态有变化时会触发"""
#输出关键日志
msg = "handle_order data:{}".format(order.log_str())
context.write_log(msg, stdout=1)
def handle_trade(context, trade):
"""成交回报通知函数,有成交时会触发"""
#输出关键日志
msg = "handle_trade data:{}".format(trade.log_str())
context.write_log(msg, stdout=1)