def mongodb_init(cls, host="127.0.0.1", port=27017, username="", password="", dbname="admin"): """ Initialize a connection pool for MongoDB. Args: host: Host for MongoDB server. port: Port for MongoDB server. username: Username for MongoDB server. password: Password for MongoDB server. dbname: DB name to connect for, default is `admin`. """ if username and password: uri = "mongodb://{username}:{password}@{host}:{port}/{dbname}".format( username=quote_plus(username), password=quote_plus(password), host=quote_plus(host), port=port, dbname=dbname) else: uri = "mongodb://{host}:{port}/{dbname}".format(host=host, port=port, dbname=dbname) cls._mongo_client = motor.motor_asyncio.AsyncIOMotorClient( uri, connectTimeoutMS=5000, serverSelectionTimeoutMS=5000) #LoopRunTask.register(cls._check_connection, 2) SingleTask.call_later(cls._check_connection, 2) #模拟串行定时器,避免并发 logger.info("create mongodb connection pool.")
def enable_timer(self, interval=1): """使能定时器功能 """ if config.backtest or config.datamatrix: #回测模式或者数据矩阵模式 pass #暂时不支持定时器的模拟 else: #实盘模式 self._interval = interval SingleTask.call_later(self._later_call, self._interval)
async def reset_order_list(self): # 撤销当前账号所有 success, error = await self.revoke_all_order() if error: logger.error('撤销所有订单失败, error: ', error) SingleTask.call_later(self.reset_order_list, delay=1) else: if self._init_success_callback: SingleTask.run(self._init_success_callback, True, None)
def __init__(self, **kwargs): """ 初始化 """ e = None if not kwargs.get("account"): e = Error("param account miss") if not kwargs.get("strategy"): e = Error("param strategy miss") if not kwargs.get("symbol"): e = Error("param symbol miss") if not kwargs.get("host"): kwargs["host"] = "http://dev.api.bitqq.vip:81" if not kwargs.get("wss"): kwargs['wss'] = 'wss://dev.websocket.bitqq.vip:9094' if not kwargs.get("access_key"): e = Error("param access_key miss") if not kwargs.get("secret_key"): e = Error("param secret_key miss") if not kwargs.get("passphrase"): e = Error("param passphrase miss") if e: logger.error(e, caller=self) if kwargs.get("init_success_callback"): SingleTask.run(kwargs["init_success_callback"], False, e) return self._account = kwargs["account"] self._strategy = kwargs["strategy"] self._platform = BITQQ self._symbol = kwargs["symbol"] self._host = kwargs["host"] self._order_module_host = kwargs.get('order_module_host') self._access_key = kwargs["access_key"] self._secret_key = kwargs["secret_key"] self._passphrase = kwargs["passphrase"] self._asset_update_callback = kwargs.get("asset_update_callback") self._order_update_callback = kwargs.get("order_update_callback") self._position_update_callback = kwargs.get("position_update_callback") self._init_success_callback = kwargs.get("init_success_callback") self._contract_update_callback = kwargs.get('contract_update_callback') # 初始化 REST API 对象 self._rest_api = BitQQRestAPI( self._host, self._access_key, self._secret_key, self._passphrase, order_module_host=self._order_module_host) if self._asset_update_callback: AssetSubscribe(self._platform, self._account, self.on_event_asset_update) SingleTask.call_later(self.reset_order_list, delay=10)
async def on_time(self): """ 每秒钟执行一次. """ logger.info("on_time ...", caller=self) cur_ts_min = int(tools.get_cur_timestamp_ms()//60000*60000) #以分钟为刻度进行对齐的毫秒时间戳 if self.last_ts_min != cur_ts_min: #新的一分钟到来了 for sym in self.symbols: SingleTask.call_later(self._task_delay, 2, sym, self.last_ts_min) #等待两秒后再工作 self.last_ts_min = cur_ts_min
async def _check_connection(cls, *args, **kwargs): try: ns = await cls._mongo_client.list_database_names() if ns and isinstance(ns, list) and "admin" in ns: cls._connected = True except Exception as e: cls._connected = False logger.error("mongodb connection ERROR:", e) finally: SingleTask.call_later(cls._check_connection, 2) #开启下一轮检测 #数据库连接状态通知上层策略 if cls._last_state != cls.is_connected(): #状态发生变化 cls._last_state = cls.is_connected() if cls._last_state: state = State(None, None, "mongodb connection SUCCESS", State.STATE_CODE_DB_SUCCESS) else: state = State(None, None, "mongodb connection ERROR", State.STATE_CODE_DB_ERROR) for cb in cls._state_cbs: SingleTask.run(cb, state)
async def _later_call(self): """延时调用 """ await self.on_time() #继续开启下一个延迟过程,这种方式实现的定时器是串行模式,而不是并发模式,因为我们这里需要串行效果,这样适合策略编程 SingleTask.call_later(self._later_call, self._interval)
async def _later_call(): """延时调用 """ await on_time() SingleTask.call_later(_later_call, 16)
cleanup(resp) #清理此套接字下的所有交易通道 return resp async def on_time(): """检测是否有套接字已经不活跃 """ ts = tools.get_cur_timestamp_ms() for ws in app['sockets']: if ts - ws._my_last_ts > 15*1000: #超过15秒 await ws.close() async def _later_call(): """延时调用 """ await on_time() SingleTask.call_later(_later_call, 16) async def on_shutdown(app): for ws in app['sockets']: await ws.close() if __name__ == '__main__': app['sockets'] = [] app.router.add_routes(routes) app.on_shutdown.append(on_shutdown) SingleTask.call_later(_later_call, 16) web.run_app(app, port=9878)
def enable_timer(self, interval=1): """使能定时器功能 """ self._interval = interval SingleTask.call_later(self._later_call, self._interval)