Fix transport and fund flow protocol edge cases

This commit is contained in:
minionszyw
2026-04-22 17:54:13 +08:00
parent 4cb48daabb
commit aa3b1ac319
8 changed files with 127 additions and 31 deletions
+3 -3
View File
@@ -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
+1 -2
View File
@@ -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
+7 -15
View File
@@ -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]]):
+3 -3
View File
@@ -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
+9 -1
View File
@@ -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:
"""关闭连接。"""