kaq-quant-common 0.2.3__py3-none-any.whl → 0.2.5__py3-none-any.whl

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.
@@ -0,0 +1,103 @@
1
+ # 避免写入导致阻塞
2
+ import datetime
3
+ import threading
4
+ import time
5
+
6
+ import pandas as pd
7
+
8
+ from kaq_quant_common.resources.kaq_ddb_stream_write_resources import (
9
+ KaqQuantDdbStreamMTWWriteRepository, KaqQuantDdbStreamWriteRepository)
10
+ from kaq_quant_common.utils import logger_utils
11
+
12
+
13
+ class FundingRateHelper:
14
+
15
+ def __init__(
16
+ self,
17
+ ddb: KaqQuantDdbStreamWriteRepository | KaqQuantDdbStreamMTWWriteRepository,
18
+ ddb_table_name: str,
19
+ ):
20
+ # 最新快照缓存与刷库线程控制
21
+ self._latest_snapshots: dict[str, tuple] = {}
22
+ self._latest_lock = threading.Lock()
23
+ # 写入到ddb的频率,默认1s
24
+ self._flush_interval_ms = 1000
25
+ self._stop_event = threading.Event()
26
+ self._flusher_thread = threading.Thread(target=self._flush_loop, daemon=True)
27
+ self._flusher_thread.name = "FundingRateHelperFlusherThread"
28
+ self._is_df = False
29
+
30
+ #
31
+ self._ddb = ddb
32
+ self._ddb_table_name = ddb_table_name
33
+
34
+ #
35
+ self._logger = logger_utils.get_logger(self)
36
+
37
+ self._build_data: callable = None
38
+
39
+ def set_build_data(self, build_data: callable):
40
+ self._build_data = build_data
41
+
42
+ def push_data(self, symbol: str, data: dict, arg: dict = None):
43
+ with self._latest_lock:
44
+ self._latest_snapshots[symbol] = (data, arg)
45
+
46
+ def start(self):
47
+ self._flusher_thread.start()
48
+
49
+ def stop(self):
50
+ self._stop_event.set()
51
+ self._flusher_thread.join()
52
+
53
+ def _flush_loop(self):
54
+ # 周期性地将每个symbol的最新快照批量入库
55
+ while not self._stop_event.is_set():
56
+ to_process = None
57
+ with self._latest_lock:
58
+ if self._latest_snapshots:
59
+ to_process = list(self._latest_snapshots.items())
60
+ self._latest_snapshots.clear()
61
+
62
+ if to_process:
63
+ df: pd.DataFrame = None
64
+ list_data: list = []
65
+ now = int(datetime.datetime.now().timestamp() * 1000)
66
+
67
+ for symbol, (data, arg) in to_process:
68
+ sub_df = self._build_data(symbol, data, arg)
69
+ if isinstance(sub_df, pd.DataFrame):
70
+ self._is_df = True
71
+ # 输出一下
72
+ data_first_now = int(sub_df["create_time"].iloc[0])
73
+ if now - data_first_now > 2000:
74
+ self._logger.debug(
75
+ f"数据时间{data_first_now} 与当前时间{now} 差值{now - data_first_now} 超过2000ms"
76
+ )
77
+
78
+ if df is None:
79
+ df = sub_df
80
+ else:
81
+ df = pd.concat([df, sub_df], ignore_index=True)
82
+ else:
83
+ list_data = sub_df
84
+
85
+ # 入库
86
+ if self._is_df:
87
+ if df is not None and not df.empty:
88
+ try:
89
+ self._ddb.save2stream_batch(self._ddb_table_name, df=df)
90
+ except Exception as e:
91
+ # 避免刷库异常导致线程退出
92
+ self._logger.error(f"批量写入df失败: {e}")
93
+ else:
94
+ if len(list_data) > 0:
95
+ try:
96
+ self._ddb.save2stream_list(list_data)
97
+ except Exception as e:
98
+ # 避免刷库异常导致线程退出
99
+ self._logger.error(f"批量写入数组失败: {e}")
100
+
101
+ # 是dataFrame的才睡眠,数组处理交由ddb自己控制节奏
102
+ if self._is_df:
103
+ time.sleep(self._flush_interval_ms / 1000.0)
@@ -4,15 +4,19 @@ import threading
4
4
  import time
5
5
 
6
6
  import pandas as pd
7
+
7
8
  from kaq_quant_common.resources.kaq_ddb_stream_write_resources import (
8
- KaqQuantDdbStreamWriteRepository,
9
- )
9
+ KaqQuantDdbStreamMTWWriteRepository, KaqQuantDdbStreamWriteRepository)
10
10
  from kaq_quant_common.utils import logger_utils
11
11
 
12
12
 
13
13
  class LimitOrderHelper:
14
14
 
15
- def __init__(self, ddb: KaqQuantDdbStreamWriteRepository, ddb_table_name: str):
15
+ def __init__(
16
+ self,
17
+ ddb: KaqQuantDdbStreamWriteRepository | KaqQuantDdbStreamMTWWriteRepository,
18
+ ddb_table_name: str,
19
+ ):
16
20
  # 最新快照缓存与刷库线程控制
