Skip to content

Backtest price history fix and simulated portfolio fixes - #18

Merged
botta0oss merged 2 commits into
mainfrom
claude/lucid-lovelace-h1c8tm
Sep 25, 2026
Merged

botta0oss merged 2 commits into
mainfrom
claude/lucid-lovelace-h1c8tm

Conversation

@botta0oss

@botta0oss botta0oss commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

1. Backtest: Polymarket price history in 14-day windows

Every backtest case failed with 400 Bad Request on https://clob.polymarket.com/prices-history.

  • The CLOB rejects startTs–endTs windows longer than about 15 days ('startTs' and 'endTs' interval is too long, report).
  • The backtest asked for up to 32 days.
  • For resolved markets the CLOB often has no points finer than 12 hours (Polymarket/py-clob-client#216).

fetch_price_history now:

  • fetches windows of at most 14 days;
  • falls back to fidelity=720 when there are no hourly points;
  • treats a 4xx for one market as no history, so the case is skipped instead of counted as an error.

2. Simulated portfolio

  • Exclude / readmit keeps the history (routes/portfolio.py, settle_bets).
    • Excluding only changes the status. ledger and summary already count bets by status, so the kept fields are not counted.
    • Readmitting a closed bet keeps its result and closing time: settled_at = settled_at or now.
    • A bet sold before being excluded comes back sold, not open.
    • Sold bets excluded by the old code get their pnl rebuilt from the sale price.
  • Multi-outcome positions without an event forecast (latest_prediction): the function falls back to the market's own MarketPrediction. Positions opened before multi-outcome support now get an exit plan and are reviewed by automatic selling.
  • Horizontal scroll on the Portfolio page: .table-wrap is now position: relative. At 951px the page scrollWidth goes from 1301 to 951.
  • Unrealised profit at the bid: open positions are valued at the best bid from the last sync minus the sale fee, which is what selling now would fetch. The value at the market price stays in the API (unrealized_pnl_mid, mid_value) and shows on hover.
  • Manual sale:
    • «Sell now» asks for confirmation.
    • It offers to exclude the market from automatic buys (checked by default), so the next forecast does not buy it back.
  • Opportunities: stored exposure_cap / no_cash reasons that no longer hold, for example after a sale, are flagged (economics.stale). The card says to open the market for up-to-date numbers.
  • Two stakes:
    • The simplified Kelly is now labelled «Simple Kelly (indicative)».
    • Its explanation points to the real stake of the «Worth it?» assessment, and shows that stake when it was computed.
  • One label left untranslated («Ricomincia…») is now translated.

Tests

  • New tests in tests/test_portfolio.py:
    • a lost bet excluded and readmitted keeps settled_at, pnl and the time of its point on the equity curve;
    • a sold bet stays sold;
    • a sold bet excluded by the old code gets its result back;
    • an outcome without an event forecast uses its own forecast and gets a plan;
    • open positions are valued at the bid;
    • stale exposure reasons are flagged.
  • The first three bugs reproduce without the fix.
  • Full suite: 197 passed.
  • Playwright:
    • no horizontal scroll on #/portafoglio at 390, 951 and 1280px;
    • the sale confirmation works in IT and EN, and Cancel restores the buttons.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JLWZrfy12imc6dQRsEtFjj

The CLOB now answers 400 ("'startTs' and 'endTs' interval is too long") to
/prices-history windows longer than about 15 days, and the backtest asked
for up to 32 days (30-day horizon + 2), so every case failed. The history
is now fetched in windows of at most 14 days; resolved markets without
hourly points are asked again every 12 hours; a 4xx for one market means
no history (case skipped) instead of an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JLWZrfy12imc6dQRsEtFjj
…s, bid value

- Excluding a bet only changes its status; readmitting restores it as it was:
  a sold bet comes back sold, a closed one keeps its result and closing time
  (settle_bets no longer overwrites settled_at). Sold bets excluded by the old
  code get their result rebuilt from the sale.
- latest_prediction falls back to the market's own forecast when its
  multi-outcome event has none, so positions opened before multi-outcome
  support get an exit plan and are reviewed by automatic selling.
- Open positions are valued at the best bid minus the sale fee (what selling
  now would fetch); the value at the market price stays available.
- "Sell now" asks for confirmation and offers to exclude the market from
  automatic buys, so the next forecast does not buy it back.
- Opportunities flag stored exposure/cash reasons that no longer hold.
- The simplified Kelly stake is labelled as indicative and points to the
  real stake of the economic assessment.
- .table-wrap is position: relative, so the hidden "Actions" header no longer
  widens the Portfolio page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JLWZrfy12imc6dQRsEtFjj
@botta0oss botta0oss changed the title Backtest: fetch Polymarket price history in 14-day windows Backtest price history fix and simulated portfolio fixes Sep 25, 2026
@botta0oss
botta0oss merged commit 1258748 into main Sep 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants