def __init__(self, account=None, platform=None, strategy=None, order_no=None, symbol=None, action=None, price=0, quantity=0, remain=0, status=ORDER_STATUS_NONE, avg_price=0, order_type=ORDER_TYPE_LIMIT, trade_type=TRADE_TYPE_NONE, ctime=None, utime=None): self.order_no = order_no self.action = action self.order_type = order_type self.symbol = symbol self.price = price self.quantity = quantity self.remain = remain if remain else quantity self.status = status self.avg_price = avg_price self.trade_type = trade_type self.ctime = ctime if ctime else tools.get_cur_timestamp_ms() self.utime = utime if utime else tools.get_cur_timestamp_ms()
def notice(self): if not self.dingding: return notice = True if self.last_notice_time > 0: ut_time = tools.get_cur_timestamp_ms() if self.last_notice_time + self.notice_period > ut_time: notice = False if not notice: return self.last_notice_time = tools.get_cur_timestamp_ms() if self.record_node: msg = self.record_node.__str__() DingTalk.send_text_msg(content=msg)
def limit_order(self, action, quantity): """ 订单限制 :param action: :param quantity: :return: """ # 检查开多和开空的时间间隔是否太短 5s同一订单不下单 ut_time = tools.get_cur_timestamp_ms() long_or_short_order = None if action == ORDER_ACTION_BUY and quantity > 0: # 开多 long_or_short_order = TradingCurb.LONG.value elif action == ORDER_ACTION_SELL and quantity < 0: # 开空 long_or_short_order = TradingCurb.SHORT.value last_order_info = self.last_order.get(long_or_short_order) if last_order_info: if last_order_info["action"] == action and last_order_info["quantity"] == quantity and \ ut_time < last_order_info["ts"] + 5000: return False if long_or_short_order: last__order_info = { "action": action, "quantity": quantity, "ts": ut_time } self.last_order[long_or_short_order] = last__order_info # 检查当前时候有该类型订单挂单了 if action == ORDER_ACTION_BUY: if quantity > 0: trade_type = TRADE_TYPE_BUY_OPEN else: trade_type = TRADE_TYPE_BUY_CLOSE else: if quantity > 0: trade_type = TRADE_TYPE_SELL_CLOSE else: trade_type = TRADE_TYPE_SELL_OPEN orders = copy.copy(self.orders) for no in orders.values(): if no.symbol == self.symbol + "/" + self.trade_symbol: if no.trade_type == trade_type and ( no.status == ORDER_STATUS_NONE or no.status == ORDER_STATUS_SUBMITTED or no.status == ORDER_STATUS_PARTIAL_FILLED): logger.info("hand same order.", no.symbol, no.trade_type, no.status, caller=self) return False return True
def update(self, short_quantity=0, short_avg_price=0, short_avg_open_price=0, long_quantity=0, long_avg_price=0, long_avg_open_price=0, liquid_price=0, utime=None): self.short_quantity = short_quantity self.short_avg_price = short_avg_price self.short_avg_open_price = short_avg_open_price self.long_quantity = long_quantity self.long_avg_price = long_avg_price self.long_avg_open_price = long_avg_open_price self.liquid_price = liquid_price self.utime = utime if utime else tools.get_cur_timestamp_ms()
def __init__(self, symbol=None, leverage=None, short_quantity=None, short_avg_price=None, short_avg_open_price=None, short_pnl_ratio=None, short_pnl_unreal=None, short_pnl=None, long_quantity=None, long_avg_price=None, long_avg_open_price=None, long_pnl_ratio=None, long_pnl_unreal=None, long_pnl=None, long_pos_margin=None, short_pos_margin=None, liquid_price=None, maint_margin_ratio=None, utime=None): """ 初始化持仓对象 @param symbol 合约名称 """ self.symbol = symbol self.leverage = leverage # 杠杆倍数 self.short_quantity = short_quantity # 空仓数量 self.short_avg_price = short_avg_price # 空仓持仓平均价格 self.short_avg_open_price = short_avg_open_price # 空仓开仓平均价格 self.short_pnl_ratio = short_pnl_ratio # 空仓收益率 self.short_pnl_unreal = short_pnl_unreal # 空仓未实现盈亏 self.short_pnl = short_pnl # 空仓已实现盈亏 self.long_quantity = long_quantity # 多仓数量 self.long_avg_price = long_avg_price # 多仓持仓平均价格 self.long_avg_open_price = long_avg_open_price # 多长开仓平均价格 self.long_pnl_ratio = long_pnl_ratio # 多仓收益率 self.long_pnl_unreal = long_pnl_unreal # 多仓未实现盈亏 self.long_pnl = long_pnl # 多仓已实现盈亏 self.long_pos_margin = long_pos_margin # 多仓持仓保证金 self.short_pos_margin = short_pos_margin # 空仓持仓保证金 self.liquid_price = liquid_price # 预估爆仓价格 self.maint_margin_ratio = maint_margin_ratio # 保证金率 self.utime = utime if utime else tools.get_cur_timestamp_ms() self.init = False
async def before_strategy(self): # 撤单 orders = copy.copy(self.orders) ut_time = tools.get_cur_timestamp_ms() if len(orders) > 0: for no in orders.values(): if ut_time >= no.ctime + self.order_cancel_time: if self.platform == "swap": await self.trade.revoke_order( self.trade_symbol.upper(), self.trade_symbol, no.order_no) else: await self.trade.revoke_order(self.symbol.upper(), self.trade_symbol, no.order_no) # 检查k是否初始完了 if self.auto_curb: if len(self.klines) != len(KILINE_PERIOD): # k线数据没有 return False else: if len(self.klines) != 1: # k线数据没有 return False if len(self.trades) == 0: # 最近成交记录没有 return False if not self.position.init: return False # 设置计算参数 self.long_status = 0 self.short_status = 0 self.long_trade_size = 0 self.short_trade_size = 0 self.last_price = 0 trades = copy.copy(self.trades) last_trades = trades.get("market." + self.mark_symbol + ".trade.detail") if last_trades and len(last_trades) > 0: self.last_price = round_to(float(last_trades[-1].price), self.price_tick) if self.last_price <= 0: # 最近一次的成交价格没有 return False return True
def record_trade(self, symbol, tick, period="5min", init=False): if not self.period: self.period = period self.period_ts = TRADE[self.period] if self.period_ts < self.notice_period: self.notice_period = TRADE[self.period] if not self.init and not init: return curr_ts = tools.get_cur_timestamp_ms() ts = int(tick.get("ts")) if ts + self.period_ts < curr_ts: return t = tools.ts_to_datetime_str( int(ts / TRADE[self.period]) * TRADE[self.period] / 1000) if not self.record_node: self.record_node = TradeRecordNode(ts, t, symbol, self.period) direction = tick.get("direction") quantity = tick.get("amount") price = tick.get("price") self.record_node.add(direction, quantity, price) self.trade_data.append(tick) if self.init and len(self.trade_data) > 0: delete = False ts = int(self.trade_data[0]["ts"]) while (ts + self.period_ts) < curr_ts and len(self.trade_data) > 0: delete = True old_tick = self.trade_data.popleft() old_direction = old_tick.get("direction") old_quantity = old_tick.get("amount") self.record_node.dell(old_direction, old_quantity) ts = int(self.trade_data[0]["ts"]) if delete: t = tools.ts_to_datetime_str( int(ts / TRADE[self.period]) * TRADE[self.period] / 1000) self.record_node.ts = ts self.record_node.t = t self.notice()
def ask_bid_price(self): ask_price = 0 bid_price = 0 ds = copy.copy(self.depths) if len(ds) == 0: return ask_price, bid_price data = ds["market.{s}.depth.{d}".format( s=self.mark_symbol.upper(), d=config.mark_sub["depth"]["step"])] if len(data) == 0: return ask_price, bid_price ut_time = tools.get_cur_timestamp_ms() if data[-1].timestamp + 30000 < ut_time: logger.error("depth not update too long, magin:", (ut_time - data[-1].timestamp), caller=self) return ask_price, bid_price ask_data = data[-1].asks bid_data = data[-1].bids if ask_data: ask_price = float(ask_data[0][0]) if bid_data: bid_price = float(bid_data[0][0]) return ask_price, bid_price