# Set TP/SL on Open Positions

Use this script to protect every open position with one TP/SL order.

### What this script does

* loads all open positions
* calculates take-profit at `+10%`
* calculates stop-loss at `-10%`
* submits one TP/SL order per position

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="set\_tpsl\_all\_positions.py" %}

```python
#!/usr/bin/env python3
"""Set TP/SL at ±10% of current price on every open position."""
import json, requests
import hmac, hashlib, base64, time

API_KEY = "op_k_your_api_key"
API_SECRET = "your_api_secret"
USDC_ID = "078dcd98-928d-479f-8110-ff6d27e44de2"
TP_OFFSET = 0.10   # +10%
SL_OFFSET = 0.10   # -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 get(self, path, params=None):
        headers = self._sign("GET", path)
        return requests.get(self._host(path) + path, headers=headers, params=params)

    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)


client = OutpollClient(API_KEY, API_SECRET)

# Step 1 — Get all open positions
print("Fetching open positions...")
positions = client.get("/api/history/deals/open-positions", params={"page": 0, "size": 100}).json()

if not positions["i"]:
    print("No open positions.")
    exit()

print(f"Found {len(positions['i'])} position(s)\n")

# Step 2 — For each position, set TP/SL
for pos in positions["i"]:
    current_price = pos["cp"]
    tp_price = min(round(current_price * (1 + TP_OFFSET), 2), 0.99)
    sl_price = max(round(current_price * (1 - SL_OFFSET), 2), 0.01)

    print(f"{pos['et']} — {pos['on']}")
    print(f"  Current: ${current_price:.2f}  |  TP: ${tp_price:.2f}  |  SL: ${sl_price:.2f}")
    print(f"  Shares: {pos['asc']}")

    resp = client.post("/orders/tpsl", {
        "e": pos["ei"],
        "o": pos["eoi"],
        "ba": pos["ai"],
        "qa": USDC_ID,
        "i": "YES" if pos["ip"] else "NO",
        "s": "SELL",
        "q": pos["asc"],
        "t": tp_price,
        "l": sl_price,
    })

    if resp.status_code in (200, 202):
        print(f"  TP/SL set\n")
    else:
        print(f"  Error {resp.status_code}: {resp.text[:100]}\n")

print("Done.")
```

{% endcode %}

### Related pages

* [Get TP/SL Orders](https://docs.outpoll.com/api/rest-api/private-endpoints/orders/get-tp-sl-orders)
* [Set Take Profit / Stop Loss](https://docs.outpoll.com/api/rest-api/private-endpoints/orders/take-profit-stop-loss)
* [Positions](https://docs.outpoll.com/api/rest-api/private-endpoints/positions)
