-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathexecutor.py
More file actions
101 lines (80 loc) · 3.34 KB
/
executor.py
File metadata and controls
101 lines (80 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
from __future__ import annotations
import asyncio
import config
import logger
from edge import Signal
from markets import get_token_id
def execute_trade(signal: Signal) -> dict:
"""Execute a trade on Polymarket or log a dry-run. Synchronous."""
daily_spent = abs(logger.get_daily_pnl())
if daily_spent + signal.bet_amount > config.DAILY_LOSS_LIMIT_USD:
return _log_and_return(signal, status="rejected_daily_limit", order_id=None)
if config.DRY_RUN:
return _log_and_return(signal, status="dry_run", order_id=None)
return _execute_live(signal)
async def execute_trade_async(signal: Signal) -> dict:
"""Async wrapper around execute_trade."""
return await asyncio.get_event_loop().run_in_executor(None, execute_trade, signal)
def _execute_live(signal: Signal) -> dict:
"""Place a real order via Polymarket CLOB client."""
try:
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType
client = ClobClient(
host=config.POLYMARKET_HOST,
key=config.POLYMARKET_API_KEY,
chain_id=137,
funder=config.POLYMARKET_PRIVATE_KEY,
)
client.set_api_creds(client.create_or_derive_api_creds())
token_id = get_token_id(signal.market, signal.side)
if not token_id:
return _log_and_return(signal, status="error_no_token", order_id=None)
price = signal.market.yes_price if signal.side == "YES" else signal.market.no_price
order_args = OrderArgs(
price=price,
size=signal.bet_amount,
side="BUY",
token_id=token_id,
)
signed_order = client.create_order(order_args)
resp = client.post_order(signed_order, OrderType.GTC)
order_id = resp.get("orderID", resp.get("id", "unknown"))
return _log_and_return(signal, status="executed", order_id=order_id)
except ImportError:
return _log_and_return(signal, status="error_no_clob_client", order_id=None)
except Exception as e:
return _log_and_return(signal, status=f"error_{type(e).__name__}", order_id=None)
def _log_and_return(signal: Signal, status: str, order_id: str | None) -> dict:
"""Log trade to SQLite and return result dict."""
trade_id = logger.log_trade(
market_id=signal.market.condition_id,
market_question=signal.market.question,
claude_score=signal.claude_score,
market_price=signal.market_price,
edge=signal.edge,
side=signal.side,
amount_usd=signal.bet_amount,
order_id=order_id,
status=status,
reasoning=signal.reasoning,
headlines=signal.headlines,
news_source=signal.news_source,
classification=signal.classification,
materiality=signal.materiality,
news_latency_ms=signal.news_latency_ms,
classification_latency_ms=signal.classification_latency_ms,
total_latency_ms=signal.total_latency_ms,
)
return {
"trade_id": trade_id,
"market": signal.market.question,
"side": signal.side,
"amount": signal.bet_amount,
"edge": signal.edge,
"status": status,
"order_id": order_id,
"classification": signal.classification,
"materiality": signal.materiality,
"latency_ms": signal.total_latency_ms,
}