pyqqq 0.12.186__tar.gz → 0.12.187__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyqqq might be problematic. Click here for more details.

Files changed (58) hide show
  1. {pyqqq-0.12.186 → pyqqq-0.12.187}/PKG-INFO +1 -1
  2. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyproject.toml +1 -1
  3. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/tracker.py +0 -8
  4. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/realtime.py +33 -6
  5. {pyqqq-0.12.186 → pyqqq-0.12.187}/README.md +0 -0
  6. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/__init__.py +0 -0
  7. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/__init__.py +0 -0
  8. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/broker.py +0 -0
  9. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/environment.py +0 -0
  10. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/logger.py +0 -0
  11. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/positionprovider.py +0 -0
  12. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/strategy.py +0 -0
  13. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/utils.py +0 -0
  14. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/backtest/wallclock.py +0 -0
  15. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/__init__.py +0 -0
  16. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/ebest/__init__.py +0 -0
  17. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/ebest/domestic_stock.py +0 -0
  18. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/ebest/oauth.py +0 -0
  19. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/ebest/simple.py +0 -0
  20. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/ebest/tr_client.py +0 -0
  21. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/helper.py +0 -0
  22. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/__init__.py +0 -0
  23. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/domestic_stock.py +0 -0
  24. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/oauth.py +0 -0
  25. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/overseas_stock.py +0 -0
  26. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/simple.py +0 -0
  27. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/simple_overseas.py +0 -0
  28. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/kis/tr_client.py +0 -0
  29. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/brokerage/multiprocess_tracker.py +0 -0
  30. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/config.py +0 -0
  31. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/__init__.py +0 -0
  32. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/daily.py +0 -0
  33. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/domestic.py +0 -0
  34. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/index.py +0 -0
  35. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/minutes.py +0 -0
  36. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/overseas.py +0 -0
  37. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/ticks.py +0 -0
  38. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/data/us_stocks.py +0 -0
  39. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/datatypes.py +0 -0
  40. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/executors/__init__.py +0 -0
  41. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/executors/hook.py +0 -0
  42. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/__init__.py +0 -0
  43. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/api_client.py +0 -0
  44. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/array.py +0 -0
  45. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/casting.py +0 -0
  46. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/compute.py +0 -0
  47. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/copycat.py +0 -0
  48. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/daily_tickers.py +0 -0
  49. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/display.py +0 -0
  50. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/kvstore.py +0 -0
  51. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/limiter.py +0 -0
  52. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/local_cache.py +0 -0
  53. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/logger.py +0 -0
  54. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/market_schedule.py +0 -0
  55. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/mock_api.py +0 -0
  56. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/position_classifier.py +0 -0
  57. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/retry.py +0 -0
  58. {pyqqq-0.12.186 → pyqqq-0.12.187}/pyqqq/utils/singleton.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqqq
3
- Version: 0.12.186
3
+ Version: 0.12.187
4
4
  Summary: Package for quantitative strategy development on the PyQQQ platform
5
5
  License: MIT
6
6
  Author: PyQQQ team
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyqqq"
3
- version = "0.12.186"
3
+ version = "0.12.187"
4
4
  description = "Package for quantitative strategy development on the PyQQQ platform"
5
5
  authors = ["PyQQQ team <pyqqq.cs@gmail.com>"]
6
6
  readme = "README.md"
@@ -474,15 +474,7 @@ class TradingTracker:
474
474
  self.positions = self.simple_api.get_positions()
475
475
 
476
476
  def _refresh_pending_orders(self):
477
- old_pending_orders = {}
478
- for o in self.pending_orders:
479
- old_pending_orders[o.order_no] = o
480
-
481
477
  self.pending_orders = self.simple_api.get_pending_orders(exchanges=list(OrderExchange))
482
- for o in self.pending_orders:
483
- old_pending_order = old_pending_orders.get(o.order_no)
484
- if old_pending_order is not None:
485
- o.average_purchase_price = old_pending_order.average_purchase_price
486
478
 
487
479
  def _notify_pending_order_update(self, status: str, order: StockOrder):
488
480
  # deprecated
@@ -8,10 +8,11 @@ from typing import List, Union
8
8
  import websockets
