center.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. import asyncio
  2. from http.client import NON_AUTHORITATIVE_INFORMATION
  3. from aiohttp import web
  4. import traceback
  5. import time
  6. import utils
  7. import logging, logging.handlers
  8. import signal
  9. import broker
  10. import os, json, sys, random
  11. def timeit(func):
  12. def wrapper(*args, **kwargs):
  13. nowTime = time.time()
  14. res = func(*args, **kwargs)
  15. spend_time = time.time() - nowTime
  16. spend_time = round(spend_time * 100, 2)
  17. print(f'{func.__name__} 耗时 {spend_time} ms')
  18. return res
  19. return wrapper
  20. def takeSecond(elem):
  21. return elem[1]
  22. import ccxt.async_support as ccxt
  23. ex_list = [
  24. ccxt.binanceusdm(),
  25. ccxt.binance(),
  26. # ccxt.okex5(),
  27. # ccxt.kucoin(),
  28. # ccxt.gateio(),
  29. # ccxt.coinex(),
  30. ]
  31. class Center:
  32. def __init__(self, fname, logname=None):
  33. print('############### 参数中心 ################')
  34. print(f'>> {utils.VERSION} <<<')
  35. print('*** 当前配置 ***')
  36. self.fname = fname
  37. self.params = utils.get_params(fname)
  38. for p in self.params.__dict__:
  39. print('***', p, ' => ', getattr(self.params, p))
  40. print('##################################################')
  41. pid = os.getpid()
  42. print(f'交易程序正在启动 进程号{pid}...')
  43. self.logger = self.get_logger(logname)
  44. self.params_base = dict()
  45. for i in broker.exchange_lists:self.params_base[i] = dict()
  46. self.params_dummy = dict()
  47. for i in broker.exchange_lists:self.params_dummy[i] = dict()
  48. self.params_real = dict()
  49. for i in broker.exchange_lists:self.params_real[i] = dict()
  50. self.win_dict = dict()
  51. for i in broker.exchange_lists:self.win_dict[i] = dict()
  52. self.loss_dict = dict()
  53. for i in broker.exchange_lists:self.loss_dict[i] = dict()
  54. self.choose_dict = dict()
  55. for i in broker.exchange_lists:self.choose_dict[i] = dict()
  56. self.dummy_choose_dict = dict()
  57. for i in broker.exchange_lists:self.dummy_choose_dict[i] = dict()
  58. try:
  59. with open('params_real.json','r') as f:
  60. self.params_real = json.load(f)
  61. except:
  62. pass
  63. try:
  64. with open('choose_dict.json','r') as f:
  65. self.choose_dict = json.load(f)
  66. except:
  67. pass
  68. try:
  69. with open('dummy_choose_dict.json','r') as f:
  70. self.dummy_choose_dict = json.load(f)
  71. except:
  72. pass
  73. try:
  74. with open('params_dummy.json','r') as f:
  75. self.params_dummy = json.load(f)
  76. except:
  77. pass
  78. self.loop = asyncio.get_event_loop()
  79. ###
  80. self.market = dict()
  81. self.score = dict()
  82. self.info_msg = "加载中..."
  83. def get_logger(self, logname):
  84. logger = logging.getLogger(__name__)
  85. logger.setLevel(logging.DEBUG)
  86. # log to txt
  87. formatter = logging.Formatter('[%(asctime)s] - %(levelname)s - %(message)s')
  88. if logname == None: logname = "log"
  89. handler = logging.handlers.RotatingFileHandler(f"{logname}.log",maxBytes=1024*1024*50,backupCount=10,encoding='utf-8')
  90. handler.setLevel(logging.DEBUG)
  91. handler.setFormatter(formatter)
  92. # log to console
  93. console = logging.StreamHandler()
  94. console.setLevel(logging.INFO)
  95. logger.addHandler(handler)
  96. logger.addHandler(console)
  97. logger.info('开启日志记录')
  98. return logger
  99. async def exit(self, delay=0):
  100. '''退出操作'''
  101. print(f"开始退出操作 delay{delay}")
  102. if delay > 0:
  103. await asyncio.sleep(delay)
  104. self.logger.info(f'停机退出')
  105. await asyncio.sleep(1)
  106. print("停机...")
  107. # self.loop.create_task(utils.ding(f"参数中心程序停止", 1, self.params.webhook, self.params.proxy))
  108. self.loop.stop()
  109. os._exit(0)
  110. async def read_market(self):
  111. market = dict()
  112. print("开始查询行情")
  113. for exchange in ex_list:
  114. if (exchange.has['fetchTickers']):
  115. tickers = await exchange.fetch_tickers()
  116. for i in tickers:
  117. symbol = tickers[i]['symbol']
  118. if '/USDT' not in symbol:continue
  119. pair = symbol.split('/')[0].lower() + '_' + symbol.split('/')[1].lower()
  120. last = tickers[i]['last']
  121. if last > 0:
  122. if pair not in market:
  123. market[pair] = last
  124. return market
  125. async def update_score(self):
  126. '''
  127. 按最近涨跌幅打分
  128. '''
  129. await asyncio.sleep(5)
  130. while 1:
  131. try:
  132. market = await self.read_market()
  133. self.score = dict()
  134. for i in self.market:
  135. if i in market:
  136. score = abs(market[i] - self.market[i])/market[i]
  137. if score > 0:
  138. self.score[i] = score
  139. score_list = []
  140. for i in self.score:
  141. score_list.append(self.score[i])
  142. if len(score_list) > 0:
  143. max_score = max(score_list)
  144. for i in self.score:
  145. self.score[i] = round(self.score[i]/max_score,3)
  146. self.market = market
  147. print("当前打分", self.score)
  148. await asyncio.sleep(60)
  149. except Exception as e:
  150. print("定时循环系统出错"+str(e))
  151. self.logger.error(traceback.print_exc())
  152. await asyncio.sleep(10)
  153. async def _on_timer(self):
  154. '''定期触发系统逻辑'''
  155. await asyncio.sleep(1)
  156. while 1:
  157. try:
  158. print('整理参数池...')
  159. # 重置info_msg
  160. self.info_msg = ""
  161. # 加载配置文件群
  162. p_list = []
  163. for root, dirs, files in os.walk(os.getcwd()):
  164. for file_name in files:
  165. if 'config_dummy' in file_name:
  166. p_list.append(utils.get_params(os.path.join(root, file_name)))
  167. # 打印本地参数数据
  168. self.params_base = dict()
  169. for i in broker.exchange_lists:self.params_base[i] = dict()
  170. for p in p_list:
  171. name = p.exchange + '@' + p.pair
  172. self.params_base[p.exchange][name] = dict()
  173. self.params_base[p.exchange][name]['pair'] = p.pair
  174. self.params_base[p.exchange][name]['exchange'] = p.exchange
  175. self.params_base[p.exchange][name]['open'] = p.open
  176. self.params_base[p.exchange][name]['close'] = p.close
  177. self.params_base[p.exchange][name]['refexchange'] = p.refexchange
  178. self.params_base[p.exchange][name]['refpair'] = p.refpair
  179. self.params_base[p.exchange][name]['profit'] = 0.0
  180. #### 整理params_real
  181. # 移除太旧的信息
  182. params_real = dict()
  183. for ex in broker.exchange_lists:
  184. params_real[ex] = dict()
  185. for name in self.params_real[ex].keys():
  186. if time.time() - self.params_real[ex][name]['time'] > utils.EARLY_STOP_SECOND:
  187. print(f"params real 记录时间太久 移除{name}")
  188. else:
  189. params_real[ex][name] = self.params_real[ex][name]
  190. self.params_real = params_real
  191. # 移除异常信息
  192. params_real = dict()
  193. for ex in broker.exchange_lists:
  194. params_real[ex] = dict()
  195. for name in self.params_real[ex].keys():
  196. if abs(float(self.params_real[ex][name]['profit'])) > 10000.0:
  197. print(f"params real 收益率异常 移除{name}")
  198. else:
  199. params_real[ex][name] = self.params_real[ex][name]
  200. self.params_real = params_real
  201. #### 整理params_dummy
  202. # 移除太旧的信息
  203. params_dummy = dict()
  204. for ex in broker.exchange_lists:
  205. params_dummy[ex] = dict()
  206. for name in self.params_dummy[ex].keys():
  207. if time.time() - self.params_dummy[ex][name]['time'] > utils.DUMMY_EARLY_STOP_SECOND:
  208. print(f"params dummy 记录时间太久 移除{name}")
  209. else:
  210. params_dummy[ex][name] = self.params_dummy[ex][name]
  211. self.params_dummy = params_dummy
  212. # 移除异常信息
  213. params_dummy = dict()
  214. for ex in broker.exchange_lists:
  215. params_dummy[ex] = dict()
  216. for name in self.params_dummy[ex].keys():
  217. if abs(float(self.params_dummy[ex][name]['profit'])) > 10000.0:
  218. print(f"params dummy 收益率异常 移除{name}")
  219. else:
  220. params_dummy[ex][name] = self.params_dummy[ex][name]
  221. self.params_dummy = params_dummy
  222. # 从params_real 提取 win_dict loss_dict
  223. self.logger.info('='*10)
  224. profit_thre = 0.001
  225. for ex in broker.exchange_lists:
  226. self.logger.info('='*10)
  227. self.info_msg += '='*10 + '\r'
  228. # 更新windict lossdict
  229. self.win_dict[ex] = dict()
  230. self.loss_dict[ex] = dict()
  231. profits = []
  232. pairs = []
  233. for name in self.params_real[ex]:
  234. profit = self.params_real[ex][name]['profit']
  235. profits.append(profit)
  236. pairs.append(self.params_real[ex][name]['pair'])
  237. if profit > profit_thre:
  238. self.win_dict[ex][name] = self.params_real[ex][name]
  239. self.win_dict[ex][name]['leverrate'] = 2.0
  240. else:
  241. self.loss_dict[ex][name] = self.params_real[ex][name]
  242. self.loss_dict[ex][name]['leverrate'] = 0.0
  243. if len(profits) > 0:
  244. max_profit = max(profits)
  245. max_profit_name = pairs[profits.index(max_profit)]
  246. max_profit - round(max_profit, 5)
  247. min_profit = min(profits)
  248. min_profit_name = pairs[profits.index(min_profit)]
  249. min_profit - round(min_profit, 5)
  250. avg_profit = round(sum(profits)/len(profits),5)
  251. win_num = 0
  252. for i in profits:
  253. if i > profit_thre:win_num+=1
  254. total_num = len(profits)
  255. base_num = len(self.params_base[ex])
  256. msg = f"Real情况 盘口{ex} 最大{max_profit_name} {max_profit} 最小{min_profit_name} {min_profit} 平均{avg_profit} 盈利{win_num} 记录{total_num} 总数{base_num}"
  257. self.logger.info(msg)
  258. self.info_msg += msg + "\r"
  259. msg = ""
  260. for i in range(total_num):
  261. msg += pairs[i] + " "
  262. if (i+1)%10 == 0:
  263. self.logger.info(msg)
  264. self.info_msg += msg + "\r"
  265. msg = ""
  266. self.logger.info(msg)
  267. self.info_msg += msg + "\r"
  268. self.logger.info('-'*10)
  269. self.info_msg += '-'*10 + '\r'
  270. # 打印dummy_params情况
  271. profits = []
  272. pairs = []
  273. for name in self.params_dummy[ex]:
  274. profit = self.params_dummy[ex][name]['profit']
  275. profits.append(profit)
  276. pairs.append(self.params_dummy[ex][name]['pair'])
  277. if len(profits) > 0:
  278. max_profit = max(profits)
  279. max_profit_name = pairs[profits.index(max_profit)]
  280. max_profit - round(max_profit, 5)
  281. min_profit = min(profits)
  282. min_profit_name = pairs[profits.index(min_profit)]
  283. min_profit - round(min_profit, 5)
  284. avg_profit = round(sum(profits)/len(profits),5)
  285. win_num = 0
  286. for i in profits:
  287. if i > profit_thre:win_num+=1
  288. total_num = len(profits)
  289. base_num = len(self.params_base[ex])
  290. msg = f"Dummy情况 盘口{ex} 最大{max_profit_name} {max_profit} 最小{min_profit_name} {min_profit} 平均{avg_profit} 盈利{win_num} 记录{total_num} 总数{base_num}"
  291. self.logger.info(msg)
  292. self.info_msg += msg + "\r"
  293. msg = ""
  294. for i in range(total_num):
  295. msg += pairs[i] + " "
  296. if (i+1)%10 == 0:
  297. self.logger.info(msg)
  298. self.info_msg += msg + "\r"
  299. msg = ""
  300. self.logger.info(msg)
  301. self.info_msg += msg + "\r"
  302. # 保存信息
  303. with open('params_real.json', 'w') as f:
  304. json.dump(self.params_real,f)
  305. with open('choose_dict.json', 'w') as f:
  306. json.dump(self.choose_dict,f)
  307. with open('dummy_choose_dict.json', 'w') as f:
  308. json.dump(self.dummy_choose_dict,f)
  309. with open('params_dummy.json', 'w') as f:
  310. json.dump(self.params_dummy,f)
  311. # 休眠
  312. await asyncio.sleep(60)
  313. except Exception as e:
  314. print("定时循环系统出错"+str(e))
  315. self.logger.error(traceback.print_exc())
  316. await asyncio.sleep(10)
  317. def stop(self):
  318. print(f'进入停机流程...')
  319. self.loop.create_task(self.exit(delay=1))
  320. async def get_info(self, request):
  321. print(request.remote)
  322. return web.Response(text=self.info_msg)
  323. async def get_dummy_params(self, request):
  324. '''
  325. 中控数据接口
  326. 从base参数池随机选参数
  327. '''
  328. data = await request.json()
  329. if isinstance(data, str):
  330. data = json.loads(data)
  331. exchange = data['exchange']
  332. res = dict()
  333. # 全部dummy实例从base参数池随机选参数 尝试新品种
  334. for _ in range(len(self.params_base[exchange])):
  335. name = random.choice(list(self.params_base[exchange].keys()))
  336. if name not in self.dummy_choose_dict[exchange]:
  337. self.dummy_choose_dict[exchange][name] = 0
  338. if name not in self.loss_dict[exchange] and time.time() - self.dummy_choose_dict[exchange][name] > utils.DUMMY_EARLY_STOP_SECOND:
  339. res[name] = self.params_base[exchange][name]
  340. res[name]['leverrate'] = 0.5
  341. self.dummy_choose_dict[exchange][name] = int(time.time())
  342. break
  343. ###### 如果没有找到满足条件的参数 随机一组参数
  344. if res == dict():
  345. name = random.choice(list(self.params_base[exchange].keys()))
  346. res[name] = self.params_base[exchange][name]
  347. res[name]['leverrate'] = 0.5
  348. self.dummy_choose_dict[exchange][name] = int(time.time())
  349. return web.Response(body=json.dumps(res))
  350. async def post_dummy_params(self, request):
  351. '''
  352. 中控数据接口
  353. 更新params_dummy参数池
  354. '''
  355. data = await request.json()
  356. # ip = request.remote
  357. # print(f'从{ip}更新dummy参数',data)
  358. if isinstance(data, str):
  359. data = json.loads(data)
  360. exchange = data['exchange']
  361. pair = data['pair']
  362. name = exchange+"@"+pair
  363. profit = round(float(data['profit']),4)
  364. #######
  365. if exchange in self.params_dummy:
  366. # 如果已有记录
  367. if name in self.params_dummy[exchange]:
  368. self.params_dummy[exchange][name]['exchange'] = data['exchange']
  369. self.params_dummy[exchange][name]['pair'] = data['pair']
  370. self.params_dummy[exchange][name]['open'] = data['open']
  371. self.params_dummy[exchange][name]['close'] = data['close']
  372. self.params_dummy[exchange][name]['refexchange'] = data['refexchange']
  373. self.params_dummy[exchange][name]['refpair'] = data['refpair']
  374. self.params_dummy[exchange][name]['profit'] = \
  375. round( profit * 0.3 + self.params_dummy[exchange][name]['profit'] * 0.7, 4)
  376. self.params_dummy[exchange][name]['time'] = int(time.time())
  377. else:
  378. # 如果没有记录
  379. self.params_dummy[exchange][name] = dict()
  380. self.params_dummy[exchange][name]['exchange'] = data['exchange']
  381. self.params_dummy[exchange][name]['pair'] = data['pair']
  382. self.params_dummy[exchange][name]['open'] = data['open']
  383. self.params_dummy[exchange][name]['close'] = data['close']
  384. self.params_dummy[exchange][name]['refexchange'] = data['refexchange']
  385. self.params_dummy[exchange][name]['refpair'] = data['refpair']
  386. self.params_dummy[exchange][name]['profit'] = profit
  387. self.params_dummy[exchange][name]['time'] = int(time.time())
  388. return web.Response(body=json.dumps({}))
  389. async def get_params(self, request):
  390. '''
  391. 中控数据接口
  392. 从base参数池随机选参数
  393. 从dummy参数池随机选参数
  394. '''
  395. data = await request.json()
  396. if isinstance(data, str):
  397. data = json.loads(data)
  398. exchange = data['exchange']
  399. res = dict()
  400. # 本盘口盈利品种数量
  401. win_num = len(self.win_dict[exchange])
  402. # 计算盈利参数占比
  403. if win_num == 0:
  404. # 没有发现盈利品种的时候 全部实例尝试新品种
  405. if random.randint(0,100) < 10:
  406. # 小概率 从base参数池选参数
  407. for _ in range(len(self.params_base[exchange])):
  408. name = random.choice(list(self.params_base[exchange].keys()))
  409. if name not in self.choose_dict[exchange]:
  410. self.choose_dict[exchange][name] = 0
  411. if name not in self.loss_dict[exchange] and time.time() - self.choose_dict[exchange][name] > utils.EARLY_STOP_SECOND:
  412. res[name] = self.params_base[exchange][name]
  413. res[name]['leverrate'] = 0.5
  414. self.choose_dict[exchange][name] = int(time.time())
  415. break
  416. else:
  417. # 大概率 从dummy参数池选参数
  418. # 计算概率数组
  419. p_list = []
  420. name_list = []
  421. for name in self.params_dummy[exchange]:
  422. p = self.params_dummy[exchange][name]['profit']
  423. if p > 0.0:
  424. p_list.append(p)
  425. name_list.append(name)
  426. if len(p_list) > 1:
  427. for _ in range(len(p_list)):
  428. name = random.choices(
  429. name_list,
  430. p_list,
  431. k=1,
  432. )[0]
  433. if name not in self.choose_dict[exchange]:
  434. self.choose_dict[exchange][name] = 0
  435. if name not in self.loss_dict[exchange] and time.time() - self.choose_dict[exchange][name] > utils.EARLY_STOP_SECOND:
  436. res[name] = self.params_dummy[exchange][name]
  437. res[name]['leverrate'] = 0.5
  438. self.choose_dict[exchange][name] = int(time.time())
  439. break
  440. else:
  441. # 允许10%的实例去搜索新品种
  442. if random.randint(0,100) < 90:
  443. # 跑实盘盈利品种
  444. res = self.win_dict[exchange]
  445. else:
  446. # 没有发现盈利品种的时候 全部实例尝试新品种
  447. if random.randint(0,100) < 10:
  448. # 小概率 从base参数池选参数
  449. for _ in range(len(self.params_base[exchange])):
  450. name = random.choice(list(self.params_base[exchange].keys()))
  451. if name not in self.choose_dict[exchange]:
  452. self.choose_dict[exchange][name] = 0
  453. if name not in self.loss_dict[exchange] and time.time() - self.choose_dict[exchange][name] > utils.EARLY_STOP_SECOND:
  454. res[name] = self.params_base[exchange][name]
  455. res[name]['leverrate'] = 0.5
  456. self.choose_dict[exchange][name] = int(time.time())
  457. break
  458. else:
  459. # 大概率 从dummy参数池选参数
  460. # 计算概率数组
  461. p_list = []
  462. name_list = []
  463. for name in self.params_dummy[exchange]:
  464. p = self.params_dummy[exchange][name]['profit']
  465. if p > 0.0:
  466. p_list.append(p)
  467. name_list.append(name)
  468. if len(p_list) > 1:
  469. for _ in range(len(p_list)):
  470. name = random.choices(
  471. name_list,
  472. p_list,
  473. k=1,
  474. )[0]
  475. if name not in self.choose_dict[exchange]:
  476. self.choose_dict[exchange][name] = 0
  477. if name not in self.loss_dict[exchange] and time.time() - self.choose_dict[exchange][name] > utils.EARLY_STOP_SECOND:
  478. res[name] = self.params_dummy[exchange][name]
  479. res[name]['leverrate'] = 0.5
  480. self.choose_dict[exchange][name] = int(time.time())
  481. break
  482. ###### 如果没有找到满足条件的参数 随机一组参数
  483. if res == dict():
  484. name = random.choice(list(self.params_base[exchange].keys()))
  485. res[name] = self.params_base[exchange][name]
  486. res[name]['leverrate'] = 0.5
  487. self.choose_dict[exchange][name] = int(time.time())
  488. return web.Response(body=json.dumps(res))
  489. async def post_params(self, request):
  490. '''
  491. 中控数据接口
  492. 更新real参数池
  493. '''
  494. data = await request.json()
  495. ip = request.remote
  496. # print(f'从{ip}更新参数',data)
  497. if isinstance(data, str):
  498. data = json.loads(data)
  499. exchange = data['exchange']
  500. pair = data['pair']
  501. name = exchange+"@"+pair
  502. profit = round(float(data['profit']),4)
  503. if exchange in self.params_real:
  504. # 如果已有记录
  505. if name in self.params_real[exchange]:
  506. self.params_real[exchange][name]['exchange'] = data['exchange']
  507. self.params_real[exchange][name]['pair'] = data['pair']
  508. self.params_real[exchange][name]['open'] = data['open']
  509. self.params_real[exchange][name]['close'] = data['close']
  510. self.params_real[exchange][name]['refexchange'] = data['refexchange']
  511. self.params_real[exchange][name]['refpair'] = data['refpair']
  512. self.params_real[exchange][name]['profit'] = \
  513. round( profit * 0.3 + self.params_real[exchange][name]['profit'] * 0.7, 4)
  514. self.params_real[exchange][name]['time'] = int(time.time())
  515. else:
  516. # 如果没有记录
  517. self.params_real[exchange][name] = dict()
  518. self.params_real[exchange][name]['exchange'] = data['exchange']
  519. self.params_real[exchange][name]['pair'] = data['pair']
  520. self.params_real[exchange][name]['open'] = data['open']
  521. self.params_real[exchange][name]['close'] = data['close']
  522. self.params_real[exchange][name]['refexchange'] = data['refexchange']
  523. self.params_real[exchange][name]['refpair'] = data['refpair']
  524. self.params_real[exchange][name]['profit'] = profit
  525. self.params_real[exchange][name]['time'] = int(time.time())
  526. return web.Response(body=json.dumps({}))
  527. async def _run_server(self):
  528. print('server正在启动...')
  529. await asyncio.sleep(10)
  530. app = web.Application()
  531. app.router.add_route('*', f'/get_info', self.get_info)
  532. app.router.add_route('POST', f'/get_params', self.get_params)
  533. app.router.add_route('POST', f'/get_dummy_params', self.get_dummy_params)
  534. app.router.add_route('POST', f'/post_params', self.post_params)
  535. app.router.add_route('POST', f'/post_dummy_params', self.post_dummy_params)
  536. try:
  537. self.loop.create_task(web._run_app(app, host='0.0.0.0', port=self.params.server_port, handle_signals=False))
  538. except:
  539. self.logger.error(traceback.format_exc())
  540. def run(self):
  541. '''启动ws行情获取'''
  542. tasks = []
  543. # 策略
  544. for i in [
  545. asyncio.ensure_future(self._run_server()),
  546. asyncio.ensure_future(self._on_timer()),
  547. # asyncio.ensure_future(self.update_score()),
  548. ]:
  549. tasks.append(i)
  550. def keyboard_interrupt(s, f):
  551. print("收到退出信号 准备关机")
  552. self.logger.info("收到退出信号 准备关机")
  553. self.stop()
  554. try:
  555. signal.signal(signal.SIGINT, keyboard_interrupt)
  556. signal.signal(signal.SIGTERM, keyboard_interrupt)
  557. if 'win' not in sys.platform:
  558. signal.signal(signal.SIGKILL, keyboard_interrupt)
  559. signal.signal(signal.SIGQUIT, keyboard_interrupt)
  560. except:
  561. pass
  562. self.loop.run_until_complete(asyncio.wait(tasks))
  563. if __name__ == "__main__":
  564. if 0:
  565. utils.check_auth()
  566. pnum = len(sys.argv)
  567. if pnum > 0:
  568. fname = None
  569. log_file = None
  570. pidnum = None
  571. for i in range(pnum):
  572. print(f"第{i}个参数为:{sys.argv[i]}")
  573. if sys.argv[i] == '-c' or sys.argv[i] == '--c':
  574. fname = sys.argv[i+1]
  575. elif sys.argv[i] == '-h':
  576. print("帮助文档")
  577. elif sys.argv[i] == '-log_file' or sys.argv[i] == '--log_file':
  578. log_file = sys.argv[i+1]
  579. elif sys.argv[i] == '-num' or sys.argv[i] == '--num':
  580. pidnum = sys.argv[i+1]
  581. elif sys.argv[i] == '-v' or sys.argv[i] == '--v':
  582. print("当前版本为 V4.1")
  583. if fname and log_file and pidnum:
  584. print(f"指定的配置为 fname:{fname} log_file:{log_file} pidnum:{pidnum}")
  585. date = time.strftime("%Y%m%d", time.localtime())
  586. logname = f"{log_file}-{date}"
  587. quant = Center(fname, logname)
  588. quant.run()
  589. elif fname:
  590. print(f"运行指定配置文件{fname}")
  591. quant = Center(fname)
  592. quant.run()
  593. else:
  594. print("缺少指定参数 运行默认配置文件")
  595. fname = 'config.toml'
  596. quant = Center(fname)
  597. quant.run()
  598. else:
  599. fname = 'config.toml'
  600. quant = Center(fname)
  601. quant.run()