This commit is contained in:
2026-07-28 20:15:11 +02:00
parent 8cc5f389f9
commit a151674441
4 changed files with 53 additions and 24 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ class Strategy(PulseWire[plugin.StrategyEngineMessage, plugin.StrategyEngineMess
def getWatchList(self): def getWatchList(self):
self.send(plugin.StrategyMessage.GetWatchList()) self.send(plugin.StrategyMessage.GetWatchList())
def getCandleStick(self, symbol: str, interval: general.CandleInterval, count: general.u32): def getCandleStick(self, symbol: str, interval: general.CandleIntervalType, count: general.u32):
msg = plugin.StrategyMessage.RequestCandlestick() msg = plugin.StrategyMessage.RequestCandlestick()
msg.symbol = symbol msg.symbol = symbol
msg.interval = interval msg.interval = interval
+37 -8
View File
@@ -76,30 +76,59 @@ class f32(PulseUnit): pass
class f64(PulseUnit): pass class f64(PulseUnit): pass
class decimal(PulseUnit): class decimal(PulseUnit):
size = struct.calcsize("<qb") # Exactly 16 bytes to match Rust's [u8; 16] output
size = 16
def __init__(self, value): def __init__(self, value):
self.value = Decimal(value) self.value = Decimal(value)
def to_com(self): def to_com(self) -> bytes:
sign, digits, exponent = self.value.as_tuple() sign, digits, exponent = self.value.as_tuple()
if not isinstance(exponent, int): if not isinstance(exponent, int):
raise ValueError("Cannot serialize NaN or Infinity") raise ValueError("Cannot serialize NaN or Infinity")
scale = -exponent scale = -exponent
integer = int("".join(map(str, digits))) mantissa = int("".join(map(str, digits)))
# Handle positive exponents (e.g. 5E+2 -> scale 0, mantissa 500)
if scale < 0:
mantissa = mantissa * (10 ** -scale)
scale = 0
# Max scale allowed in rust_decimal is 28
if scale > 28:
raise ValueError(f"Scale {scale} exceeds maximum allowed (28)")
# Split 96-bit mantissa into three 32-bit chunks
lo = mantissa & 0xFFFFFFFF
mid = (mantissa >> 32) & 0xFFFFFFFF
hi = (mantissa >> 64) & 0xFFFFFFFF
# Construct flags: scale is in bits 16-23, sign is bit 31
flags = (scale << 16) & 0x00FF0000
if sign: if sign:
integer = -integer flags |= 0x80000000
return struct.pack("<4I", flags, lo, mid, hi)
return struct.pack("<qb", integer, scale)
@classmethod @classmethod
def from_com(cls, data: bytes, offset: int = 0) -> tuple[typing.Any, int]: def from_com(cls, data: bytes, offset: int = 0) -> tuple[typing.Any, int]:
integer, scale = struct.unpack_from("<qb", data, offset) # Unpack four 32-bit unsigned integers (Little-Endian)
flags, lo, mid, hi = struct.unpack_from("<4I", data, offset)
value = Decimal(integer) / (Decimal(10) ** scale) # Extract scale (Bits 16-23)
scale = (flags >> 16) & 0xFF
# Extract sign (Bit 31)
is_negative = (flags & 0x80000000) != 0
# Reconstruct the 96-bit integer mantissa
mantissa = lo | (mid << 32) | (hi << 64)
# Convert to Python Decimal
value = Decimal(mantissa) / (Decimal(10) ** scale)
if is_negative:
value = -value
return cls(value), offset + cls.size return cls(value), offset + cls.size
+14 -14
View File
@@ -19,20 +19,20 @@ class LogKind(PulseWire):
@pwp_enum @pwp_enum
class CandleInterval(PulseWire): class CandleInterval(PulseWire):
class OneMinute: pass class OneMinute(PulseWire): pass
class ThreeMinutes: pass class ThreeMinutes(PulseWire): pass
class FiveMinutes: pass class FiveMinutes(PulseWire): pass
class FifteenMinutes: pass class FifteenMinutes(PulseWire): pass
class ThirtyMinutes: pass class ThirtyMinutes(PulseWire): pass
class OneHour: pass class OneHour(PulseWire): pass
class TwoHours: pass class TwoHours(PulseWire): pass
class FourHours: pass class FourHours(PulseWire): pass
class EightHours: pass class EightHours(PulseWire): pass
class TwelveHours: pass class TwelveHours(PulseWire): pass
class OneDay: pass class OneDay(PulseWire): pass
class ThreeDays: pass class ThreeDays(PulseWire): pass
class OneWeek: pass class OneWeek(PulseWire): pass
class OneMonth: pass class OneMonth(PulseWire): pass
@pwp @pwp
class Signal(PulseWire): class Signal(PulseWire):
+1 -1
View File
@@ -20,7 +20,7 @@ class StrategyMessage(PulseWire):
class RequestCandlestick(PulseWire): class RequestCandlestick(PulseWire):
symbol: str symbol: str
interval: general.CandleInterval interval: general.CandleIntervalType
count: u32 count: u32
class Subscribe(PulseWire): class Subscribe(PulseWire):