mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 22:44:17 +08:00
Fix transport and fund flow protocol edge cases
This commit is contained in:
+3
-3
@@ -75,11 +75,11 @@ def _classify_fund_flow(records: list[TransactionRecord]) -> FundFlow:
|
||||
if not direction:
|
||||
continue
|
||||
|
||||
if amount >= 1_000_000:
|
||||
if amount > 1_000_000:
|
||||
stats[f"super_{direction}"] += amount
|
||||
elif amount >= 200_000:
|
||||
elif amount > 200_000:
|
||||
stats[f"large_{direction}"] += amount
|
||||
elif amount >= 40_000:
|
||||
elif amount > 40_000:
|
||||
stats[f"medium_{direction}"] += amount
|
||||
else:
|
||||
stats[f"small_{direction}"] += amount
|
||||
|
||||
@@ -52,8 +52,7 @@ class GetHistoryFundFlowCmd(BaseCommand[list[HistoricalFundFlow]]):
|
||||
|
||||
# 记录格式:4字节日期 + 8个4字节自定义浮点金额
|
||||
# [0]日期, [1..4]流入(超/大/中/小), [5..8]流出(超/大/中/小)
|
||||
# 这里的 i 是 uint32 原始字节,随后需用 _decode_volume 解码
|
||||
raw_data = struct.unpack("<Iiiiiiiii", body[pos:pos+36])
|
||||
raw_data = struct.unpack("<IIIIIIIII", body[pos:pos+36])
|
||||
|
||||
raw_date = raw_data[0]
|
||||
year = raw_date // 10000
|
||||
|
||||
@@ -17,22 +17,14 @@ from .base import BaseCommand
|
||||
def _format_server_time(raw: int) -> str:
|
||||
"""将 reversed_bytes0 整数转换为 HH:MM:SS.mmm 字符串。
|
||||
|
||||
方法来自 pytdx issue #187。raw 为 14999212 → "14:59:57.163"
|
||||
该字段编码为“小时 + 百万分之一小时的小数部分”。
|
||||
例如:14999212 → "14:59:57.163"
|
||||
"""
|
||||
s = str(raw)
|
||||
if len(s) < 6:
|
||||
return s
|
||||
# 最后6位:前两位=秒,后四位=毫秒的某种编码
|
||||
time_part = s[:-6] + ":"
|
||||
last6 = int(s[-6:])
|
||||
if int(s[-6:-4]) < 60:
|
||||
time_part += s[-6:-4] + ":"
|
||||
time_part += f"{last6 % 10000 * 60 / 10000.0:06.3f}"
|
||||
else:
|
||||
mins = last6 * 60 // 1000000
|
||||
secs = (last6 * 60 % 1000000) * 60 / 1000000.0
|
||||
time_part += f"{mins:02d}:{secs:06.3f}"
|
||||
return time_part
|
||||
hours, fractional_hour = divmod(raw, 1_000_000)
|
||||
total_millis = fractional_hour * 3600 // 1000
|
||||
minutes, remainder = divmod(total_millis, 60_000)
|
||||
seconds, millis = divmod(remainder, 1000)
|
||||
return f"{hours:02d}:{minutes:02d}:{seconds:02d}.{millis:03d}"
|
||||
|
||||
|
||||
class GetSecurityQuotesCmd(BaseCommand[list[SecurityQuote]]):
|
||||
|
||||
@@ -20,9 +20,9 @@ class FundFlow:
|
||||
|
||||
# 流入项 (Buy)
|
||||
super_in: float # 超大单流入 (>100万)
|
||||
large_in: float # 大单流入 (20万-100万)
|
||||
medium_in: float # 中单流入 (4万-20万)
|
||||
small_in: float # 小单流入 (<4万)
|
||||
large_in: float # 大单流入 (>20万 且 <=100万)
|
||||
medium_in: float # 中单流入 (>4万 且 <=20万)
|
||||
small_in: float # 小单流入 (<=4万)
|
||||
|
||||
# 流出项 (Sell)
|
||||
super_out: float
|
||||
|
||||
@@ -126,7 +126,15 @@ class TdxConnection:
|
||||
sock.close()
|
||||
raise TdxConnectionError(f"无法连接 {self.host}:{self.port}: {e}") from e
|
||||
self._sock = sock
|
||||
self._send_setup()
|
||||
try:
|
||||
self._send_setup()
|
||||
except Exception:
|
||||
try:
|
||||
sock.close()
|
||||
except OSError:
|
||||
pass
|
||||
self._sock = None
|
||||
raise
|
||||
|
||||
def close(self) -> None:
|
||||
"""关闭连接。"""
|
||||
|
||||
Reference in New Issue
Block a user