17
21
  self._latest_snapshots: dict[str, tuple] = {}
18
22
  self._latest_lock = threading.Lock()
@@ -21,6 +25,7 @@ class LimitOrderHelper:
21
25
  self._stop_event = threading.Event()
22
26
  self._flusher_thread = threading.Thread(target=self._flush_loop, daemon=True)
23
27
  self._flusher_thread.name = "LimitOrderHelperFlusherThread"
28
+ self._is_df = False
24
29
 
25
30
  #
26
31
  self._ddb = ddb
@@ -56,26 +61,43 @@ class LimitOrderHelper:
56
61
 
57
62
  if to_process:
58
63
  df: pd.DataFrame = None
64
+ list_data: list = []
59
65
  now = int(datetime.datetime.now().timestamp() * 1000)
60
66
 
61
67
  for symbol, (data, arg) in to_process:
62
68
  sub_df = self._build_data(symbol, data, arg)
63
- # 输出一下
64
- data_first_now = int(sub_df["create_time"].iloc[0])
65
- if now - data_first_now > 2000:
66
- self._logger.debug(f"数据时间{data_first_now} 与当前时间{now} 差值{now - data_first_now} 超过2000ms")
67
-
68
- if df is None:
69
- df = sub_df
69
+ if isinstance(sub_df, pd.DataFrame):
70
+ self._is_df = True
71
+ # 输出一下
72
+ data_first_now = int(sub_df["create_time"].iloc[0])
73
+ if now - data_first_now > 2000:
74
+ self._logger.debug(
75
+ f"数据时间{data_first_now} 与当前时间{now} 差值{now - data_first_now} 超过2000ms"
76
+ )
77
+
78
+ if df is None:
79
+ df = sub_df
80
+ else:
81
+ df = pd.concat([df, sub_df], ignore_index=True)
70
82
  else:
71
- df = pd.concat([df, sub_df], ignore_index=True)
83
+ list_data = sub_df
72
84
 
73
85
  # 入库
74
- if df is not None and not df.empty:
75
- try:
76
- self._ddb.save2stream_batch(self._ddb_table_name, df=df)
77
- except Exception as e:
78
- # 避免刷库异常导致线程退出
79
- self._logger.error(f"批量写入失败: {e}")
80
-
81
- time.sleep(self._flush_interval_ms / 1000.0)
86
+ if self._is_df:
87
+ if df is not None and not df.empty:
88
+ try:
89
+ self._ddb.save2stream_batch(self._ddb_table_name, df=df)
90
+ except Exception as e:
91
+ # 避免刷库异常导致线程退出
92
+ self._logger.error(f"批量写入df失败: {e}")
93
+ else:
94
+ if len(list_data) > 0:
95
+ try:
96
+ self._ddb.save2stream_list(list_data)
97
+ except Exception as e:
98
+ # 避免刷库异常导致线程退出
99
+ self._logger.error(f"批量写入数组失败: {e}")
100
+
101
+ # 是dataFrame的才睡眠,数组处理交由ddb自己控制节奏
102
+ if self._is_df:
103
+ time.sleep(self._flush_interval_ms / 1000.0)
@@ -22,7 +22,7 @@ class KaqQuantDdbPoolStreamReadRepository:
22
22
 
23
23
  # 连接地址为localhost,端口为8848的DolphinDB,登录用户名为admin,密码为123456的账户,连接数为8
