diff --git a/src/pulse_sdk_py/__init__.py b/src/pulse_sdk_py/__init__.py index 9a136f7..3be7b31 100644 --- a/src/pulse_sdk_py/__init__.py +++ b/src/pulse_sdk_py/__init__.py @@ -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 diff --git a/src/pulse_sdk_py/adv_types.py b/src/pulse_sdk_py/adv_types.py index b892c89..d2f163b 100644 --- a/src/pulse_sdk_py/adv_types.py +++ b/src/pulse_sdk_py/adv_types.py @@ -76,30 +76,59 @@ class f32(PulseUnit): pass class f64(PulseUnit): pass class decimal(PulseUnit): - size = struct.calcsize(" 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(" tuple[typing.Any, int]: - integer, scale = struct.unpack_from("> 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 \ No newline at end of file diff --git a/src/pulse_sdk_py/general.py b/src/pulse_sdk_py/general.py index 2715226..5d345a3 100644 --- a/src/pulse_sdk_py/general.py +++ b/src/pulse_sdk_py/general.py @@ -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): diff --git a/src/pulse_sdk_py/plugin.py b/src/pulse_sdk_py/plugin.py index a5f2a08..679e975 100644 --- a/src/pulse_sdk_py/plugin.py +++ b/src/pulse_sdk_py/plugin.py @@ -20,7 +20,7 @@ class StrategyMessage(PulseWire): class RequestCandlestick(PulseWire): symbol: str - interval: general.CandleInterval + interval: general.CandleIntervalType count: u32 class Subscribe(PulseWire):