diff --git a/bot_x.py b/bot_x.py index 9c8316a..4ce2f73 100644 --- a/bot_x.py +++ b/bot_x.py @@ -207,6 +207,25 @@ class MeanReversionStrategy: team_name = "HanyangFloorFunction" +class OrderRateLimiter: + def __init__(self, max_per_second=500): + self.max_per_second = max_per_second + self.timestamps = deque(maxlen=max_per_second + 100) + + def can_send(self): + now = time.time() + self.timestamps.append(now) + recent = [t for t in self.timestamps if now - t < 1.0] + if len(recent) >= self.max_per_second: + return False + return True + + def reset_if_needed(self): + now = time.time() + while self.timestamps and now - self.timestamps[0] >= 1.0: + self.timestamps.popleft() + + def main(): args = parse_arguments() @@ -243,6 +262,7 @@ def main(): state = StateManager() om = OrderManager(exchange) + rate_limiter = OrderRateLimiter(max_per_second=500) market_open = False active_orders = {} @@ -344,6 +364,9 @@ def main(): return if any(cross_ema.last_signal.get(s) is not None for s in symbols_for_ema): return + rate_limiter.reset_if_needed() + if not rate_limiter.can_send(): + return bond_ask = state.ask_prices["BOND"] gs_ask = state.ask_prices["GS"] @@ -418,6 +441,9 @@ def main(): return if any(cross_ema.last_signal.get(s) is not None for s in symbols_for_ema): return + rate_limiter.reset_if_needed() + if not rate_limiter.can_send(): + return vale_bid = state.bid_prices["VALE"] vale_ask = state.ask_prices["VALE"] @@ -482,6 +508,9 @@ def main(): return if any(mean_rev.position.get(s) is not None for s in symbols_for_mr): return + rate_limiter.reset_if_needed() + if not rate_limiter.can_send(): + return for symbol in symbols_for_ema: mid_price = state.get_mid_price(symbol) @@ -527,6 +556,9 @@ def main(): return if xlf_state != "IDLE" or vale_state != "IDLE": return + rate_limiter.reset_if_needed() + if not rate_limiter.can_send(): + return for symbol in symbols_for_mr: mid_price = state.get_mid_price(symbol)