24
24
  self.pool = ddb.DBConnectionPool(host, port, pool_size, user, passwd,
25
- loadBalance=True,
25
+ loadBalance=False,
26
26
  compress=True,
27
27
  protocol=protocal,
28
28
  reConnect=True,
@@ -29,7 +29,7 @@ class KaqQuantDdbStreamWriteRepository:
29
29
  self.session.connect(host, port, user, passwd, tryReconnectNums=10, reconnect=True, keepAliveTime=1000, readTimeout=10, writeTimeout=5)
30
30
  # 流表订阅用的
31
31
  # self.session.enableStreaming(threadCount=5)
32
- # self.pool = ddb.DBConnectionPool(host, port, userid=user, password=passwd, loadBalance=True, reConnect=True, tryReconnectNums=5, sqlStd=SqlStd.MySQL)
32
+ # self.pool = ddb.DBConnectionPool(host, port, userid=user, password=passwd, loadBalance=False, reConnect=True, tryReconnectNums=5, sqlStd=SqlStd.MySQL)
33
33
 
34
34
  # 需要注意的是 fetchSize 取值不能小于 8192 (记录条数)
35
35
  self.size = 8192
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaq_quant_common
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary:
5
5
  Author: kevinfuture
6
6
  Author-email: liuenbofuture@foxmail.com
@@ -27,7 +27,8 @@ kaq_quant_common/api/ws/ws_server_base.py,sha256=-JFA5fnYHXPYBZ09aZmhYuhgDHFfJbk
27
27
  kaq_quant_common/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  kaq_quant_common/common/ddb_table_monitor.py,sha256=7Yihz_uGGujo_QqqPl45Gp8fwUMMw1auXx5egbzyYlE,3662
29
29
  kaq_quant_common/common/http_monitor.py,sha256=_yChiwfVv1c5g_lKgYUjWY40fX61BWVK8SL4kXwRfwk,2375
30
- kaq_quant_common/common/modules/limit_order_helper.py,sha256=Pbh1RHapr9D0Uacup5oQqeXgfI72zLAG2vZHEjPgoPY,2894
30
+ kaq_quant_common/common/modules/funding_rate_helper.py,sha256=BVGNS6E7aVPITOz5u4g7vBUHOrm1S1Uri8psgWxp-BQ,3853
31
+ kaq_quant_common/common/modules/limit_order_helper.py,sha256=Py9DPBXq1-QnjEh6mGQOA7vD3TVNUabnS_rMf0SQx5U,3853
31
32
  kaq_quant_common/common/modules/limit_order_symbol_monitor.py,sha256=TBK48qyeCSQvkfDMv3J_0UM7f3OuBRKRFYDcL9kG6Cs,2876
32
33
  kaq_quant_common/common/modules/limit_order_symbol_monitor_group.py,sha256=oEqHIwxhqAzckmluHJHZHiHUNmAyaS2JyK2nXO58UhY,2394
33
34
  kaq_quant_common/common/monitor_base.py,sha256=E4EUMsO3adNltCDNRgxkvUSbTTfKOL9S1zzN3WkZvpU,2467
@@ -38,10 +39,10 @@ kaq_quant_common/common/statistics/kline_history_statistics.py,sha256=pQgWkP7Z0n
38
39
  kaq_quant_common/common/ws_wrapper.py,sha256=JNJ0CIjDXgCsRjOLSbCi7ysYDHw7tT_aK7V4ADqw3vA,452
39
40
  kaq_quant_common/config/config.yaml,sha256=ST_QBLo7kwVaoNOvuN3mpeSF7LPNSWdD7EjxrBYZYBs,230
40
41
  kaq_quant_common/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- kaq_quant_common/resources/kaq_ddb_pool_stream_read_resources.py,sha256=Y-rtGpBF3bNh2mPZ2Lze6D9JZnpkqh24OEh7okikh1w,2536
42
+ kaq_quant_common/resources/kaq_ddb_pool_stream_read_resources.py,sha256=q4P96rSrEcWn9ki09UD0vw00iFq_bpgOFTrRzVG7uCA,2537
42
43
  kaq_quant_common/resources/kaq_ddb_stream_init_resources.py,sha256=0MxxbajocTFzcRD344rfZQPKOwwuqCbyoT6dQpIox-o,3349
43
44
  kaq_quant_common/resources/kaq_ddb_stream_read_resources.py,sha256=WShsXMoL8o-JZvrtAd7H2Cg-vrE47QbsdGgURaQwiZs,3165
44
- kaq_quant_common/resources/kaq_ddb_stream_write_resources.py,sha256=_-bNnxnG5I98JOlV46FYXlYoJRkzlMzWREHUonornF4,12638
45
+ kaq_quant_common/resources/kaq_ddb_stream_write_resources.py,sha256=Ql8pqZDzbC_4pZCVgfiW09Vbsnc8qC_iTJpjBE9xjD8,12639
45
46
  kaq_quant_common/resources/kaq_mysql_init_resources.py,sha256=UcqWey6LgoMqvLq1SxK33nS6-rkViGYhzUPxcrucOks,827
46
47
  kaq_quant_common/resources/kaq_mysql_resources.py,sha256=282jpXvYlEQNx-hicYTNBHDii85KYgN7BQQSMS9aPFM,13211
47
48
  kaq_quant_common/resources/kaq_postgresql_resources.py,sha256=iG1eYkciI0xUIBdEpGqKGOLBFxvVrfbBoTuaOmhQ0v0,1762
@@ -61,6 +62,6 @@ kaq_quant_common/utils/signal_utils.py,sha256=zBSyEltNTKqkQCsrETd47kEBb3Q_OWUBUn
61
62
  kaq_quant_common/utils/sqlite_utils.py,sha256=UDDFKfwL0N-jFifl40HdyOCENh2YQfW5so6hRaSJpv0,5722
62
63
  kaq_quant_common/utils/uuid_utils.py,sha256=pm_pnXpd8n9CI66x3A20cOEUiriJyqHaKGCeLrgkBxU,71
63
64
  kaq_quant_common/utils/yml_utils.py,sha256=gcKjb_-uuUajBGAl5QBPIZTg2wXm7qeeJvtHflj_zOE,4513
64
- kaq_quant_common-0.2.3.dist-info/METADATA,sha256=wk6Okdv4qKVJxUnM54tR6sTtw4zMR2Qicwv5NZOXsXk,1970
65
- kaq_quant_common-0.2.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
66
- kaq_quant_common-0.2.3.dist-info/RECORD,,
65
+ kaq_quant_common-0.2.5.dist-info/METADATA,sha256=fW-ErJTmmEIBIGdLBabB7xZNNaUrQDyRlonF6-pkdEI,1970
66
+ kaq_quant_common-0.2.5.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
67
+ kaq_quant_common-0.2.5.dist-info/RECORD,,