def long_close_signal(self, var, bar, boll): if var.direction == LONG: symbol_obj = self.context.symbol_infos[bar.symbol] if var.close_count >= 3: if self.pre_close(var, bar.symbol): log.info('%s 平多 *' % bar.symbol) msg.send('%s 平多 *' % bar.symbol) self.order(bar.symbol, LONG, CLOSE, var.open_vol, limit_price=bar.close - symbol_obj.tick_size) else: if bar.close < boll.mid and bar.close < bar.open and ( boll.top - boll.bot) / boll.mid > var.spread_thres: var.close_count += 1 log.info('%s 平多计数器+1 close_count %s' % (bar.symbol, var.close_count)) if var.close_count >= 3: if self.pre_close(var, bar.symbol): log.info('%s 平多' % bar.symbol) msg.send('%s 平多' % bar.symbol) self.order(bar.symbol, LONG, CLOSE, var.open_vol, limit_price=bar.close - var.slippage * symbol_obj.tick_size)
def stop_gain(self, var, tick): if var.direction != '': delta = var.open_price - tick.last_price if var.direction == LONG: delta = tick.last_price - var.open_price if var.gain_over_flag and delta / var.max_gain < var.stop_gain_thres: symbol_obj = self.context.symbol_infos[tick.symbol] if var.direction == LONG: msg.send('%s 多单止盈 max_gain %s gain_now %s' % (tick.symbol, var.max_gain, delta)) log.info('%s 多单止盈 max_gain %s gain_now %s' % (tick.symbol, var.max_gain, delta)) self.order(tick.symbol, LONG, CLOSE, var.open_vol, limit_price=tick.last_price - var.slippage * symbol_obj.tick_size) else: msg.send('%s 空单止盈 max_gain %s gain_now %s' % (tick.symbol, var.max_gain, delta)) log.info('%s 空单止盈 max_gain %s gain_now %s' % (tick.symbol, var.max_gain, delta)) self.order(tick.symbol, SHORT, CLOSE, var.open_vol, limit_price=tick.last_price + var.slippage * symbol_obj.tick_size)
def short_close_signal(self, var, bar, boll): if var.direction == SHORT: symbol_obj = self.context.symbol_infos[bar.symbol] if var.close_count >= 3: if self.pre_close(var, bar.symbol): log.info('%s 平空 *' % bar.symbol) msg.send('%s 平空 *' % bar.symbol) self.order(bar.symbol, SHORT, CLOSE, var.open_vol, limit_price=bar.close + symbol_obj.tick_size) else: if bar.close > boll.mid and bar.close > bar.open and ( boll.top - boll.bot) / boll.mid > var.spread_thres: var.close_count += 1 log.info('%s 平空计数器+1 close_count %s' % (bar.symbol, var.close_count)) if var.close_count >= 3: if self.pre_close(var, bar.symbol): log.info('%s 平空' % bar.symbol) msg.send('%s 平空' % bar.symbol) self.order(bar.symbol, SHORT, CLOSE, var.open_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size)
def stop_loss(self, var, tick, symbol_obj): if var.direction != '': # 止损 1 if var.open_by_two_big_bar_flag: if var.direction == SHORT: if tick.last_price - var.open_price > var.two_big_bar_stop_thres * symbol_obj.tick_size: msg.send('%s 两根大阴线开仓 5 tick_size 止损' % tick.symbol) log.info('%s 两根大阴线开仓 5 tick_size 止损' % tick.symbol) self.order(tick.symbol, SHORT, CLOSE, var.open_vol, limit_price=tick.last_price + var.slippage * symbol_obj.tick_size) var.reverse_flag = True elif var.direction == LONG: if var.open_price - tick.last_price > var.two_big_bar_stop_thres * symbol_obj.tick_size: msg.send('%s 两根大阳线开仓 5 tick_size 止损' % tick.symbol) log.info('%s 两根大阳线开仓 5 tick_size 止损' % tick.symbol) self.order(tick.symbol, LONG, CLOSE, var.open_vol, limit_price=tick.last_price - var.slippage * symbol_obj.tick_size) var.reverse_flag = True # 止损 2 upnl = (var.open_price - tick.last_price) * var.open_vol * symbol_obj.contract_size if var.direction == LONG: upnl = (tick.last_price - var.open_price ) * var.open_vol * symbol_obj.contract_size if upnl < 0 and abs(upnl) / var.open_margin > var.stop_loss_thres: if var.direction == SHORT: msg.send('%s 空单损失超过0.02止损' % tick.symbol) log.info('%s 空单损失超过0.02止损' % tick.symbol) self.order(tick.symbol, SHORT, CLOSE, var.open_vol, limit_price=tick.last_price + var.slippage * symbol_obj.tick_size) var.reverse_flag = True elif var.direction == LONG: msg.send('%s 多单损失超过0.02止损' % tick.symbol) log.info('%s 多单损失超过0.02止损' % tick.symbol) self.order(tick.symbol, LONG, CLOSE, var.open_vol, limit_price=tick.last_price - var.slippage * symbol_obj.tick_size) var.reverse_flag = True
def short_open_by_tick(self, var, tick): if var.signal_count == 1 and var.pre_bar_direction_flag == SHORT: if var.bar_n_2.close - tick.last_price >= var.tick_open_thres * var.boll_n_2.mid: log.info('%s 按tick 开空' % tick.symbol) msg.send('%s 按tick 开空' % tick.symbol) symbol_obj = self.context.symbol_infos[tick.symbol] self.order(tick.symbol, SHORT, OPEN, var.limit_vol, limit_price=tick.last_price - var.slippage * symbol_obj.tick_size) var.pre_bar_direction_flag = '' var.signal_count = 0 var.bar_n_2 = None var.boll_n_2 = None
def on_trade(self, trade): var = self.context.vars[trade.symbol] symbol_obj = self.context.symbol_infos[trade.symbol] if trade.offset == OPEN: var.direction = trade.direction var.open_vol += trade.vol var.open_price = trade.price var.open_margin = var.open_vol * symbol_obj.contract_size * var.open_price * symbol_obj.broker_margin * 0.01 else: var.open_vol -= trade.vol if var.open_vol == 0: # 清仓初始化各种中间变量 var.initialize() if var.reverse_flag: var.reverse_flag = False var.reverse_count += 1 if trade.direction == SHORT and var.reverse_count <= var.max_reverse_count: msg.send('%s 空单止损后反相开多' % trade.symbol) log.info('%s 空单止损后反相开多' % trade.symbol) self.order(trade.symbol, LONG, OPEN, var.limit_vol, limit_price=var.last_price + var.slippage * symbol_obj.tick_size) elif trade.direction == LONG and var.reverse_count <= var.max_reverse_count: msg.send('%s 多单止损后反相开空' % trade.symbol) log.info('%s 多单止损后反相开空' % trade.symbol) self.order(trade.symbol, SHORT, OPEN, var.limit_vol, limit_price=var.last_price - var.slippage * symbol_obj.tick_size) else: # 平仓、止盈时 清空反手计数器 var.reverse_count = 0
def close_signal(self, var, bar, symbol_obj): if var.open_vol > 0: if var.direction == LONG: if bar.open - bar.close > var.open_thres * symbol_obj.tick_size: msg.send('%s 持有多单后大阴线平仓' % bar.symbol) log.info('%s 持有多单后大阴线平仓' % bar.symbol) self.order(bar.symbol, LONG, CLOSE, var.open_vol, limit_price=bar.close - var.slippage * symbol_obj.tick_size) elif var.direction == SHORT: if bar.close - bar.open > var.open_thres * symbol_obj.tick_size: msg.send('%s 持有空单后大阳线平仓' % bar.symbol) log.info('%s 持有空单后大阳线平仓' % bar.symbol) self.order(bar.symbol, SHORT, CLOSE, var.open_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size)
def stop_loss(self, var, tick): if var.direction != '': symbol_obj = self.context.symbol_infos[tick.symbol] if var.direction == LONG: if var.open_price - tick.last_price > var.stop_loss_thres * var.boll_t.mid or tick.last_price < var.boll_t.bot: log.info('%s 多单止损' % tick.symbol) msg.send('%s 多单止损' % tick.symbol) self.order(tick.symbol, LONG, CLOSE, var.open_vol, limit_price=tick.last_price - var.slippage * symbol_obj.tick_size) elif var.direction == SHORT: if tick.last_price - var.open_price > var.stop_loss_thres * var.boll_t.mid or tick.last_price > var.boll_t.top: log.info('%s 空单止损' % tick.symbol) msg.send('%s 空单止损' % tick.symbol) self.order(tick.symbol, SHORT, CLOSE, var.open_vol, limit_price=tick.last_price + var.slippage * symbol_obj.tick_size)
def handle_bar(self, bar): print('时间:%s %s' % (dt.now(), bar)) # 撤单 for sys_id, order in self.context.orders.items(): if order.symbol == bar.symbol: self.cancel_order(order) var = self.context.vars[bar.symbol] symbol_obj = self.context.symbol_infos[var.symbol] # 判断是否需要平仓 if self.pre_close(var, bar.symbol): self.close_signal(var, bar, symbol_obj) # 判断最大利润 if var.open_vol > 0: delta = var.open_price - bar.close if var.direction == LONG: delta = bar.close - var.open_price if delta / var.open_price > var.gain_thres: var.gain_over_flag = True if delta > var.max_gain: var.max_gain = delta if var.pre_bar_direction_flag == LONG: if bar.close - bar.open > var.open_thres * symbol_obj.tick_size and bar.close - var.big_bar_open < var.second_big_bar_open_thres * symbol_obj.tick_size: log.info('%s 按barj+k.close开多' % bar.symbol) msg.send('%s 按barj+k.close开多' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, LONG, OPEN, var.limit_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size) var.open_by_two_big_bar_flag = True else: msg.send('%s 按barj+k.close开多 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 按barj+k.close开多 有持仓或挂单舍弃开仓信号' % bar.symbol) if var.num_from_big_bar < var.open_num_from_big_bar: var.exchange_peak(bar.open) var.exchange_peak(bar.close) var.num_from_big_bar += 1 elif var.num_from_big_bar < var.max_open_num_from_big_bar: var.exchange_peak(bar.open) var.exchange_peak(bar.close) var.num_from_big_bar += 1 if bar.close > var.big_bar_close and var.min_price > var.big_bar_open and var.max_price > var.big_bar_close: msg.send('%s 大阳线 N-J>=5开多' % bar.symbol) log.info('%s 大阳线 N-J>=5开多' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, LONG, OPEN, var.limit_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size) else: msg.send('%s 大阳线 N-J>=5开多仓 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 大阳线 N-J>=5开多仓 有持仓或挂单舍弃开仓信号' % bar.symbol) elif var.min_price < var.big_bar_open and var.max_price < var.big_bar_close and bar.close < var.big_bar_open: msg.send('%s 大阳线 N-J>=5开空' % bar.symbol) log.info('%s 大阳线 N-J>=5开空' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, SHORT, OPEN, var.limit_vol, limit_price=bar.close - var.slippage * symbol_obj.tick_size) else: msg.send('%s 大阳线 N-J>=5开多空 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 大阳线 N-J>=5开多空 有持仓或挂单舍弃开仓信号' % bar.symbol) if var.num_from_big_bar == var.max_open_num_from_big_bar: msg.send('%s 大阳线第25个bar重置清空信号' % bar.symbol) log.info('%s 大阳线第25个bar重置清空信号' % bar.symbol) var.clear_signal() elif var.pre_bar_direction_flag == SHORT: if bar.open - bar.close > var.open_thres * symbol_obj.tick_size and var.big_bar_open - bar.close < var.second_big_bar_open_thres * symbol_obj.tick_size: msg.send('%s 大阴线按barj+k.close开空' % bar.symbol) log.info('%s 大阴线按barj+k.close开空' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, SHORT, OPEN, var.limit_vol, limit_price=bar.close - var.slippage * symbol_obj.tick_size) var.open_by_two_big_bar_flag = True else: msg.send('%s 大阴线按barj+k.close开空 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 大阴线按barj+k.close开空 有持仓或挂单舍弃开仓信号' % bar.symbol) if var.num_from_big_bar < var.open_num_from_big_bar: var.exchange_peak(bar.open) var.exchange_peak(bar.close) var.num_from_big_bar += 1 elif var.num_from_big_bar < var.max_open_num_from_big_bar: var.exchange_peak(bar.open) var.exchange_peak(bar.close) var.num_from_big_bar += 1 if bar.close < var.big_bar_close and var.min_price < var.big_bar_close and var.max_price < var.big_bar_open: msg.send('%s 大阴线 N-J>=5开空' % bar.symbol) log.info('%s 大阴线 N-J>=5开空' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, SHORT, OPEN, var.limit_vol, limit_price=bar.close - var.slippage * symbol_obj.tick_size) else: msg.send('%s 大阴线 N-J>=5开空 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 大阴线 N-J>=5开空 有持仓或挂单舍弃开仓信号' % bar.symbol) elif var.min_price > var.big_bar_close and var.max_price > var.big_bar_open and bar.close > var.big_bar_open: msg.send('%s 大阴线 N-J>=5开多' % bar.symbol) log.info('%s 大阴线 N-J>=5开多' % bar.symbol) if self.pre_open(var, bar.symbol): self.order(bar.symbol, LONG, OPEN, var.limit_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size) else: msg.send('%s 大阴线 N-J>=5开多 有持仓或挂单舍弃开仓信号' % bar.symbol) log.info('%s 大阴线 N-J>=5开多 有持仓或挂单舍弃开仓信号' % bar.symbol) if var.num_from_big_bar == var.max_open_num_from_big_bar: msg.send('%s 大阴线第25个bar重置清空信号' % bar.symbol) log.info('%s 大阴线第25个bar重置清空信号' % bar.symbol) var.clear_signal() # msg.send('%s check 是否要转变信号' % bar.symbol) self.pre_bar_direction_flag(var, bar, symbol_obj) log.info(var)
def long_open_signal(self, var, bar, ma, boll): if var.direction == '' and var.pre_bar_direction_flag == LONG: if var.signal_count == 0: if (boll.top - boll.bot) / boll.mid > var.spread_thres: cond_1_1 = boll.top > bar.close > boll.mid > bar.open > boll.bot cond_1_2 = bar.close - boll.mid <= var.open_thres * boll.mid if cond_1_1 and cond_1_2: var.signal_count += 1 var.bar_n_2 = bar var.boll_n_2 = boll log.info('%s 多单第1根突破' % bar.symbol) msg.send('%s 多单第1根突破' % bar.symbol) elif var.signal_count == 1: if (boll.top - boll.bot) / boll.mid > var.spread_thres: cond_1_3 = bar.close > boll.mid cond_1_4 = bar.close - bar.open <= var.open_thres * boll.mid if cond_1_3 and cond_1_4: var.signal_count += 1 var.bar_n_1 = bar var.boll_n_1 = boll log.info('%s 多单第2根突破' % bar.symbol) else: var.pre_bar_direction_flag = '' var.signal_count = 0 var.bar_n_2 = None var.boll_n_2 = None else: var.pre_bar_direction_flag = '' var.signal_count = 0 var.bar_n_2 = None var.boll_n_2 = None elif var.signal_count == 2: if (boll.top - boll.bot) / boll.mid > var.spread_thres: cond_1_5 = bar.close > boll.mid cond_1_6 = bar.close - bar.open <= var.open_thres * boll.mid if cond_1_5 and cond_1_6: # 3 b2, b1 = var.bar_n_2, var.bar_n_1 mn = (b2.close + b1.close + bar.close) / 3.00 cond_3 = mn - ma > var.ma_thres * boll.mid if cond_3: if self.pre_open(var, bar.symbol): log.info('%s 连续3根满足条件开多' % bar.symbol) msg.send('%s 连续3根满足条件开多' % bar.symbol) symbol_obj = self.context.symbol_infos[ bar.symbol] self.order(bar.symbol, LONG, OPEN, var.limit_vol, limit_price=bar.close + var.slippage * symbol_obj.tick_size) # 放弃所有信号 var.pre_bar_direction_flag = '' var.signal_count = 0 var.bar_n_2 = None var.bar_n_1 = None var.boll_n_2 = None var.boll_n_1 = None