Copy Large Trades
Listen to the public trade feed and copy trades above a chosen value threshold
What this script does
#!/usr/bin/env python3
"""Copy trades > $1000 from the public feed, each trade = 5% of initial balance."""
import asyncio, json, requests, websockets
import hmac, hashlib, base64, time
API_KEY = "op_k_your_api_key"
API_SECRET = "your_api_secret"
USDC_ID = "078dcd98-928d-479f-8110-ff6d27e44de2"
MIN_TRADE_VALUE = 1000 # only copy trades > $1000
TRADE_FRACTION = 0.05 # 5% of balance per trade
SERVICE_MAP = {
"/api/events": "https://event-service.outpoll.com",
"/api/user-balances": "https://wallet-mutator-view.outpoll.com",
"/api/history": "https://history-service.outpoll.com",
"/orders": "https://order-service.outpoll.com",
}
class OutpollClient:
def __init__(self, api_key, api_secret):
self.api_key = api_key
self.api_secret = api_secret
def _host(self, path):
for prefix, host in SERVICE_MAP.items():
if path.startswith(prefix):
return host
return "https://event-service.outpoll.com"
def _sign(self, method, path, body=""):
timestamp = str(int(time.time()))
message = timestamp + method + path + body
padded = self.api_secret + "=" * (4 - len(self.api_secret) % 4) if len(self.api_secret) % 4 else self.api_secret
secret_bytes = base64.urlsafe_b64decode(padded)
signature = base64.urlsafe_b64encode(
hmac.new(secret_bytes, message.encode(), hashlib.sha256).digest()
).decode().rstrip("=")
return {
"OUTPOLL-API-KEY": self.api_key,
"OUTPOLL-API-SIGNATURE": signature,
"OUTPOLL-API-TIMESTAMP": timestamp,
"Content-Type": "application/json",
}
def post(self, path, data=None):
body = json.dumps(data) if data else ""
headers = self._sign("POST", path, body)
return requests.post(self._host(path) + path, headers=headers, data=body)
def ws_auth_msg(path):
timestamp = str(int(time.time()))
message = timestamp + "GET" + path
s = API_SECRET
s += "=" * (4 - len(s) % 4) if len(s) % 4 else ""
secret_bytes = base64.urlsafe_b64decode(s)
signature = base64.urlsafe_b64encode(
hmac.new(secret_bytes, message.encode(), hashlib.sha256).digest()
).decode().rstrip("=")
return {"t": "AUTH", "d": {"apiKey": API_KEY, "signature": signature, "timestamp": timestamp}}
async def run():
client = OutpollClient(API_KEY, API_SECRET)
# Step 1 — Get USDC balance
print("Fetching USDC balance...")
async with websockets.connect("wss://wallet-mutator-view.outpoll.com/balance/ws") as ws:
await ws.send(json.dumps(ws_auth_msg("/balance/ws")))
msg = json.loads(await asyncio.wait_for(ws.recv(), timeout=10))
usdc_balance = 0.0
if msg.get("t") == "success":
for b in msg["d"]["l"]:
if b["i"] == USDC_ID:
usdc_balance = b["f"]
break
spend_per_trade = round(usdc_balance * TRADE_FRACTION, 2)
print(f"USDC free: ${usdc_balance:.2f}")
print(f"Per trade: ${spend_per_trade:.2f} (5%)")
if spend_per_trade < 1:
print("Insufficient balance. Exiting.")
return
# Step 2 — We need runner info per event. Cache event data.
event_cache = {}
def get_event_info(event_id):
if event_id not in event_cache:
resp = requests.post(
"https://event-service.outpoll.com/api/events/search",
params={"page": 0, "size": 50},
json={"sb": "VOLUME_24H", "sd": "DESC", "l": "en"},
)
for ev in resp.json()["content"]:
event_cache[ev["i"]] = ev
return event_cache.get(event_id)
# Step 3 — Watch last trades, copy big ones
print(f"\nWatching last trades (min ${MIN_TRADE_VALUE})...\n")
trade_count = 0
async with websockets.connect("wss://history-service.outpoll.com/last-trades/ws") as ws:
async for raw in ws:
data = json.loads(raw)
# Skip heartbeats
if data.get("t") == "PING":
continue
# Trade value = quantity × price
qty = data.get("q", 0)
price = data.get("p", 0)
value = qty * price
if value < MIN_TRADE_VALUE:
continue
side = data.get("s", "BUY")
event_id = data.get("e", "")
outcome_id = data.get("o", "")
print(f"Whale trade: {side} {qty} @ ${price:.2f} = ${value:.2f}")
# Look up event to find runner IDs
event_info = get_event_info(event_id)
if not event_info:
print(f" Event {event_id[:8]}... not found, skipping\n")
continue
# Find the matching market and runner
runner_id = None
for mkt in event_info.get("ma", []):
for runner in mkt["r"]:
if runner["o"] == outcome_id or mkt["i"] == outcome_id:
if runner["ip"]:
runner_id = runner["i"]
break
if not runner_id:
print(f" Runner not found, skipping\n")
continue
# Copy the trade
order = client.post("/orders/market", {
"e": event_id,
"o": outcome_id,
"ba": runner_id,
"qa": USDC_ID,
"s": side,
"am": spend_per_trade,
})
trade_count += 1
print(f" Copied #{trade_count}: {order.json()}\n")
asyncio.run(run())Related pages
Last updated
Was this helpful?

