Jane Street India Ban: Lessons for Algo Traders
Analyze the Jane Street India ban case and learn critical compliance lessons for algorithmic traders in India.
October 2023: SEBI bans Jane Street, one of world’s largest prop firms, from Indian markets for alleged order manipulation. Message clear: Nobody too big to be punished.
This case study dissects what went wrong and how you can avoid similar fate with proper compliance.
The Jane Street Case
What Happened
Jane Street accused of:
- Spoofing: Placing large orders with intent to cancel
- Layering: Creating false market depth
- Price Manipulation: Moving prices artificially
Penalty: 3-year ban + ₹20 crore fine
Key Violations
# ILLEGAL: Spoofing pattern
def spoofing_strategy():
"""
DO NOT USE - This is illegal spoofing
"""
# Place large buy order to signal bullish intent
place_order(symbol='NIFTY', side='buy', qty=1000, price=18000)
# Wait for others to follow
time.sleep(2)
# Cancel original order
cancel_order(order_id)
# Execute opposite side at better price
place_order(symbol='NIFTY', side='sell', qty=100, price=18005)
# LEGAL: Legitimate market making
class LegitimateMarketMaker:
"""
Legal market-making with proper intent
"""
def __init__(self):
self.spread_bps = 5
self.max_position = 100
def quote(self, symbol: str, mid_price: float):
"""Place genuine two-sided quotes"""
spread = mid_price * (self.spread_bps / 10000)
# Place both sides simultaneously with real intent to trade
buy_order = {
'symbol': symbol,
'side': 'buy',
'price': mid_price - spread/2,
'quantity': 10,
'order_type': 'LIMIT'
}
sell_order = {
'symbol': symbol,
'side': 'sell',
'price': mid_price + spread/2,
'quantity': 10,
'order_type': 'LIMIT'
}
# Both orders have genuine intent to execute
return [buy_order, sell_order]
mm = LegitimateMarketMaker()
orders = mm.quote('NIFTY', 18000)
print(f"Legitimate quotes: {orders}")
Compliance Best Practices
Automated Monitoring
class ComplianceMonitor:
"""
Monitor for potentially manipulative patterns
"""
def __init__(self):
self.order_history = []
self.cancel_threshold = 0.90 # 90% cancel rate is suspicious
def track_order(self, order: dict):
"""Track order lifecycle"""
self.order_history.append({
'order_id': order['order_id'],
'timestamp': pd.Timestamp.now(),
'symbol': order['symbol'],
'side': order['side'],
'quantity': order['quantity'],
'price': order['price'],
'status': 'placed'
})
def check_cancel_ratio(self, symbol: str, window_minutes: int = 60) -> dict:
"""Check order cancellation ratio"""
cutoff = pd.Timestamp.now() - pd.Timedelta(minutes=window_minutes)
recent_orders = [o for o in self.order_history
if o['timestamp'] >= cutoff and o['symbol'] == symbol]
if not recent_orders:
return {'warning': False}
total = len(recent_orders)
cancelled = len([o for o in recent_orders if o['status'] == 'cancelled'])
cancel_ratio = cancelled / total if total > 0 else 0
return {
'symbol': symbol,
'total_orders': total,
'cancelled': cancelled,
'cancel_ratio': cancel_ratio,
'warning': cancel_ratio > self.cancel_threshold
}
monitor = ComplianceMonitor()
Takeaways
- Intent Matters: SEBI looks at order intent, not just outcomes
- Cancel Ratios: High cancellation rates trigger scrutiny
- Documentation: Keep audit trail of all algo decisions
- Testing: Pre-deployment testing mandatory
- Kill Switch: Emergency controls required
Your strategy’s legality depends on intent. If orders placed to mislead market participants, it’s manipulation—regardless of profits or losses.