# Buy a Liquid Event

Use this script to buy into a liquid event at a target price.

### What this script does

* finds the most liquid event
* watches the order book in real time
* places a market buy when the YES price reaches `$0.40`
* spends `10%` of available USDC balance

Start with [Setup & Helpers](https://docs.outpoll.com/api/rest-api/python-examples/setup-and-helpers) if you still need the shared prerequisites.

{% code title="buy\_liquid\_event.py" %}

```python
#!/usr/bin/env python3
"""Buy YES token at $0.40 on the most liquid event, spending 10% of USDC 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"
TARGET_PRICE = 0.40
BALANCE_FRACTION = 0.10

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}}


# Step 1 — Find the most liquid event
print("Searching for most liquid event...")
resp = requests.post(
    "https://event-service.outpoll.com/api/events/search",
    params={"page": 0, "size": 1},
    json={"sb": "LIQUIDITY", "sd": "DESC", "l": "en"},
)
event = resp.json()["content"][0]
market = event["ma"][0]
yes_runner = next(r for r in market["r"] if r["ip"])

EVENT_ID = event["i"]
OUTCOME_ID = market["i"]
RUNNER_ID = yes_runner["i"]

print(f"Event:   {event['ti']}")
print(f"YES price: ${yes_runner['p']:.2f}")
print(f"Target:  ${TARGET_PRICE:.2f}")


async def run():
    client = OutpollClient(API_KEY, API_SECRET)

    # Step 2 — Get USDC balance via Balance WebSocket
    print("\nFetching USDC balance...")
    usdc_balance = 0.0
    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))
        if msg.get("t") == "success":
            for b in msg["d"]["l"]:
                if b["i"] == USDC_ID:
                    usdc_balance = b["f"]
                    break
    spend = round(usdc_balance * BALANCE_FRACTION, 2)
    print(f"USDC free: ${usdc_balance:.2f}")
    print(f"Will spend: ${spend:.2f} (10%)")

    if spend < 1:
        print("Insufficient balance. Exiting.")
        return

    # Step 3 — Monitor order book, wait for YES ≤ $0.40
    print(f"\nWatching order book for YES ≤ ${TARGET_PRICE}...")
    async with websockets.connect("wss://order-book.outpoll.com/event/ws") as ws:
        await ws.send(json.dumps({"t": "SUBSCRIBE", "e": EVENT_ID}))

        async for raw in ws:
            data = json.loads(raw)
            if data["t"] not in ("PRICES_DATA", "PRICES_DATA_DELTA"):
                continue

            for p in data["d"]:
                if p["o"] != RUNNER_ID:
                    continue

                chance = p["c"]
                print(f"  YES: ${chance:.4f} (bid={p['b']:.4f}, ask={p['a']:.4f})", end="\r")

                if chance <= TARGET_PRICE:
                    # Step 4 — Market buy
                    print(f"\n\nPrice hit ${chance:.4f} ≤ ${TARGET_PRICE}! Buying...")
                    order = client.post("/orders/market", {
                        "e": EVENT_ID,
                        "o": OUTCOME_ID,
                        "ba": RUNNER_ID,
                        "qa": USDC_ID,
                        "s": "BUY",
                        "am": spend,
                    })
                    print(f"Order placed: {order.json()}")
                    return


asyncio.run(run())
```

{% endcode %}

### Related pages

* [Order Book](https://docs.outpoll.com/api/rest-api/websockets/order-book)
* [Balances](https://docs.outpoll.com/api/rest-api/private-endpoints/balances)
* [Place Market Order](https://docs.outpoll.com/api/rest-api/private-endpoints/orders/place-market-order)
