Skip to content

Commit 24ee0ff

Browse files
committed
fix: resolve all ruff lint/format failures (CI unblock)
Made-with: Cursor
1 parent 978b6d3 commit 24ee0ff

9 files changed

Lines changed: 138 additions & 82 deletions

File tree

src/gap_mm/__init__.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
"""
88

99
from gap_mm.engine import (
10-
encode_signal,
11-
calculate_quotes_fast,
10+
CONF_HIGH,
11+
CONF_LOW,
12+
CONF_MED,
13+
SIGNAL_DOWN,
14+
SIGNAL_NEUTRAL,
15+
SIGNAL_UP,
1216
calculate_pnl_fast,
17+
calculate_quotes_fast,
1318
check_signal_correct,
14-
decode_signal,
1519
decode_confidence,
16-
SIGNAL_UP,
17-
SIGNAL_DOWN,
18-
SIGNAL_NEUTRAL,
19-
CONF_HIGH,
20-
CONF_MED,
21-
CONF_LOW,
20+
decode_signal,
21+
encode_signal,
2222
)
2323
from gap_mm.live import LiveTradingEngine
2424

src/gap_mm/engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"""
2222

2323
from numba import jit
24-
import numpy as np
2524

2625
# Signal direction constants (numba nopython mode does not support strings)
2726
SIGNAL_UP = 1
@@ -111,7 +110,7 @@ def calculate_quotes_fast(
111110
automatically centred around a position-aware fair value, rather than the
112111
raw exchange mid.
113112
"""
114-
if confidence == CONF_HIGH or confidence == CONF_MED:
113+
if confidence in (CONF_HIGH, CONF_MED):
115114
if signal == SIGNAL_UP:
116115
bid_edge = 1.0
117116
ask_edge = 100.0
@@ -201,6 +200,7 @@ def calculate_statistics(
201200

202201
# ── Python-layer helpers (not JIT-compiled) ──────────────────────────────────
203202

203+
204204
def decode_signal(signal_code: int) -> tuple[str, str]:
205205
"""Return (text, emoji_text) for a signal code."""
206206
if signal_code == SIGNAL_UP:

src/gap_mm/live.py

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212
import time
1313
from datetime import datetime
1414

15-
from rust_engine import TradingNode, ExecutionNode
16-
1715
from gap_mm.engine import (
1816
calculate_quotes_fast,
19-
encode_signal,
20-
decode_signal,
2117
decode_confidence,
18+
decode_signal,
19+
encode_signal,
2220
)
21+
from rust_engine import ExecutionNode, TradingNode
2322

2423

2524
class LiveTradingEngine:
@@ -70,9 +69,9 @@ def on_fill(self, fill: dict) -> None:
7069
"""Callback invoked by the private WebSocket on each execution report."""
7170
self.total_fills += 1
7271

73-
print(f"\n{'='*80}")
72+
print(f"\n{'=' * 80}")
7473
print(f" FILL #{self.total_fills}")
75-
print(f" {'='*80}")
74+
print(f" {'=' * 80}")
7675
print(f" Symbol: {fill['symbol']}")
7776
print(f" Side: {fill['side']}")
7877
print(f" Fill: {fill['fill_price']:.2f} x {fill['fill_qty']:.6f}")
@@ -89,18 +88,22 @@ def on_fill(self, fill: dict) -> None:
8988
print(f" Avg entry: {pos['avg_entry_price']:.2f}")
9089
print(f" Realized P&L: {pos['realized_pnl']:+.2f} USDT")
9190

92-
print(f" {'='*80}\n")
91+
print(f" {'=' * 80}\n")
9392

9493
def _should_update(self, new_bid: float, new_ask: float, now: float) -> bool:
9594
"""Return True only when target prices changed (and optional throttle cleared)."""
9695
if self.last_bid_price is None or self.last_ask_price is None:
9796
return True
9897
half_tick = self.tick_size / 2.0
99-
if abs(new_bid - self.last_bid_price) <= half_tick and abs(new_ask - self.last_ask_price) <= half_tick:
98+
if (
99+
abs(new_bid - self.last_bid_price) <= half_tick
100+
and abs(new_ask - self.last_ask_price) <= half_tick
101+
):
100102
return False
101-
if self.min_update_interval > 0 and (now - self.last_execution_time) < self.min_update_interval:
102-
return False
103-
return True
103+
return not (
104+
self.min_update_interval > 0
105+
and now - self.last_execution_time < self.min_update_interval
106+
)
104107

105108
def on_market_update(self, data: dict) -> None:
106109
"""Main hot-path callback: receives market data, calculates and reconciles quotes."""
@@ -161,33 +164,46 @@ def on_market_update(self, data: dict) -> None:
161164

162165
except Exception as exc:
163166
import traceback
167+
164168
print(f"ERROR in market update callback: {exc}")
165169
traceback.print_exc()
166170

167171
def _print_action(self, side: str, action: dict) -> None:
168172
t = action.get("type")
169173
if t == "submitted":
170-
print(f" + {side} SUBMITTED @ {action['price']:.2f} | ID: {action['order_id'][:8]}... | {action.get('latency_ms', 0)}ms")
174+
print(
175+
f" + {side} SUBMITTED @ {action['price']:.2f} | ID: {action['order_id'][:8]}... | {action.get('latency_ms', 0)}ms"
176+
)
171177
elif t == "amended":
172-
print(f" ~ {side} AMENDED: {action['old_price']:.2f} -> {action['new_price']:.2f} | ID: {action['order_id'][:8]}... | {action.get('latency_ms', 0)}ms")
178+
print(
179+
f" ~ {side} AMENDED: {action['old_price']:.2f} -> {action['new_price']:.2f} | ID: {action['order_id'][:8]}... | {action.get('latency_ms', 0)}ms"
180+
)
173181
elif t == "no_change":
174-
print(f" = {side} UNCHANGED @ {action['price']:.2f} | ID: {action['order_id'][:8]}...")
182+
print(
183+
f" = {side} UNCHANGED @ {action['price']:.2f} | ID: {action['order_id'][:8]}..."
184+
)
175185
elif t == "skipped":
176186
print(f" - {side} SKIPPED: {action['reason']}")
177187

178188
def _print_stats(self) -> None:
179189
elapsed = time.time() - self.start_time
180-
elapsed_min = max(elapsed / 60.0, 1e-9)
181-
print(f"\n{'='*80}")
182-
print(f" STATS runtime={elapsed:.1f}s updates={self.total_updates} executions={self.total_executions} fills={self.total_fills}")
190+
max(elapsed / 60.0, 1e-9)
191+
print(f"\n{'=' * 80}")
192+
print(
193+
f" STATS runtime={elapsed:.1f}s updates={self.total_updates} executions={self.total_executions} fills={self.total_fills}"
194+
)
183195
print(f" Last signal: {self.last_signal} ({self.last_confidence})")
184196
if self.last_bid_price and self.last_ask_price:
185-
print(f" Current quotes: BID {self.last_bid_price:.2f} | ASK {self.last_ask_price:.2f}")
197+
print(
198+
f" Current quotes: BID {self.last_bid_price:.2f} | ASK {self.last_ask_price:.2f}"
199+
)
186200
if self.current_position:
187201
net = self.current_position["net_qty"]
188202
direction = "LONG" if net > 0 else "SHORT" if net < 0 else "FLAT"
189-
print(f" Position: {net:+.6f} ({direction}) P&L: {self.current_position['realized_pnl']:+.2f} USDT")
190-
print(f"{'='*80}\n")
203+
print(
204+
f" Position: {net:+.6f} ({direction}) P&L: {self.current_position['realized_pnl']:+.2f} USDT"
205+
)
206+
print(f"{'=' * 80}\n")
191207

192208
def start(self) -> None:
193209
"""Start the live trading engine (blocks until interrupted)."""

tests/benchmarks/bench_latency.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
"""
2323

2424
import json
25-
import socket
2625
import statistics
2726
import sys
2827
import threading
@@ -38,24 +37,30 @@
3837
try:
3938
from rust_engine import ExecutionNode
4039
except ImportError:
41-
sys.exit("ERROR: rust_engine not built. Run `poetry run maturin develop --manifest-path rust_engine/Cargo.toml`")
40+
sys.exit(
41+
"ERROR: rust_engine not built. Run `poetry run maturin develop --manifest-path rust_engine/Cargo.toml`"
42+
)
4243

4344
# ── constants ─────────────────────────────────────────────────────────────────
44-
MID = 90_000.0
45+
MID = 90_000.0
4546
TICK = 0.10
4647

47-
N_WARMUP = 500
48+
N_WARMUP = 500
4849
N_BENCH_NUMBA = 5_000
49-
N_BENCH_HTTP = 500 # each call → up to 2 HTTP round-trips
50+
N_BENCH_HTTP = 500 # each call → up to 2 HTTP round-trips
5051

51-
SUBMIT_BODY = json.dumps({
52-
"retCode": 0, "retMsg": "OK",
53-
"result": {"orderId": "BENCH-001", "orderLinkId": "link-001"},
54-
}).encode()
52+
SUBMIT_BODY = json.dumps(
53+
{
54+
"retCode": 0,
55+
"retMsg": "OK",
56+
"result": {"orderId": "BENCH-001", "orderLinkId": "link-001"},
57+
}
58+
).encode()
5559

5660

5761
# ── mock HTTP server ──────────────────────────────────────────────────────────
5862

63+
5964
class _Handler(BaseHTTPRequestHandler):
6065
def do_POST(self):
6166
# drain body
@@ -83,16 +88,17 @@ def _start_mock_server() -> tuple[ThreadingHTTPServer, str]:
8388

8489
# ── stats / reporting ─────────────────────────────────────────────────────────
8590

91+
8692
def _stats(samples_ns: list[int]) -> dict:
8793
s = sorted(samples_ns)
8894
n = len(s)
8995
return {
90-
"n": n,
91-
"min": s[0],
92-
"p50": s[n // 2],
93-
"p95": s[int(n * 0.95)],
94-
"p99": s[int(n * 0.99)],
95-
"max": s[-1],
96+
"n": n,
97+
"min": s[0],
98+
"p50": s[n // 2],
99+
"p95": s[int(n * 0.95)],
100+
"p99": s[int(n * 0.99)],
101+
"max": s[-1],
96102
"mean": int(statistics.mean(s)),
97103
}
98104

@@ -119,6 +125,7 @@ def fmt(ns: int) -> str:
119125

120126
# ── warmup ────────────────────────────────────────────────────────────────────
121127

128+
122129
def _warmup():
123130
print(f"Warming up Numba ({N_WARMUP} iters)...", end=" ", flush=True)
124131
for _ in range(N_WARMUP):
@@ -129,6 +136,7 @@ def _warmup():
129136

130137
# ── segment 1 ─────────────────────────────────────────────────────────────────
131138

139+
132140
def bench_segment1():
133141
samples = []
134142
for i in range(N_BENCH_NUMBA):
@@ -142,6 +150,7 @@ def bench_segment1():
142150

143151
# ── segment 2 ─────────────────────────────────────────────────────────────────
144152

153+
145154
def bench_segment2():
146155
last_bid: float | None = None
147156
last_ask: float | None = None
@@ -174,6 +183,7 @@ def _should_update(b: float, a: float) -> bool:
174183

175184
# ── segment 3 ─────────────────────────────────────────────────────────────────
176185

186+
177187
def bench_segment3(base_url: str):
178188
node = ExecutionNode(
179189
api_key="bench-key",
@@ -204,6 +214,7 @@ def bench_segment3(base_url: str):
204214

205215
# ── full pipeline ─────────────────────────────────────────────────────────────
206216

217+
207218
def bench_full_pipeline(base_url: str):
208219
node = ExecutionNode(
209220
api_key="bench-key",
@@ -219,7 +230,7 @@ def bench_full_pipeline(base_url: str):
219230

220231
samples = []
221232
for i in range(N_BENCH_HTTP):
222-
mid = MID + (i % 100) * TICK
233+
mid = MID + (i % 100) * TICK
223234
score = 0.82 if i % 2 == 0 else 0.18
224235
t0 = time.perf_counter_ns()
225236
sig, conf = encode_signal(score)
@@ -241,7 +252,7 @@ def bench_full_pipeline(base_url: str):
241252
bench_segment1()
242253
bench_segment2()
243254

244-
print(f"\nStarting localhost mock HTTP server...", end=" ", flush=True)
255+
print("\nStarting localhost mock HTTP server...", end=" ", flush=True)
245256
server, base_url = _start_mock_server()
246257
print(f"listening on {base_url}")
247258

tests/integration/test_gap_signal_pipeline.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010
"""
1111

1212
import pytest
13+
1314
from gap_mm.engine import (
14-
encode_signal,
15-
calculate_quotes_fast,
16-
SIGNAL_UP,
17-
SIGNAL_DOWN,
18-
SIGNAL_NEUTRAL,
1915
CONF_HIGH,
20-
CONF_MED,
2116
CONF_LOW,
17+
CONF_MED,
18+
SIGNAL_DOWN,
19+
SIGNAL_NEUTRAL,
20+
SIGNAL_UP,
21+
calculate_quotes_fast,
22+
encode_signal,
2223
)
2324

2425
TICK = 0.10

0 commit comments

Comments
 (0)