def _load_ext(self): """根据当前配置文件下的信息载入行情api和交易api,记住这个api的选项是可选的""" self.active = True if "CONNECT_INFO" in self.config.keys(): info = self.config.get("CONNECT_INFO") else: raise ConfigError(message="没有相应的登录信息", args=("没有发现登录信息",)) MdApi, TdApi = Interface.get_interface(self) if self.config.get("MD_FUNC"): self.market = MdApi(self.event_engine) self.market.connect(info) if self.config.get("TD_FUNC"): if self.config['INTERFACE'] == "looper": self.trader = TdApi(self.event_engine, self) else: self.trader = TdApi(self.event_engine) self.trader.connect(info) show_me = graphic_pattern(__version__, self.engine_method) print(show_me) if self.refresh: if self.r is not None: self.r_flag = False sleep(self.config['REFRESH_INTERVAL'] + 1.5) self.r = Thread(target=refresh_query, args=(self,),daemon=True) self.r.start() else: self.r = Thread(target=refresh_query, args=(self,), daemon=True) self.r.start() self.r_flag = True
def cover(self, price: float, volume: float, origin: [BarData, TickData, TradeData, OrderData, PositionData], price_type: OrderType = OrderType.LIMIT, stop: bool = False, lock: bool = False, **kwargs): """ 平多头, 注意返回是一个list, 因为单号会涉及到平昨平今组合平仓 Args: price (float): 价格 volume(float): 手数, 股票会自动*100 origin(Any(BarData, TradeData, TickData, OrderData, PositionData)): 快速获取品种和交易所信息 price_type(OrderType): 价格类型 Returns: str: 单号 """ if not isinstance(self.app.config['SLIPPAGE_COVER'], float) and not isinstance( self.app.config['SLIPPAGE_COVER'], int): raise ConfigError(message="滑点配置应为浮点小数") price = price - self.app.config['SLIPPAGE_COVER'] req_list = [helper.generate_order_req_by_var(volume=x[1], price=price, offset=x[0], direction=Direction.SHORT, type=price_type, exchange=origin.exchange, symbol=origin.symbol) for x in self.get_req(origin.local_symbol, Direction.LONG, volume, self.app)] return [self.send_order(req) for req in req_list if req.volume != 0]
def buy(self, price: float, volume: float, origin: [BarData, TickData, TradeData, OrderData, PositionData], price_type: OrderType = OrderType.LIMIT, stop: bool = False, lock: bool = False, **kwargs): """ 多头开仓 Args: price (float): 价格 volume(float): 手数, 股票会自动*100 origin(Any(BarData, TradeData, TickData, OrderData, PositionData)): 快速获取品种和交易所信息 price_type(OrderType): 价格类型 Returns: str: 单号 """ if not isinstance(self.app.config['SLIPPAGE_BUY'], float) and not isinstance( self.app.config['SLIPPAGE_BUY'], int): raise ConfigError(message="滑点配置应为浮点小数或者整数") price = price + self.app.config['SLIPPAGE_BUY'] req = helper.generate_order_req_by_var(volume=volume, price=price, offset=Offset.OPEN, direction=Direction.LONG, type=price_type, exchange=origin.exchange, symbol=origin.symbol) return self.send_order(req)
def short(self, price: float, volume: float, origin: [BarData, TickData, TradeData, OrderData, PositionData], price_type: OrderType = OrderType.LIMIT, stop: bool = False, lock: bool = False, **kwargs): """ 开仓 空头 """ if not isinstance(self.app.config['SLIPPAGE_SHORT'], float) and not isinstance( self.app.config['SLIPPAGE_SHORT'], int): raise ConfigError(message="滑点配置应为浮点小数") price = price + self.app.config['SLIPPAGE_SHORT'] req = helper.generate_order_req_by_var(volume=volume, price=price, offset=Offset.OPEN, direction=Direction.SHORT, type=price_type, exchange=origin.exchange, symbol=origin.symbol) return self.send_order(req)
def cover(self, price: float, volume: float, origin: [BarData, TickData, TradeData, OrderData, PositionData], price_type: OrderType = OrderType.LIMIT, stop: bool = False, lock: bool = False, **kwargs): if not isinstance(self.looper.params['slippage_cover'], float) and not isinstance( self.looper.params['slippage_cover'], int): raise ConfigError(message="滑点配置应为浮点小数") price = price + self.looper.exec_intercept['slippage_cover'] req_list = [ helper.generate_order_req_by_var(volume=x[1], price=price, offset=x[0], direction=Direction.LONG, type=price_type, exchange=origin.exchange, symbol=origin.symbol) for x in self.get_req(origin.local_symbol, Direction.SHORT, volume, self.looper) ] return [ self.looper.send_order(req) for req in req_list if req.volume != 0 ]
def sell(self, price: float, volume: float, origin: [BarData, TickData, TradeData, OrderData] = None, stop: bool = False, lock: bool = False, **kwargs): """ 平空头 """ if not isinstance(self.app.config['SLIPPAGE_SELL'], float) and not isinstance( self.app.config['SLIPPAGE_SELL'], int): raise ConfigError(message="滑点配置应为浮点小数") price = price + self.app.config['SLIPPAGE_SELL'] req_list = [ helper.generate_order_req_by_var(volume=x[1], price=price, offset=x[0], direction=Direction.LONG, type=OrderType.LIMIT, exchange=origin.exchange, symbol=origin.symbol) for x in self.get_req(origin.local_symbol, Direction.SHORT, volume, self.app) ] return [self.send_order(req) for req in req_list if req.volume != 0]
def init_interface(self): if self.config.get("PATTERN", "real") == "real" and not self._init_interface: self.active = True if "CONNECT_INFO" in self.config.keys(): info = self.config.get("CONNECT_INFO") else: raise ConfigError(message="没有相应的登录信息", args=("没有发现登录信息", )) MdApi, TdApi = Interface.get_interface(self) if self.config.get("MD_FUNC"): self.market = MdApi(self.app_signal) self.market.connect(info) if self.config.get("TD_FUNC"): self.trader = TdApi(self.app_signal) self.trader.connect(info) self._init_interface = True elif self.config.get("PATTERN", "real") == "looper" and not self._init_interface: self.config["INTERFACE"] = "looper" Market, Trader = Interface.get_interface(app=self) self.trader = Trader(self.app_signal, self) self.market = Market(self.app_signal) self._init_interface = True
def _running(self, logout=True): """ 根据当前配置文件下的信息载入行情api和交易api 注意此函数同时会根据构造函数中的refresh参数决定开启定时线程, 向CtpBee里面提供定时查询账户持仓功能 """ self.active = True if "CONNECT_INFO" in self.config.keys(): info = self.config.get("CONNECT_INFO") else: raise ConfigError(message="没有相应的登录信息", args=("没有发现登录信息",)) show_me = graphic_pattern(__version__, self.engine_method) if logout: print(show_me) MdApi, TdApi = Interface.get_interface(self) if self.config.get("MD_FUNC"): self.market = MdApi(self.app_signal) self.market.connect(info) if self.config.get("TD_FUNC"): self.trader = TdApi(self.app_signal) self.trader.connect(info) if self.refresh: if self.r is not None: self.r_flag = False sleep(self.config['REFRESH_INTERVAL'] + 1.5) self.r = Thread(target=refresh_query, args=(self,), daemon=True) self.r.start() else: self.r = Thread(target=refresh_query, args=(self,), daemon=True) self.r.start() self.r_flag = True
def _load_ext(self): """根据当前配置文件下的信息载入行情api和交易api,记住这个api的选项是可选的""" self.__active = True if "CONNECT_INFO" in self.config.keys(): info = self.config.get("CONNECT_INFO") else: raise ConfigError(message="没有相应的登录信息", args=("没有发现登录信息", )) if self.config.get("TD_FUNC"): self.trader = BeeTdApi() self.trader.connect(info) sleep(0.5) self.market = BeeMdApi() self.market.connect(info)
def short(self, price, volume, origin, price_type: OrderType = OrderType.LIMIT, **kwargs): if not isinstance(self.looper.params['slippage_short'], float) and not isinstance( self.looper.params['slippage_short'], int): raise ConfigError(message="滑点配置应为浮点小数") req = OrderRequest(price=price, volume=volume, exchange=origin.exchange, offset=Offset.OPEN, direction=Direction.SHORT, type=price_type, symbol=origin.symbol) return self.looper.send_order(req)
def generate_pointer(): tick_type = current_app.config.get('TICK_DATABASE_TYPE') bar_type = current_app.config.get('BAR_DATABASE_TYPE') if tick_type is None or bar_type is None: raise ConfigError(args=("配置信息异常, 请检查TICK_DATABASE_TYPE和BAR_DATABASE_TYPE有没有被设置",)) tick_pointer = type_map[tick_type]( current_app.config.get('TICK_DATABASE_NAME'), user=current_app.config.get('TICK_DATABASE_USER'), password=current_app.config.get('TICK_DATABASE_PWD'), host=current_app.config.get('TICK_DATABASE_HOST'), port=current_app.config.get('TICK_DATABASE_PORT') ) bar_pointer = type_map[tick_type]( database=current_app.config.get('BAR_DATABASE_NAME'), user=current_app.config.get('BAR_DATABASE_USER'), password=current_app.config.get('BAR_DATABASE_PWD'), host=current_app.config.get('BAR_DATABASE_HOST'), port=current_app.config.get('BAR_DATABASE_PORT') ) return (tick_pointer, bar_pointer)
def update_trade(self, trade: TradeData) -> None: """ 当前选择调用这个接口的时候就已经确保了这个单子是可以成交的, make sure it can be traded if you choose to call this method, :param trade:交易单子/trade :return: """ # 根据当前成交单子 更新当前的持仓 -----> if trade.offset == Offset.OPEN: if self.commission != 0: commission_expense = trade.price * trade.volume * self.commission else: commission_expense = 0 elif trade.offset == Offset.CLOSETODAY: if self.interface.params.get("today_commission") != 0: commission_expense = trade.price * trade.volume * self.interface.params.get( "today_commission") else: commission_expense = 0 elif trade.offset == Offset.CLOSEYESTERDAY: if self.interface.params.get("yesterday_commission") != 0: commission_expense = trade.price * trade.volume * self.interface.params.get( "yesterday_commission") else: commission_expense = 0 else: if self.interface.params.get("close_commission") != 0: commission_expense = trade.price * trade.volume * self.interface.params.get( "close_commission") else: commission_expense = 0 if trade.offset == Offset.CLOSETODAY or trade.offset == Offset.CLOSEYESTERDAY or trade.offset == Offset.CLOSE: reversed_map = { Direction.LONG: Direction.SHORT, Direction.SHORT: Direction.LONG } position: PositionData = self.position_manager.get_position_by_ld( trade.local_symbol, reversed_map[trade.direction]) if self.interface.params.get( "size_map") is None or self.interface.params.get( "size_map").get(trade.local_symbol) is None: raise ConfigError(message="请检查你的回测配置中是否存在着size配置", args=("回测配置错误", )) if trade.direction == Direction.LONG: """ 平空头 """ pnl = (position.price - trade.price) * trade.volume * self.interface.params.get( "size_map").get(trade.local_symbol) else: """ 平多头 """ pnl = (trade.price - position.price ) * trade.volume * self.interface.params.get( "size_map").get(trade.local_symbol) self.balance += pnl self.balance -= commission_expense self.commission_expense += commission_expense self.count_statistics += 1 self.position_manager.update_trade(trade=trade) if not self.date: self.date = self.interface.date if self.interface.date != self.date: """ 新的一天 """ self.settle() self.date = self.interface.date
def _load_ext(self): """根据当前配置文件下的信息载入行情api和交易api,记住这个api的选项是可选的""" self.__active = True if "CONNECT_INFO" in self.config.keys(): info = self.config.get("CONNECT_INFO") else: raise ConfigError(message="没有相应的登录信息", args=("没有发现登录信息", )) MdApi, TdApi = Interface.get_interface(self) if self.config.get("MD_FUNC"): self.market = MdApi(self.event_engine) self.market.connect(info) if self.config.get("TD_FUNC"): if self.config['INTERFACE'] == "looper": self.trader = TdApi(self.event_engine, self) else: self.trader = TdApi(self.event_engine) self.trader.connect(info) show_me = \ f""" {"*" * 60} * * * ------------------------------------- * * | | * * | ctpbee: {__version__.ljust(16, " ")} | * * | work_mode: {self.work_mode.ljust(16, " ")} | * * | engine: {self.engine_method.ljust(16, " ")} | * * | | * * ------------------------------------- * * * {"*" * 60} """ print(show_me) # 检查work_mode if self.work_mode == "forever": """ 7×24小时 """ # 启动监视器 if self.p is not None: self.p_flag = False sleep(1.5) self.p = Thread(target=run_forever, args=(self, )) self.p.start() else: self.p = Thread(target=run_forever, args=(self, )) self.p.start() self.p_flag = True else: pass if self.refresh: if self.r is not None: self.r_flag = False sleep(self.config['REFRESH_INTERVAL'] + 1.5) self.r = Thread(target=refresh_query, args=(self, )) self.r.start() else: self.r = Thread(target=refresh_query, args=(self, )) self.r.start() self.r_flag = True self.p_flag = True