kaq-quant-common 0.2.2__tar.gz → 0.2.4__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.
Files changed (67) hide show
  1. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/PKG-INFO +1 -1
  2. kaq_quant_common-0.2.4/kaq_quant_common/common/modules/funding_rate_helper.py +103 -0
  3. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/modules/limit_order_helper.py +41 -19
  4. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_ddb_stream_write_resources.py +3 -1
  5. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/pyproject.toml +1 -1
  6. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/README.md +0 -0
  7. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/__init__.py +0 -0
  8. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/__init__.py +0 -0
  9. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/common/__init__.py +0 -0
  10. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/common/api_interface.py +0 -0
  11. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/common/auth.py +0 -0
  12. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/__init__.py +0 -0
  13. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/api_client_base.py +0 -0
  14. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/api_server_base.py +0 -0
  15. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/helper/order_helper.py +0 -0
  16. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/instruction_client.py +0 -0
  17. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/instruction_server_base.py +0 -0
  18. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/models/__init__.py +0 -0
  19. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/models/account.py +0 -0
  20. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/models/order.py +0 -0
  21. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/models/position.py +0 -0
  22. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/rest/instruction/models/transfer.py +0 -0
  23. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/__init__.py +0 -0
  24. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/exchange/models.py +0 -0
  25. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/exchange/ws_exchange_client.py +0 -0
  26. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/exchange/ws_exchange_server.py +0 -0
  27. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/instruction/__init__.py +0 -0
  28. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/instruction/ws_instruction_client.py +0 -0
  29. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/instruction/ws_instruction_server_base.py +0 -0
  30. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/models.py +0 -0
  31. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/ws_client_base.py +0 -0
  32. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/api/ws/ws_server_base.py +0 -0
  33. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/__init__.py +0 -0
  34. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/ddb_table_monitor.py +0 -0
  35. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/http_monitor.py +0 -0
  36. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/modules/limit_order_symbol_monitor.py +0 -0
  37. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/modules/limit_order_symbol_monitor_group.py +0 -0
  38. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/monitor_base.py +0 -0
  39. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/monitor_group.py +0 -0
  40. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/redis_table_monitor.py +0 -0
  41. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/statistics/funding_rate_history_statistics.py +0 -0
  42. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/statistics/kline_history_statistics.py +0 -0
  43. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/common/ws_wrapper.py +0 -0
  44. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/config/config.yaml +0 -0
  45. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/__init__.py +0 -0
  46. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_ddb_pool_stream_read_resources.py +0 -0
  47. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_ddb_stream_init_resources.py +0 -0
  48. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_ddb_stream_read_resources.py +0 -0
  49. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_mysql_init_resources.py +0 -0
  50. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_mysql_resources.py +0 -0
  51. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_postgresql_resources.py +0 -0
  52. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_quant_hive_resources.py +0 -0
  53. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/resources/kaq_redis_resources.py +0 -0
  54. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/__init__.py +0 -0
  55. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/dagster_job_check_utils.py +0 -0
  56. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/dagster_utils.py +0 -0
  57. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/date_util.py +0 -0
  58. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/enums_utils.py +0 -0
  59. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/error_utils.py +0 -0
  60. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/hash_utils.py +0 -0
  61. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/log_time_utils.py +0 -0
  62. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/logger_utils.py +0 -0
  63. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/mytt_utils.py +0 -0
  64. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/signal_utils.py +0 -0
  65. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/sqlite_utils.py +0 -0
  66. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/uuid_utils.py +0 -0
  67. {kaq_quant_common-0.2.2 → kaq_quant_common-0.2.4}/kaq_quant_common/utils/yml_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaq_quant_common
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary:
5
5
  Author: kevinfuture
6
6
  Author-email: liuenbofuture@foxmail.com
@@ -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)
@@ -94,7 +94,9 @@ class KaqQuantDdbStreamWriteRepository:
94
94
  for row in arr:
95
95
  parts = []
96
96
  for i, v in enumerate(row):
97
- if i in str_idx:
97
+ if v is None or pd.isna(v):
98
+ parts.append("NULL")
99
+ elif i in str_idx:
98
100
  parts.append(f"'{v}'") # 直接拼接最快
99
101
  else:
100
102
  parts.append(str(v))
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kaq_quant_common"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = ""
5
5
  authors = [
6
6
  {name = "kevinfuture",email = "liuenbofuture@foxmail.com"}