potd-trader 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- potd_trader-0.3.1/PKG-INFO +222 -0
- potd_trader-0.3.1/README.md +202 -0
- potd_trader-0.3.1/pyproject.toml +45 -0
- potd_trader-0.3.1/src/potd_trader/__init__.py +3 -0
- potd_trader-0.3.1/src/potd_trader/cli.py +498 -0
- potd_trader-0.3.1/src/potd_trader/config.py +136 -0
- potd_trader-0.3.1/src/potd_trader/control.py +51 -0
- potd_trader-0.3.1/src/potd_trader/ledger.py +162 -0
- potd_trader-0.3.1/src/potd_trader/oxinsider.py +255 -0
- potd_trader-0.3.1/src/potd_trader/polymarket.py +170 -0
- potd_trader-0.3.1/src/potd_trader/storage.py +44 -0
- potd_trader-0.3.1/src/potd_trader/trader.py +278 -0
- potd_trader-0.3.1/src/potd_trader/wizard.py +158 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: potd-trader
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Buy the 0xinsider Pick of the Day on your own Polymarket account. Your keys stay on your machine.
|
|
5
|
+
Keywords: polymarket,0xinsider,pick-of-the-day,sports,prediction-markets
|
|
6
|
+
Author: 0xinsider
|
|
7
|
+
Author-email: 0xinsider <support@0xinsider.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Requires-Dist: polymarket-client==0.10.0
|
|
10
|
+
Requires-Dist: httpx>=0.27,<1
|
|
11
|
+
Requires-Dist: pydantic>=2,<3
|
|
12
|
+
Requires-Dist: pydantic-settings>=2,<3
|
|
13
|
+
Requires-Dist: python-dotenv>=1.2,<2
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Project-URL: API reference, https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day
|
|
16
|
+
Project-URL: Guide, https://docs.0xinsider.com/guides/auto-buy-the-pick
|
|
17
|
+
Project-URL: Homepage, https://0xinsider.com/pick-of-the-day
|
|
18
|
+
Project-URL: Repository, https://github.com/0xinsider/potd-trader
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# potd-trader
|
|
22
|
+
|
|
23
|
+
Buy the [0xinsider Pick of the Day](https://0xinsider.com/pick-of-the-day) on your own
|
|
24
|
+
Polymarket account, with a small stake and explicit spending limits. Dry-run is the default.
|
|
25
|
+
Your wallet key signs locally through the official Polymarket SDK.
|
|
26
|
+
|
|
27
|
+
[Setup guide](https://docs.0xinsider.com/guides/auto-buy-the-pick) ·
|
|
28
|
+
[API contract](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) ·
|
|
29
|
+
[Release notes](CHANGELOG.md)
|
|
30
|
+
|
|
31
|
+
## Install a version with locked dependencies
|
|
32
|
+
|
|
33
|
+
Python 3.12+ and [uv](https://docs.astral.sh/uv/) are required. Supported systems: macOS and
|
|
34
|
+
Linux, including WSL. The process locks require a local filesystem, not NFS or a synced folder.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone --branch v0.3.0 --depth 1 https://github.com/0xinsider/potd-trader potd-trader-src
|
|
38
|
+
cd potd-trader-src
|
|
39
|
+
uv sync --locked
|
|
40
|
+
uv run --locked potd-trader init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The [v0.3.0 release](https://github.com/0xinsider/potd-trader/releases/tag/v0.3.0) identifies the
|
|
44
|
+
merged commit and includes SHA-256 checksums for its package artifacts. For an immutable source
|
|
45
|
+
pin, check out that full commit instead of a moving branch. `uv sync --locked` installs the
|
|
46
|
+
versions and artifact hashes in the checked-in `uv.lock` and refuses a stale lockfile. Installing
|
|
47
|
+
an unversioned Git URL or a package without its lockfile does not reproduce that environment.
|
|
48
|
+
|
|
49
|
+
`init` creates a new `potd-trader/` folder inside the checkout. It asks four questions, hides both
|
|
50
|
+
keys as you type, writes `.env` at mode 600 in a mode 700 folder, and runs account checks and a
|
|
51
|
+
forced dry run. An inherited `LIVE=yes` cannot make this setup run buy. Only the final confirmation
|
|
52
|
+
can enable subsequent live commands. An existing folder is never overwritten.
|
|
53
|
+
|
|
54
|
+
From that new folder, `uv` finds the project in its parent directory:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cd potd-trader
|
|
58
|
+
uv run --locked potd-trader run --dry-run
|
|
59
|
+
uv run --locked potd-trader live on # type "spend real money" yourself
|
|
60
|
+
uv run --locked potd-trader watch
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What leaves your machine
|
|
64
|
+
|
|
65
|
+
| Goes to | What | Why |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| `api.0xinsider.com` | your 0xinsider API key | read today's Pro picks |
|
|
68
|
+
| `clob.polymarket.com` | signed authentication messages, derived API credentials, signed orders, and token IDs | authenticate, check balance, quote, and buy |
|
|
69
|
+
| `gamma-api.polymarket.com` | token IDs | read market identity, kickoff, tick size, and status |
|
|
70
|
+
| `polymarket.com/api/geoblock` | your IP, as with any request | check trading eligibility for your location |
|
|
71
|
+
| `polygon.drpc.org` | public wallet, token, and contract addresses in RPC calls | SDK wallet and approval checks |
|
|
72
|
+
| `relayer-v2.polymarket.com` | wallet addresses; relayer credentials and signed approval requests when setup is requested | SDK wallet and relayer operations |
|
|
73
|
+
|
|
74
|
+
These are runtime destinations, not package-installation hosts. The reviewed SDK is pinned to
|
|
75
|
+
`polymarket-client==0.10.0`. The private key remains inside the signing process; there is no
|
|
76
|
+
0xinsider endpoint accepting it. `OXINSIDER_API_BASE` only accepts `https://api.0xinsider.com`;
|
|
77
|
+
redirects are refused. The optional builder code stays optional. No withdrawal command exists.
|
|
78
|
+
|
|
79
|
+
Keeping the key local does not make a recommendation feed infallible. A compromised feed could
|
|
80
|
+
recommend unwanted purchases within your limits. Use a dedicated wallet and a small budget.
|
|
81
|
+
|
|
82
|
+
## Set up by hand or with an agent
|
|
83
|
+
|
|
84
|
+
Inside the versioned checkout:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cp .env.example .env
|
|
88
|
+
chmod 600 .env
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Fill in these values locally; never paste keys into a chat:
|
|
92
|
+
|
|
93
|
+
- `OXINSIDER_API_KEY`: a live Pro key from [0xinsider.com/developers](https://0xinsider.com/developers).
|
|
94
|
+
- `POLYMARKET_PRIVATE_KEY`: the signer key. Email/Google login: Polymarket Settings, Export
|
|
95
|
+
private key ([official help](https://help.polymarket.com/en/articles/13364258-how-do-i-export-my-key)).
|
|
96
|
+
Wallet login: export from that wallet app.
|
|
97
|
+
- `POLYMARKET_WALLET_ADDRESS`: the account address in your Polymarket profile menu, which holds
|
|
98
|
+
the pUSD. This can differ from the signer address.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run --locked potd-trader status
|
|
102
|
+
uv run --locked potd-trader run --dry-run
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
An agent must read [AGENTS.md](AGENTS.md), keep secrets out of output, run only these read/dry-run
|
|
106
|
+
checks, and leave enabling live orders to you. `status` reports region, account, approvals,
|
|
107
|
+
balance, reserved UTC budget, and unresolved orders. Missing approvals require `setup` with a
|
|
108
|
+
Relayer API key configured in `.env`; that command submits approval transactions, not orders.
|
|
109
|
+
|
|
110
|
+
## Stop and resume
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
uv run --locked potd-trader live off
|
|
114
|
+
uv run --locked potd-trader live status
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`live off` writes a persistent `HALT` file beside the active `.env`, then waits for any submission
|
|
118
|
+
already in progress before acknowledging the stop. Running watchers using that folder cannot
|
|
119
|
+
start another submission after that acknowledgment. An order already sent may fill; this is not
|
|
120
|
+
an order-cancellation command. If a network call is stuck, the acknowledgment can wait for it.
|
|
121
|
+
Creating `HALT` yourself signals the stop before the next post too.
|
|
122
|
+
|
|
123
|
+
`live on` requires your confirmation, writes `LIVE=yes`, and clears `HALT`. A watcher that started
|
|
124
|
+
with live control enabled can resume on its next cycle. One started in dry-run stays dry until
|
|
125
|
+
restarted. `run --dry-run` and `watch --dry-run` always prohibit orders. Live mode requires both
|
|
126
|
+
process settings and the active file to say exactly `yes`, with no `HALT`; an inherited variable
|
|
127
|
+
cannot override a file saying `no`, and a missing control file fails closed. Restart after changing
|
|
128
|
+
other settings. A local `.env` is used alone; the home file is a fallback, not merged into it.
|
|
129
|
+
|
|
130
|
+
## What happens before an order
|
|
131
|
+
|
|
132
|
+
1. Validate current New York product dates and unique pick slots/tokens. Refuse a duplicate or
|
|
133
|
+
inconsistent slate. Skip settled, unreleased, started, out-of-rank, or incomplete picks.
|
|
134
|
+
2. Require a positive published price and a current entry authorization for the selected token.
|
|
135
|
+
3. Check the independent Polymarket market identity and backed outcome, an explicitly open
|
|
136
|
+
market, known kickoff, tick size, and minimum order size. Keep the kickoff buffer.
|
|
137
|
+
4. Quote the book for your stake. Enforce `MAX_PRICE`, `MAX_SLIPPAGE_PCT`, and the authorization's
|
|
138
|
+
`max_entry_price` together. The authorization is a drift limit, not a promise of profit.
|
|
139
|
+
5. Recheck the market and book before signing. After signing, recheck live control and the
|
|
140
|
+
quote deadline (30 seconds at most, shorter near kickoff/authorization expiry).
|
|
141
|
+
6. Under an exclusive file lock, reload the ledger, reject a repeated pick/slot/token, and reserve
|
|
142
|
+
the stake against the local UTC submission day. Persist and sync the reservation before posting.
|
|
143
|
+
7. Post one Fill-and-Kill BUY through the SDK's separate `post_order`. Record its result without
|
|
144
|
+
automatic approval transactions or an application retry of an ambiguous submission.
|
|
145
|
+
|
|
146
|
+
Live preflight also checks geoblocking, wallet approvals, and the available balance. FAK orders
|
|
147
|
+
can fill partially; their full requested principal remains reserved for that UTC day. Exchange
|
|
148
|
+
fees are additional: `STAKE_USD` and `DAILY_CAP_USD` bound order principal, not fee-inclusive debits.
|
|
149
|
+
|
|
150
|
+
`watch` honors `Retry-After`, release times, and `proof_pending_picks[].retry_at`. Read transport
|
|
151
|
+
failures receive bounded backoff with a visible warning; an ambiguous order does not get retried.
|
|
152
|
+
|
|
153
|
+
## Ledger and recovery
|
|
154
|
+
|
|
155
|
+
`ledger.json` beside `.env` records local submission timestamps, pick identities, reserved stakes,
|
|
156
|
+
and exchange answers. The adjacent `.lock` file coordinates concurrent processes. All instances
|
|
157
|
+
for one wallet must share this ledger and configuration folder on the same local filesystem;
|
|
158
|
+
separate copies or machines do not coordinate. Never delete the ledger or lock files while running.
|
|
159
|
+
|
|
160
|
+
A `submitting`, `accepted`, or `unknown` entry blocks the pick, the same date/rank slot even if its
|
|
161
|
+
token changes, and the token even if the feed relabels its date. Known rejections release their
|
|
162
|
+
reservation. `submitting` and `unknown` entries continue consuming budget across midnight until
|
|
163
|
+
reconciled. Corrupt state fails closed. Existing v1 ledgers remain readable without a migration.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
uv run --locked potd-trader ledger
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
For an unresolved order: stop all instances, inspect Polymarket Activity and the order/fill state,
|
|
170
|
+
and preserve a backup. Only after proving no order can still execute should you remove its local
|
|
171
|
+
entry. If the order exists, preserve its identity and record the confirmed result instead. Never
|
|
172
|
+
clear an entry just to make the bot try again. There is no automatic unknown-order reconciliation.
|
|
173
|
+
|
|
174
|
+
## Upgrade from 0.2.0
|
|
175
|
+
|
|
176
|
+
Stop every old `watch` process first: the old `live off` command cannot stop an already-running
|
|
177
|
+
old binary. Back up your private configuration folder and ledger, install the new release in a
|
|
178
|
+
separate checkout, and use the same ledger path. Run `--dry-run` before restarting live.
|
|
179
|
+
|
|
180
|
+
Behavior changes: `DAILY_CAP_USD=0` is rejected; set a positive cap. Dates are checked against New
|
|
181
|
+
York, but spending is capped by locally recorded UTC submissions. Missing safety data now skips
|
|
182
|
+
trading. Alternate API origins are refused. Environment-only live deployments must mount an
|
|
183
|
+
active `.env` control file containing `LIVE=yes`; keys may still come from the environment.
|
|
184
|
+
|
|
185
|
+
## Settings
|
|
186
|
+
|
|
187
|
+
| Variable | Default | Meaning |
|
|
188
|
+
| --- | --- | --- |
|
|
189
|
+
| `LIVE` | `no` | exact `yes` in process settings and active `.env`, with no `HALT` |
|
|
190
|
+
| `STAKE_USD` | `5` | order principal per pick; `0` means no buys |
|
|
191
|
+
| `MAX_PRICE` | `0.925` | maximum purchase probability |
|
|
192
|
+
| `MAX_SLIPPAGE_PCT` | `3` | maximum increase over the published backed price |
|
|
193
|
+
| `DAILY_CAP_USD` | `25` | positive ceiling on UTC order principal plus unresolved prior intents |
|
|
194
|
+
| `KICKOFF_BUFFER_MINUTES` | `5` | stop buying this far before kickoff or authorization expiry |
|
|
195
|
+
| `MIN_RANKS` / `MAX_RANKS` | `1` / `6` | inclusive ranked slots; a day carries up to 10 picks, so `MAX_RANKS=10` buys every one |
|
|
196
|
+
| `LEDGER_PATH` | `ledger.json` beside `.env` | shared durable order state |
|
|
197
|
+
| `POTD_TRADER_HOME` | `~/.potd-trader` | fallback configuration folder |
|
|
198
|
+
| `WATCH_IDLE_MINUTES` | `30` | idle recheck cadence |
|
|
199
|
+
|
|
200
|
+
## Docker
|
|
201
|
+
|
|
202
|
+
Build from the release checkout. Mount the configuration folder so `live off` on the host and
|
|
203
|
+
container see the same control file and ledger. Never bake secrets into the image.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
docker build -t potd-trader:0.3.0 .
|
|
207
|
+
docker run --rm -v "$PWD/potd-trader:/app/data" potd-trader:0.3.0
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Verification and limits
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
./scripts/pre-merge-check.sh
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The gate runs lint, formatting, strict source typing, fake-exchange safety tests, and CLI checks.
|
|
217
|
+
The tests exercise competing processes, crash recovery, duplicate picks, UTC budgets, stop timing,
|
|
218
|
+
malformed feeds, and credential routing without wallet keys or real submissions. A public SDK/book
|
|
219
|
+
read checks provider compatibility separately. Neither proves future feed integrity or profit.
|
|
220
|
+
|
|
221
|
+
Orders spend real money and cannot be undone. Polymarket regional restrictions apply. This tool
|
|
222
|
+
is MIT licensed, with no warranty; 0xinsider does not operate or custody your wallet.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# potd-trader
|
|
2
|
+
|
|
3
|
+
Buy the [0xinsider Pick of the Day](https://0xinsider.com/pick-of-the-day) on your own
|
|
4
|
+
Polymarket account, with a small stake and explicit spending limits. Dry-run is the default.
|
|
5
|
+
Your wallet key signs locally through the official Polymarket SDK.
|
|
6
|
+
|
|
7
|
+
[Setup guide](https://docs.0xinsider.com/guides/auto-buy-the-pick) ·
|
|
8
|
+
[API contract](https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day) ·
|
|
9
|
+
[Release notes](CHANGELOG.md)
|
|
10
|
+
|
|
11
|
+
## Install a version with locked dependencies
|
|
12
|
+
|
|
13
|
+
Python 3.12+ and [uv](https://docs.astral.sh/uv/) are required. Supported systems: macOS and
|
|
14
|
+
Linux, including WSL. The process locks require a local filesystem, not NFS or a synced folder.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git clone --branch v0.3.0 --depth 1 https://github.com/0xinsider/potd-trader potd-trader-src
|
|
18
|
+
cd potd-trader-src
|
|
19
|
+
uv sync --locked
|
|
20
|
+
uv run --locked potd-trader init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The [v0.3.0 release](https://github.com/0xinsider/potd-trader/releases/tag/v0.3.0) identifies the
|
|
24
|
+
merged commit and includes SHA-256 checksums for its package artifacts. For an immutable source
|
|
25
|
+
pin, check out that full commit instead of a moving branch. `uv sync --locked` installs the
|
|
26
|
+
versions and artifact hashes in the checked-in `uv.lock` and refuses a stale lockfile. Installing
|
|
27
|
+
an unversioned Git URL or a package without its lockfile does not reproduce that environment.
|
|
28
|
+
|
|
29
|
+
`init` creates a new `potd-trader/` folder inside the checkout. It asks four questions, hides both
|
|
30
|
+
keys as you type, writes `.env` at mode 600 in a mode 700 folder, and runs account checks and a
|
|
31
|
+
forced dry run. An inherited `LIVE=yes` cannot make this setup run buy. Only the final confirmation
|
|
32
|
+
can enable subsequent live commands. An existing folder is never overwritten.
|
|
33
|
+
|
|
34
|
+
From that new folder, `uv` finds the project in its parent directory:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd potd-trader
|
|
38
|
+
uv run --locked potd-trader run --dry-run
|
|
39
|
+
uv run --locked potd-trader live on # type "spend real money" yourself
|
|
40
|
+
uv run --locked potd-trader watch
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What leaves your machine
|
|
44
|
+
|
|
45
|
+
| Goes to | What | Why |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `api.0xinsider.com` | your 0xinsider API key | read today's Pro picks |
|
|
48
|
+
| `clob.polymarket.com` | signed authentication messages, derived API credentials, signed orders, and token IDs | authenticate, check balance, quote, and buy |
|
|
49
|
+
| `gamma-api.polymarket.com` | token IDs | read market identity, kickoff, tick size, and status |
|
|
50
|
+
| `polymarket.com/api/geoblock` | your IP, as with any request | check trading eligibility for your location |
|
|
51
|
+
| `polygon.drpc.org` | public wallet, token, and contract addresses in RPC calls | SDK wallet and approval checks |
|
|
52
|
+
| `relayer-v2.polymarket.com` | wallet addresses; relayer credentials and signed approval requests when setup is requested | SDK wallet and relayer operations |
|
|
53
|
+
|
|
54
|
+
These are runtime destinations, not package-installation hosts. The reviewed SDK is pinned to
|
|
55
|
+
`polymarket-client==0.10.0`. The private key remains inside the signing process; there is no
|
|
56
|
+
0xinsider endpoint accepting it. `OXINSIDER_API_BASE` only accepts `https://api.0xinsider.com`;
|
|
57
|
+
redirects are refused. The optional builder code stays optional. No withdrawal command exists.
|
|
58
|
+
|
|
59
|
+
Keeping the key local does not make a recommendation feed infallible. A compromised feed could
|
|
60
|
+
recommend unwanted purchases within your limits. Use a dedicated wallet and a small budget.
|
|
61
|
+
|
|
62
|
+
## Set up by hand or with an agent
|
|
63
|
+
|
|
64
|
+
Inside the versioned checkout:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cp .env.example .env
|
|
68
|
+
chmod 600 .env
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Fill in these values locally; never paste keys into a chat:
|
|
72
|
+
|
|
73
|
+
- `OXINSIDER_API_KEY`: a live Pro key from [0xinsider.com/developers](https://0xinsider.com/developers).
|
|
74
|
+
- `POLYMARKET_PRIVATE_KEY`: the signer key. Email/Google login: Polymarket Settings, Export
|
|
75
|
+
private key ([official help](https://help.polymarket.com/en/articles/13364258-how-do-i-export-my-key)).
|
|
76
|
+
Wallet login: export from that wallet app.
|
|
77
|
+
- `POLYMARKET_WALLET_ADDRESS`: the account address in your Polymarket profile menu, which holds
|
|
78
|
+
the pUSD. This can differ from the signer address.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
uv run --locked potd-trader status
|
|
82
|
+
uv run --locked potd-trader run --dry-run
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
An agent must read [AGENTS.md](AGENTS.md), keep secrets out of output, run only these read/dry-run
|
|
86
|
+
checks, and leave enabling live orders to you. `status` reports region, account, approvals,
|
|
87
|
+
balance, reserved UTC budget, and unresolved orders. Missing approvals require `setup` with a
|
|
88
|
+
Relayer API key configured in `.env`; that command submits approval transactions, not orders.
|
|
89
|
+
|
|
90
|
+
## Stop and resume
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run --locked potd-trader live off
|
|
94
|
+
uv run --locked potd-trader live status
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`live off` writes a persistent `HALT` file beside the active `.env`, then waits for any submission
|
|
98
|
+
already in progress before acknowledging the stop. Running watchers using that folder cannot
|
|
99
|
+
start another submission after that acknowledgment. An order already sent may fill; this is not
|
|
100
|
+
an order-cancellation command. If a network call is stuck, the acknowledgment can wait for it.
|
|
101
|
+
Creating `HALT` yourself signals the stop before the next post too.
|
|
102
|
+
|
|
103
|
+
`live on` requires your confirmation, writes `LIVE=yes`, and clears `HALT`. A watcher that started
|
|
104
|
+
with live control enabled can resume on its next cycle. One started in dry-run stays dry until
|
|
105
|
+
restarted. `run --dry-run` and `watch --dry-run` always prohibit orders. Live mode requires both
|
|
106
|
+
process settings and the active file to say exactly `yes`, with no `HALT`; an inherited variable
|
|
107
|
+
cannot override a file saying `no`, and a missing control file fails closed. Restart after changing
|
|
108
|
+
other settings. A local `.env` is used alone; the home file is a fallback, not merged into it.
|
|
109
|
+
|
|
110
|
+
## What happens before an order
|
|
111
|
+
|
|
112
|
+
1. Validate current New York product dates and unique pick slots/tokens. Refuse a duplicate or
|
|
113
|
+
inconsistent slate. Skip settled, unreleased, started, out-of-rank, or incomplete picks.
|
|
114
|
+
2. Require a positive published price and a current entry authorization for the selected token.
|
|
115
|
+
3. Check the independent Polymarket market identity and backed outcome, an explicitly open
|
|
116
|
+
market, known kickoff, tick size, and minimum order size. Keep the kickoff buffer.
|
|
117
|
+
4. Quote the book for your stake. Enforce `MAX_PRICE`, `MAX_SLIPPAGE_PCT`, and the authorization's
|
|
118
|
+
`max_entry_price` together. The authorization is a drift limit, not a promise of profit.
|
|
119
|
+
5. Recheck the market and book before signing. After signing, recheck live control and the
|
|
120
|
+
quote deadline (30 seconds at most, shorter near kickoff/authorization expiry).
|
|
121
|
+
6. Under an exclusive file lock, reload the ledger, reject a repeated pick/slot/token, and reserve
|
|
122
|
+
the stake against the local UTC submission day. Persist and sync the reservation before posting.
|
|
123
|
+
7. Post one Fill-and-Kill BUY through the SDK's separate `post_order`. Record its result without
|
|
124
|
+
automatic approval transactions or an application retry of an ambiguous submission.
|
|
125
|
+
|
|
126
|
+
Live preflight also checks geoblocking, wallet approvals, and the available balance. FAK orders
|
|
127
|
+
can fill partially; their full requested principal remains reserved for that UTC day. Exchange
|
|
128
|
+
fees are additional: `STAKE_USD` and `DAILY_CAP_USD` bound order principal, not fee-inclusive debits.
|
|
129
|
+
|
|
130
|
+
`watch` honors `Retry-After`, release times, and `proof_pending_picks[].retry_at`. Read transport
|
|
131
|
+
failures receive bounded backoff with a visible warning; an ambiguous order does not get retried.
|
|
132
|
+
|
|
133
|
+
## Ledger and recovery
|
|
134
|
+
|
|
135
|
+
`ledger.json` beside `.env` records local submission timestamps, pick identities, reserved stakes,
|
|
136
|
+
and exchange answers. The adjacent `.lock` file coordinates concurrent processes. All instances
|
|
137
|
+
for one wallet must share this ledger and configuration folder on the same local filesystem;
|
|
138
|
+
separate copies or machines do not coordinate. Never delete the ledger or lock files while running.
|
|
139
|
+
|
|
140
|
+
A `submitting`, `accepted`, or `unknown` entry blocks the pick, the same date/rank slot even if its
|
|
141
|
+
token changes, and the token even if the feed relabels its date. Known rejections release their
|
|
142
|
+
reservation. `submitting` and `unknown` entries continue consuming budget across midnight until
|
|
143
|
+
reconciled. Corrupt state fails closed. Existing v1 ledgers remain readable without a migration.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
uv run --locked potd-trader ledger
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
For an unresolved order: stop all instances, inspect Polymarket Activity and the order/fill state,
|
|
150
|
+
and preserve a backup. Only after proving no order can still execute should you remove its local
|
|
151
|
+
entry. If the order exists, preserve its identity and record the confirmed result instead. Never
|
|
152
|
+
clear an entry just to make the bot try again. There is no automatic unknown-order reconciliation.
|
|
153
|
+
|
|
154
|
+
## Upgrade from 0.2.0
|
|
155
|
+
|
|
156
|
+
Stop every old `watch` process first: the old `live off` command cannot stop an already-running
|
|
157
|
+
old binary. Back up your private configuration folder and ledger, install the new release in a
|
|
158
|
+
separate checkout, and use the same ledger path. Run `--dry-run` before restarting live.
|
|
159
|
+
|
|
160
|
+
Behavior changes: `DAILY_CAP_USD=0` is rejected; set a positive cap. Dates are checked against New
|
|
161
|
+
York, but spending is capped by locally recorded UTC submissions. Missing safety data now skips
|
|
162
|
+
trading. Alternate API origins are refused. Environment-only live deployments must mount an
|
|
163
|
+
active `.env` control file containing `LIVE=yes`; keys may still come from the environment.
|
|
164
|
+
|
|
165
|
+
## Settings
|
|
166
|
+
|
|
167
|
+
| Variable | Default | Meaning |
|
|
168
|
+
| --- | --- | --- |
|
|
169
|
+
| `LIVE` | `no` | exact `yes` in process settings and active `.env`, with no `HALT` |
|
|
170
|
+
| `STAKE_USD` | `5` | order principal per pick; `0` means no buys |
|
|
171
|
+
| `MAX_PRICE` | `0.925` | maximum purchase probability |
|
|
172
|
+
| `MAX_SLIPPAGE_PCT` | `3` | maximum increase over the published backed price |
|
|
173
|
+
| `DAILY_CAP_USD` | `25` | positive ceiling on UTC order principal plus unresolved prior intents |
|
|
174
|
+
| `KICKOFF_BUFFER_MINUTES` | `5` | stop buying this far before kickoff or authorization expiry |
|
|
175
|
+
| `MIN_RANKS` / `MAX_RANKS` | `1` / `6` | inclusive ranked slots; a day carries up to 10 picks, so `MAX_RANKS=10` buys every one |
|
|
176
|
+
| `LEDGER_PATH` | `ledger.json` beside `.env` | shared durable order state |
|
|
177
|
+
| `POTD_TRADER_HOME` | `~/.potd-trader` | fallback configuration folder |
|
|
178
|
+
| `WATCH_IDLE_MINUTES` | `30` | idle recheck cadence |
|
|
179
|
+
|
|
180
|
+
## Docker
|
|
181
|
+
|
|
182
|
+
Build from the release checkout. Mount the configuration folder so `live off` on the host and
|
|
183
|
+
container see the same control file and ledger. Never bake secrets into the image.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
docker build -t potd-trader:0.3.0 .
|
|
187
|
+
docker run --rm -v "$PWD/potd-trader:/app/data" potd-trader:0.3.0
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Verification and limits
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
./scripts/pre-merge-check.sh
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The gate runs lint, formatting, strict source typing, fake-exchange safety tests, and CLI checks.
|
|
197
|
+
The tests exercise competing processes, crash recovery, duplicate picks, UTC budgets, stop timing,
|
|
198
|
+
malformed feeds, and credential routing without wallet keys or real submissions. A public SDK/book
|
|
199
|
+
read checks provider compatibility separately. Neither proves future feed integrity or profit.
|
|
200
|
+
|
|
201
|
+
Orders spend real money and cannot be undone. Polymarket regional restrictions apply. This tool
|
|
202
|
+
is MIT licensed, with no warranty; 0xinsider does not operate or custody your wallet.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "potd-trader"
|
|
3
|
+
version = "0.3.1"
|
|
4
|
+
description = "Buy the 0xinsider Pick of the Day on your own Polymarket account. Your keys stay on your machine."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
authors = [{ name = "0xinsider", email = "support@0xinsider.com" }]
|
|
9
|
+
keywords = ["polymarket", "0xinsider", "pick-of-the-day", "sports", "prediction-markets"]
|
|
10
|
+
dependencies = [
|
|
11
|
+
# Official Polymarket SDK: signs orders locally, talks to the CLOB.
|
|
12
|
+
"polymarket-client==0.10.0",
|
|
13
|
+
"httpx>=0.27,<1",
|
|
14
|
+
"pydantic>=2,<3",
|
|
15
|
+
"pydantic-settings>=2,<3",
|
|
16
|
+
"python-dotenv>=1.2,<2",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://0xinsider.com/pick-of-the-day"
|
|
21
|
+
Guide = "https://docs.0xinsider.com/guides/auto-buy-the-pick"
|
|
22
|
+
"API reference" = "https://docs.0xinsider.com/api-reference/endpoint/get-pick-of-the-day"
|
|
23
|
+
Repository = "https://github.com/0xinsider/potd-trader"
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
potd-trader = "potd_trader.cli:main"
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["uv_build==0.8.13"]
|
|
30
|
+
build-backend = "uv_build"
|
|
31
|
+
|
|
32
|
+
[dependency-groups]
|
|
33
|
+
dev = ["mypy>=1.13", "ruff>=0.6"]
|
|
34
|
+
|
|
35
|
+
[tool.ruff]
|
|
36
|
+
line-length = 100
|
|
37
|
+
target-version = "py312"
|
|
38
|
+
|
|
39
|
+
[tool.ruff.lint]
|
|
40
|
+
select = ["E", "F", "I", "UP", "B"]
|
|
41
|
+
|
|
42
|
+
[tool.mypy]
|
|
43
|
+
strict = true
|
|
44
|
+
python_version = "3.12"
|
|
45
|
+
plugins = ["pydantic.mypy"]
|