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):
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.symbol = symbol
msg.interval = interval
+37 -8
View File
@@ -76,30 +76,59 @@ class f32(PulseUnit): pass
class f64(PulseUnit): pass
class decimal(PulseUnit):
size = struct.calcsize("<qb")
# Exactly 16 bytes to match Rust's [u8; 16] output
size = 16
def __init__(self, value):
self.value = Decimal(value)
def to_com(self):
def to_com(self) -> bytes:
sign, digits, exponent = self.value.as_tuple()
if not isinstance(exponent, int):
raise ValueError("Cannot serialize NaN or Infinity")
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:
integer = -integer
flags |= 0x80000000
return struct.pack("<qb", integer, scale)
return struct.pack("<4I", flags, lo, mid, hi)
@classmethod
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
+14 -14
View File
@@ -19,20 +19,20 @@ class LogKind(PulseWire):
@pwp_enum
class CandleInterval(PulseWire):
class OneMinute: pass
class ThreeMinutes: pass
class FiveMinutes: pass
class FifteenMinutes: pass
class ThirtyMinutes: pass
class OneHour: pass
class TwoHours: pass
class FourHours: pass
class EightHours: pass
class TwelveHours: pass
class OneDay: pass
class ThreeDays: pass
class OneWeek: pass
class OneMonth: pass
class OneMinute(PulseWire): pass
class ThreeMinutes(PulseWire): pass
class FiveMinutes(PulseWire): pass
class FifteenMinutes(PulseWire): pass
class ThirtyMinutes(PulseWire): pass
class OneHour(PulseWire): pass
class TwoHours(PulseWire): pass
class FourHours(PulseWire): pass
class EightHours(PulseWire): pass
class TwelveHours(PulseWire): pass
class OneDay(PulseWire): pass
class ThreeDays(PulseWire): pass
class OneWeek(PulseWire): pass
class OneMonth(PulseWire): pass
@pwp
class Signal(PulseWire):
+1 -1
View File
@@ -20,7 +20,7 @@ class StrategyMessage(PulseWire):
class RequestCandlestick(PulseWire):
symbol: str
interval: general.CandleInterval
interval: general.CandleIntervalType
count: u32
class Subscribe(PulseWire):