9
9
 
10
10
  import pyqqq.config as c
11
- from pyqqq.datatypes import DataExchange
11
+ from pyqqq.datatypes import DataExchange, Exchange
12
12
  from pyqqq.utils.api_client import raise_for_status, send_request
13
13
  from pyqqq.utils.logger import get_logger
14
14
  from pyqqq.utils.singleton import singleton
15
+ from pyqqq.utils.market_schedule import is_trading_time, get_next_trading_day, get_market_schedule
15
16
 
16
17
  logger = get_logger(__name__)
17
18
 
@@ -136,6 +137,7 @@ class TickEventListener:
136
137
  self.retry_cnt = 0
137
138
  self.ws = None
138
139
  self.tot_retry_cnt = 0
140
+ self.reconnect_datetime = None
139
141
  logger.info(f"{self.LOG_TAG}init")
140
142
 
141
143
  if "event_add_delay" in config:
@@ -143,12 +145,12 @@ class TickEventListener:
143
145
 
144
146
  if "health_ping_delay" in config:
145
147
  self.health_ping_delay = config["health_ping_delay"]
146
-
148
+ now_int_str = str(int(dtm.datetime.now().timestamp()))
147
149
  if client_id is not None:
148
150
  api_key = os.getenv("PYQQQ_API_KEY") or ""
149
- self.client_id = client_id + api_key
151
+ self.client_id = client_id + api_key + "_" + now_int_str
150
152
  else:
151
- self.client_id = api_key
153
+ self.client_id = api_key + "_" + now_int_str
152
154
 
153
155
  self.url = url
154
156
  if self.url is None:
@@ -186,13 +188,37 @@ class TickEventListener:
186
188
  async for message in websocket:
187
189
  # logger.debug(f"{self.LOG_TAG}message: {message}")
188
190
  await self.handle_response(message)
191
+
192
+ logger.warning(f"{self.LOG_TAG}Websocket connection closed by server. code: {websocket.close_code}, reason: {websocket.close_reason}")
189
193
  except websockets.exceptions.ConnectionClosed:
190
194
  logger.info(f"{self.LOG_TAG}Connection closed")
191
- await self.on_connect_failed()
195
+ if websocket.close_code == 4409:
196
+ logger.info(f"{self.LOG_TAG}Connection closed by server with code: {websocket.close_code}, reason: {websocket.close_reason}")
197
+
198
+ self.move_events_to_pending()
199
+
200
+ if is_trading_time(dtm.datetime.now()):
201
+ logger.info("try reconnect next minute")
202
+ self.reconnect_datetime = dtm.datetime.now() + dtm.timedelta(minutes=1)
203
+ else:
204
+ logger.info("not trading time")
205
+ next_trading_day = get_next_trading_day(dtm.datetime.now().date())
206
+ next_market_schedule = get_market_schedule(next_trading_day, Exchange.NXT)
207
+ next_start_time = dtm.datetime.combine(next_trading_day, next_market_schedule.open_time)
208
+ logger.info(f"reconnect at {next_start_time}")
209
+ self.reconnect_datetime = next_start_time
210
+
211
+ await asyncio.sleep(self.reconnect_datetime.timestamp() - dtm.datetime.now().timestamp())
212
+
213
+ await self.connect_ws()
214
+
215
+ else:
216
+ await self.on_connect_failed()
192
217
  except Exception as e:
193
218
  logger.info(f"{self.LOG_TAG}Connection failed. error: {e}")
194
219
  await self.on_connect_failed()
195
220
  finally:
221
+ logger.info(f"{self.LOG_TAG}Websocket connection closed")
196
222
  self.ws_connected = False
197
223
 
198
224
  async def health_ping(self):
@@ -321,7 +347,8 @@ class TickEventListener:
321
347
  logger.debug(f"{self.LOG_TAG} try connect events:{cur_pending_event_ids}, connected: {res}")
322
348
 
323
349
  else:
324
- logger.debug(f"{self.LOG_TAG}not connected")
350
+ logger.info(f"{self.LOG_TAG} not connected. stop process_events_appending")
351
+ return
325
352
 
326
353
  await asyncio.sleep(self.event_add_delay)
327
354
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes