racinglines 1.0.0__py3-none-any.whl
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.
- racinglines/__init__.py +10 -0
- racinglines/__main__.py +5 -0
- racinglines/_bundled/exchanges/og.toml +188 -0
- racinglines/_bundled/markets/kinds.toml +567 -0
- racinglines/_bundled/migrations/env.py +38 -0
- racinglines/_bundled/migrations/script.py.mako +24 -0
- racinglines/_bundled/migrations/versions/20260926_0e47bb766d0b_house_markets_and_bets.py +68 -0
- racinglines/_bundled/migrations/versions/20260926_1983462a0695_initial_schema.py +258 -0
- racinglines/_bundled/migrations/versions/20260926_3f94d44a125e_market_trades_and_book_snapshots.py +57 -0
- racinglines/_bundled/migrations/versions/20260926_50a176ca2955_market_price_history.py +33 -0
- racinglines/_bundled/migrations/versions/20260926_66d4b92ba307_market_links_and_orders.py +79 -0
- racinglines/_bundled/migrations/versions/20260926_81022900a936_jobs.py +45 -0
- racinglines/_bundled/migrations/versions/20260926_8c46493d7cda_house_market_uniqueness_per_mirrored_.py +30 -0
- racinglines/_bundled/migrations/versions/20260926_8d64d59a2940_users_roles_activity_log.py +80 -0
- racinglines/_bundled/migrations/versions/20260926_d84cd5aa7ce4_polymarket_alignment.py +83 -0
- racinglines/_bundled/migrations/versions/20260926_f3e017071b76_laps_track_profiles_round_extra.py +64 -0
- racinglines/_bundled/migrations/versions/20260927_5b1e0c7d2a41_user_prefs.py +24 -0
- racinglines/_bundled/migrations/versions/20260927_9c4d2e8f1a63_market_first_seen.py +23 -0
- racinglines/_bundled/migrations/versions/20260927_c7a1f4e2b9d0_strategy_signals.py +79 -0
- racinglines/_bundled/migrations/versions/20260927_d2b8e5a1c3f7_replay_taker_account.py +35 -0
- racinglines/_bundled/migrations/versions/20260927_e4c1a9b7d205_paper_position_venue.py +23 -0
- racinglines/_bundled/migrations/versions/20260929_a3f5c8d1e7b2_live_events.py +40 -0
- racinglines/_bundled/migrations/versions/20260929_b7d2e4f1a9c3_data_changes.py +33 -0
- racinglines/_bundled/migrations/versions/20260929_c8e3f6a2d4b1_market_disagreements.py +55 -0
- racinglines/_bundled/migrations/versions/20261002_d9f2a7e5c1b3_user_email_prefs.py +40 -0
- racinglines/_bundled/migrations/versions/20261002_d9f4b1c7e5a2_user_mcp_tokens.py +24 -0
- racinglines/_bundled/migrations/versions/20261003_f8a2c4e7b5d1_fastf1_snapshots.py +59 -0
- racinglines/_bundled/migrations/versions/20261005_a7e3c1f9b4d2_kalshi_candlestick_bid_ask.py +34 -0
- racinglines/_bundled/sports/f1/calibration.toml +241 -0
- racinglines/_bundled/sports/f1/fastest_lap.toml +72 -0
- racinglines/_bundled/sports/f1/grid_penalties.toml +24 -0
- racinglines/_bundled/sports/f1.toml +228 -0
- racinglines/_bundled/sports/mtb_dh.toml +161 -0
- racinglines/_bundled/sports/points/uci_dhi_wc.toml +57 -0
- racinglines/attribution.py +137 -0
- racinglines/books/__init__.py +3 -0
- racinglines/books/ledger.py +138 -0
- racinglines/books/picks.py +132 -0
- racinglines/books/render.css +85 -0
- racinglines/books/render.py +650 -0
- racinglines/books/schema.py +394 -0
- racinglines/books/slips.py +561 -0
- racinglines/cli/__init__.py +120 -0
- racinglines/cli/backtest.py +197 -0
- racinglines/cli/book.py +432 -0
- racinglines/cli/check.py +44 -0
- racinglines/cli/config.py +57 -0
- racinglines/cli/db.py +204 -0
- racinglines/cli/f1.py +1302 -0
- racinglines/cli/live.py +555 -0
- racinglines/cli/markets.py +337 -0
- racinglines/cli/mtb_dh.py +502 -0
- racinglines/cli/replay_cmd.py +405 -0
- racinglines/cli/rich_view.py +130 -0
- racinglines/cli/source.py +274 -0
- racinglines/cli/tty.py +115 -0
- racinglines/cli/users.py +141 -0
- racinglines/cli/verbs.py +217 -0
- racinglines/cli/web.py +34 -0
- racinglines/core/__init__.py +1 -0
- racinglines/core/calibration.py +60 -0
- racinglines/core/stages.py +54 -0
- racinglines/core/stats.py +34 -0
- racinglines/core/walk_forward.py +103 -0
- racinglines/db/__init__.py +0 -0
- racinglines/db/changes.py +51 -0
- racinglines/db/config.py +33 -0
- racinglines/db/ingest.py +194 -0
- racinglines/db/mirror.py +433 -0
- racinglines/db/models.py +654 -0
- racinglines/db/pull.py +336 -0
- racinglines/db/queries.py +183 -0
- racinglines/db/reads.py +335 -0
- racinglines/db/records.py +61 -0
- racinglines/db/registry.py +41 -0
- racinglines/db/schedule.py +142 -0
- racinglines/db/snapshot.py +71 -0
- racinglines/demo/__init__.py +0 -0
- racinglines/demo/mk_demo/__init__.py +2 -0
- racinglines/demo/mk_demo/generate.py +513 -0
- racinglines/demo/packs/kart/book.toml +147 -0
- racinglines/demo/packs/kart/files/live/f1/demo-2026-09.toml +35 -0
- racinglines/demo/packs/kart/pack.toml +72 -0
- racinglines/demo/packs/kart/world.toml +336 -0
- racinglines/demo/store.py +279 -0
- racinglines/exchanges.py +78 -0
- racinglines/fantasy/__init__.py +8 -0
- racinglines/fantasy/exchange.py +653 -0
- racinglines/fantasy/follow.py +287 -0
- racinglines/fantasy/ledger.py +313 -0
- racinglines/fantasy/sizing.py +110 -0
- racinglines/frames/__init__.py +55 -0
- racinglines/frames/_util.py +34 -0
- racinglines/frames/f1.py +123 -0
- racinglines/frames/mtb_dh.py +156 -0
- racinglines/frames/schema.py +255 -0
- racinglines/markets/__init__.py +0 -0
- racinglines/markets/alerts.py +219 -0
- racinglines/markets/combos.py +260 -0
- racinglines/markets/crowd.py +249 -0
- racinglines/markets/disagree.py +442 -0
- racinglines/markets/exchange_driver.py +733 -0
- racinglines/markets/identity.py +54 -0
- racinglines/markets/kalshi/__init__.py +0 -0
- racinglines/markets/kalshi/client.py +113 -0
- racinglines/markets/kalshi/sync.py +565 -0
- racinglines/markets/kalshi/trade.py +110 -0
- racinglines/markets/kinds.py +312 -0
- racinglines/markets/payoffs.py +502 -0
- racinglines/markets/polymarket/__init__.py +0 -0
- racinglines/markets/polymarket/links.py +107 -0
- racinglines/markets/polymarket/sync.py +611 -0
- racinglines/markets/polymarket/trade.py +240 -0
- racinglines/markets/private_book.py +438 -0
- racinglines/markets/probalytics.py +390 -0
- racinglines/markets/quoting.py +76 -0
- racinglines/markets/settle_check.py +136 -0
- racinglines/markets/settlement_rules.py +184 -0
- racinglines/markets/store.py +407 -0
- racinglines/markets/strategies/__init__.py +0 -0
- racinglines/markets/strategies/buy_everything.py +107 -0
- racinglines/markets/strategies/maker_replay.py +691 -0
- racinglines/markets/strategies/replay_json.py +51 -0
- racinglines/markets/strategies/season.py +162 -0
- racinglines/markets/strategies/sizing.py +30 -0
- racinglines/markets/strategies/taker_weekend.py +312 -0
- racinglines/markets/venue_replay.py +454 -0
- racinglines/markets/venues.py +654 -0
- racinglines/models/__init__.py +0 -0
- racinglines/models/calibration.py +173 -0
- racinglines/models/combo_job.py +212 -0
- racinglines/models/dnf_check.py +123 -0
- racinglines/models/evaluate.py +267 -0
- racinglines/models/inputs/__init__.py +107 -0
- racinglines/models/inputs/grid.py +138 -0
- racinglines/models/inputs/laps.py +864 -0
- racinglines/models/inputs/laps_core.py +82 -0
- racinglines/models/inputs/laps_pricing.py +730 -0
- racinglines/models/inputs/practice.py +246 -0
- racinglines/models/inputs/results.py +454 -0
- racinglines/models/inputs/run_times/__init__.py +6 -0
- racinglines/models/inputs/run_times/core.py +107 -0
- racinglines/models/inputs/run_times/model.py +296 -0
- racinglines/models/inputs/run_times/points.py +183 -0
- racinglines/models/inputs/run_times/season.py +271 -0
- racinglines/models/inputs/run_times/settings.py +61 -0
- racinglines/models/inrace.py +46 -0
- racinglines/models/model_global.py +70 -0
- racinglines/models/outcomes.py +224 -0
- racinglines/models/position_sim/__init__.py +27 -0
- racinglines/models/props.py +394 -0
- racinglines/models/race_model.py +95 -0
- racinglines/models/sprint_check.py +114 -0
- racinglines/models/timed_runs/__init__.py +15 -0
- racinglines/models/variants.py +84 -0
- racinglines/paths.py +62 -0
- racinglines/pipelines/__init__.py +0 -0
- racinglines/pipelines/clv.py +470 -0
- racinglines/pipelines/coverage.py +199 -0
- racinglines/pipelines/demo_history.py +91 -0
- racinglines/pipelines/live.py +341 -0
- racinglines/pipelines/live_dh.py +983 -0
- racinglines/pipelines/live_f1.py +897 -0
- racinglines/pipelines/live_report.py +280 -0
- racinglines/pipelines/model_vs_market.py +128 -0
- racinglines/pipelines/position_replay.py +636 -0
- racinglines/pipelines/profiles.py +418 -0
- racinglines/pipelines/reconcile.py +483 -0
- racinglines/pipelines/scorecard.py +302 -0
- racinglines/pipelines/search.py +580 -0
- racinglines/pipelines/search_plan.py +108 -0
- racinglines/pipelines/search_report.py +404 -0
- racinglines/pipelines/season_checkpoints.py +174 -0
- racinglines/pipelines/season_replay.py +362 -0
- racinglines/pipelines/season_strategy.py +369 -0
- racinglines/pipelines/season_sweep.py +498 -0
- racinglines/pipelines/signals.py +933 -0
- racinglines/pipelines/sport_forecast.py +201 -0
- racinglines/pipelines/sport_paper.py +302 -0
- racinglines/pipelines/sport_signals.py +331 -0
- racinglines/pipelines/story.py +345 -0
- racinglines/pipelines/sweep_settings.py +379 -0
- racinglines/pipelines/weekend_sweep.py +680 -0
- racinglines/progress.py +110 -0
- racinglines/reporting/__init__.py +1 -0
- racinglines/reporting/markdown_html.py +55 -0
- racinglines/reporting/metrics.py +19 -0
- racinglines/reporting/search_analyze.py +231 -0
- racinglines/reporting/search_noise.py +59 -0
- racinglines/reporting/search_plot.py +157 -0
- racinglines/sources/__init__.py +0 -0
- racinglines/sources/chronorace/__init__.py +0 -0
- racinglines/sources/chronorace/download.py +488 -0
- racinglines/sources/chronorace/ingest.py +131 -0
- racinglines/sources/chronorace/parse.py +736 -0
- racinglines/sources/chronorace/pdf.py +198 -0
- racinglines/sources/fastf1/__init__.py +0 -0
- racinglines/sources/fastf1/fetch.py +219 -0
- racinglines/sources/fastf1/ingest.py +350 -0
- racinglines/sources/http.py +108 -0
- racinglines/sports.py +233 -0
- racinglines/testing/__init__.py +0 -0
- racinglines/testing/checks.py +273 -0
- racinglines/testing/synthetic.py +265 -0
- racinglines/weather/__init__.py +21 -0
- racinglines/weather/open_meteo.py +269 -0
- racinglines/weather/schema.py +173 -0
- racinglines/weather/venues.toml +278 -0
- racinglines/weather/wet.py +274 -0
- racinglines/weather/wunderground.py +230 -0
- racinglines/web/__init__.py +1 -0
- racinglines/web/accounts.py +170 -0
- racinglines/web/admin.py +508 -0
- racinglines/web/api.py +80 -0
- racinglines/web/app.py +912 -0
- racinglines/web/audience.py +47 -0
- racinglines/web/board.py +342 -0
- racinglines/web/book_routes.py +318 -0
- racinglines/web/demo.py +83 -0
- racinglines/web/diag.py +314 -0
- racinglines/web/diag_routes.py +89 -0
- racinglines/web/edge.py +453 -0
- racinglines/web/exchange_routes.py +207 -0
- racinglines/web/f1_live.py +191 -0
- racinglines/web/f1_ws.py +283 -0
- racinglines/web/fantasy_routes.py +211 -0
- racinglines/web/formats.py +87 -0
- racinglines/web/info_routes.py +154 -0
- racinglines/web/jobs.py +517 -0
- racinglines/web/layout.py +52 -0
- racinglines/web/legacy.py +38 -0
- racinglines/web/mybets.py +28 -0
- racinglines/web/order_routes.py +186 -0
- racinglines/web/prefs.py +45 -0
- racinglines/web/ranges.py +43 -0
- racinglines/web/roles.py +192 -0
- racinglines/web/sport_status.py +227 -0
- racinglines/web/static/app.js +700 -0
- racinglines/web/static/brand/logo.svg +8 -0
- racinglines/web/static/f1_stream.js +58 -0
- racinglines/web/static/htmx.min.js +1 -0
- racinglines/web/static/replay.js +115 -0
- racinglines/web/static/replay.wasm +0 -0
- racinglines/web/static/style.css +643 -0
- racinglines/web/strategy_pick.py +208 -0
- racinglines/web/templates/_admin_nav.html +9 -0
- racinglines/web/templates/_board_recent.html +9 -0
- racinglines/web/templates/_board_sport.html +66 -0
- racinglines/web/templates/_lab_nav.html +8 -0
- racinglines/web/templates/_macros.html +77 -0
- racinglines/web/templates/_recorders.html +11 -0
- racinglines/web/templates/_site_notice.html +28 -0
- racinglines/web/templates/_sport_status.html +14 -0
- racinglines/web/templates/_storage_status.html +60 -0
- racinglines/web/templates/admin.html +19 -0
- racinglines/web/templates/admin_activity.html +17 -0
- racinglines/web/templates/admin_db.html +11 -0
- racinglines/web/templates/admin_mcp.html +25 -0
- racinglines/web/templates/admin_monitors.html +25 -0
- racinglines/web/templates/admin_row.html +17 -0
- racinglines/web/templates/admin_sql.html +19 -0
- racinglines/web/templates/admin_table.html +17 -0
- racinglines/web/templates/admin_user.html +29 -0
- racinglines/web/templates/admin_users.html +47 -0
- racinglines/web/templates/athlete.html +11 -0
- racinglines/web/templates/base.html +37 -0
- racinglines/web/templates/base_public.html +8 -0
- racinglines/web/templates/bet.html +43 -0
- racinglines/web/templates/board.html +61 -0
- racinglines/web/templates/book.html +32 -0
- racinglines/web/templates/diag.html +123 -0
- racinglines/web/templates/error.html +7 -0
- racinglines/web/templates/event.html +15 -0
- racinglines/web/templates/exchange.html +44 -0
- racinglines/web/templates/fantasy_trade.html +53 -0
- racinglines/web/templates/forgot.html +26 -0
- racinglines/web/templates/history.html +90 -0
- racinglines/web/templates/house.html +51 -0
- racinglines/web/templates/house_market.html +47 -0
- racinglines/web/templates/house_sheet.html +15 -0
- racinglines/web/templates/lab.html +26 -0
- racinglines/web/templates/lab_backtests.html +9 -0
- racinglines/web/templates/lab_diagnostics.html +12 -0
- racinglines/web/templates/lab_edge.html +134 -0
- racinglines/web/templates/lab_jobs.html +12 -0
- racinglines/web/templates/lab_models.html +9 -0
- racinglines/web/templates/lab_run.html +39 -0
- racinglines/web/templates/lab_runs.html +6 -0
- racinglines/web/templates/lab_scenarios.html +11 -0
- racinglines/web/templates/lab_sport_sweep_form.html +25 -0
- racinglines/web/templates/lab_sweep_form.html +40 -0
- racinglines/web/templates/live.html +52 -0
- racinglines/web/templates/live_f1.html +97 -0
- racinglines/web/templates/live_f1_stream.html +690 -0
- racinglines/web/templates/live_mtb_dh.html +95 -0
- racinglines/web/templates/live_partial.html +1 -0
- racinglines/web/templates/live_picks.html +17 -0
- racinglines/web/templates/market.html +31 -0
- racinglines/web/templates/market_lookup.html +37 -0
- racinglines/web/templates/markets.html +18 -0
- racinglines/web/templates/mcp_authorize.html +21 -0
- racinglines/web/templates/order_preview.html +21 -0
- racinglines/web/templates/orders.html +20 -0
- racinglines/web/templates/positions.html +144 -0
- racinglines/web/templates/positions_backtests.html +26 -0
- racinglines/web/templates/race.html +119 -0
- racinglines/web/templates/racinglines101.html +389 -0
- racinglines/web/templates/run.html +17 -0
- racinglines/web/templates/settings.html +111 -0
- racinglines/web/templates/signin.html +19 -0
- racinglines/web/templates/signup.html +31 -0
- racinglines/web/templates/strategy.html +137 -0
- racinglines/web/templates/strategy_pick.html +51 -0
- racinglines/web/templates/strategy_pick_alpha.html +56 -0
- racinglines/web/templates/tapes.html +25 -0
- racinglines/web/templates/term.html +51 -0
- racinglines/web/term/demos.toml +16 -0
- racinglines/web/term/f1-singapore-10.ansi +21 -0
- racinglines/web/term/f1-singapore-10.html +23 -0
- racinglines/web/term/f1-singapore-2.ansi +7 -0
- racinglines/web/term/f1-singapore-2.html +9 -0
- racinglines/web/term/f1-singapore-4.ansi +21 -0
- racinglines/web/term/f1-singapore-4.html +23 -0
- racinglines/web/term/f1-singapore-6.ansi +21 -0
- racinglines/web/term/f1-singapore-6.html +23 -0
- racinglines/web/term/f1-singapore-8.ansi +21 -0
- racinglines/web/term/f1-singapore-8.html +23 -0
- racinglines/web/term/f1-singapore.json +48 -0
- racinglines/web/term/f1-singapore.toml +84 -0
- racinglines/web/term/quickstart.json +37 -0
- racinglines/web/term/step-1.html +0 -0
- racinglines/web/term/step-2.ansi +37 -0
- racinglines/web/term/step-2.html +39 -0
- racinglines/web/term/step-3.ansi +52 -0
- racinglines/web/term/step-3.html +54 -0
- racinglines/web/term/step-4.ansi +60 -0
- racinglines/web/term/step-4.html +62 -0
- racinglines/web/term/step-5.ansi +146 -0
- racinglines/web/term/step-5.html +148 -0
- racinglines/web/term_routes.py +72 -0
- racinglines/web/users.py +130 -0
- racinglines/web/views.py +1117 -0
- racinglines/web/viz.py +183 -0
- racinglines-1.0.0.dist-info/METADATA +273 -0
- racinglines-1.0.0.dist-info/RECORD +349 -0
- racinglines-1.0.0.dist-info/WHEEL +5 -0
- racinglines-1.0.0.dist-info/entry_points.txt +2 -0
- racinglines-1.0.0.dist-info/licenses/LICENSE +21 -0
- racinglines-1.0.0.dist-info/top_level.txt +1 -0
racinglines/__init__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""racinglines: fair prices and market making for race sports. See `racinglines -h`."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
if sys.version_info < (3, 11):
|
|
6
|
+
raise SystemExit(
|
|
7
|
+
f"racinglines needs Python 3.11+ (this is {sys.version.split()[0]} at {sys.executable}).\n"
|
|
8
|
+
"Set up the project environment once:\n"
|
|
9
|
+
" python3.14 -m venv .venv && source .venv/bin/activate\n"
|
|
10
|
+
" pip install -r requirements.txt && pip install -e .")
|
racinglines/__main__.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# OG.com (Crypto.com's CFTC prediction market): an exchange defined as data. Read by racinglines/exchanges.py; the one
|
|
2
|
+
# generic driver (racinglines/markets/exchange_driver.py) does the sync, tape, history and books from this file, so
|
|
3
|
+
# adding a venue with a plain JSON API is a new file here, not new code. Read-only: only public market data, no key.
|
|
4
|
+
# Built from real responses captured 2026-09-29 (tests/fixtures/market/og_*.json, described in og_README.txt).
|
|
5
|
+
# Off by default: the app shows the venue only with RACINGLINES_OG_VENUE=1. Nothing here sends an order.
|
|
6
|
+
|
|
7
|
+
[exchange]
|
|
8
|
+
code = "og"
|
|
9
|
+
name = "OG.com"
|
|
10
|
+
kind = "exchange"
|
|
11
|
+
switch = "RACINGLINES_OG_VENUE" # env var; the venue appears in the app only when it is 1 / true / yes
|
|
12
|
+
url = "https://og.com/" # no per-event page pattern known: the venue links to the front page
|
|
13
|
+
# What the feed offers historically, shown under the Markets board's "Exchange data" counts.
|
|
14
|
+
coverage = "OG.com: the API serves only about the last month of trades and minute prices, so history starts when we began pulling (2026-09-29); no book history (one snapshot per books run)."
|
|
15
|
+
# The taker fee per contract, in dollars, from 2026 reviews of the exchange (UNVERIFIED against its fee schedule).
|
|
16
|
+
# Used only by the fair-price report; change it here when the schedule is confirmed.
|
|
17
|
+
taker_fee_per_contract = 0.02
|
|
18
|
+
|
|
19
|
+
[api]
|
|
20
|
+
host = "https://api.crypto.com"
|
|
21
|
+
host_env = "OG_API_HOST" # override, e.g. the UAT sandbox https://uat-api.3ona.co
|
|
22
|
+
prefix = "/fcm/v1/public"
|
|
23
|
+
timeout = 20
|
|
24
|
+
max_per_second = 20 # the exchange allows 100 per method per IP; stay well under it
|
|
25
|
+
ok_path = "code" # every response is {"code": 0, "result": {...}}
|
|
26
|
+
ok_value = 0
|
|
27
|
+
error_path = "message"
|
|
28
|
+
|
|
29
|
+
[endpoints.events]
|
|
30
|
+
path = "/get-events"
|
|
31
|
+
data = "result.data"
|
|
32
|
+
next = "result.next_cursor" # paged with cursor=<next>; the last page has none
|
|
33
|
+
cursor_param = "cursor"
|
|
34
|
+
params = { since = 0, limit = 1000 }
|
|
35
|
+
|
|
36
|
+
[endpoints.instruments]
|
|
37
|
+
path = "/get-instruments"
|
|
38
|
+
data = "result.data"
|
|
39
|
+
next = "result.next_cursor"
|
|
40
|
+
cursor_param = "cursor"
|
|
41
|
+
params = { limit = 1000 }
|
|
42
|
+
batch_param = "event_symbols" # comma-separated event symbols, at most `batch_size` per call
|
|
43
|
+
# The live API caps this at 10: 11 or more event symbols return 400 {"code": 40004, "message": "Invalid event_symbol"}
|
|
44
|
+
# whatever the symbols are (checked against api.crypto.com on 2026-09-29; the fixture request used 2). get-tickers took 20.
|
|
45
|
+
batch_size = 10
|
|
46
|
+
limits = { max_batch = 10 } # checked when the schema loads (racinglines/exchanges.py)
|
|
47
|
+
|
|
48
|
+
[endpoints.tickers]
|
|
49
|
+
path = "/get-tickers"
|
|
50
|
+
data = "result.data"
|
|
51
|
+
batch_param = "instrument_name" # comma-separated instrument symbols
|
|
52
|
+
batch_size = 50
|
|
53
|
+
|
|
54
|
+
[endpoints.book]
|
|
55
|
+
path = "/get-book"
|
|
56
|
+
data = "result.data"
|
|
57
|
+
params = { depth = 50 }
|
|
58
|
+
instrument_param = "instrument_name"
|
|
59
|
+
|
|
60
|
+
[endpoints.trades]
|
|
61
|
+
path = "/get-trades"
|
|
62
|
+
data = "result.data"
|
|
63
|
+
instrument_param = "instrument_name"
|
|
64
|
+
start_param = "start_ts" # nanoseconds
|
|
65
|
+
start_unit = "ns"
|
|
66
|
+
params = { count = 150 } # the server's maximum: 200 and up is "Invalid count" (checked 2026-09-29)
|
|
67
|
+
limits = { max_count = 150 }
|
|
68
|
+
window_days = 30 # the docs say 7; the server accepted 30 and 60, and returned nothing at 100
|
|
69
|
+
|
|
70
|
+
[endpoints.history]
|
|
71
|
+
path = "/get-ticker-histories"
|
|
72
|
+
data = "result.data"
|
|
73
|
+
instrument_param = "instrument_names"
|
|
74
|
+
start_param = "start_ts" # milliseconds
|
|
75
|
+
end_param = "end_ts"
|
|
76
|
+
start_unit = "ms"
|
|
77
|
+
params = { count = 1000 }
|
|
78
|
+
window_days = 31 # start to end at most 31 days, 1,000 one-minute rows a call
|
|
79
|
+
limits = { max_window_days = 31 }
|
|
80
|
+
|
|
81
|
+
[endpoints.settlements]
|
|
82
|
+
# Who won. get-instruments, get-events and get-tickers drop an instrument once it settles (a settled event returns
|
|
83
|
+
# []), so the listing never says the outcome; this feed does. It holds every instrument the exchange settles (mostly
|
|
84
|
+
# FX and crypto, about 20,000 rows per 12 hours), unfiltered: an instrument_type filter is refused together with
|
|
85
|
+
# since / cursor. exchange_driver.settle scans it forward from `since` until every closed, unresolved link of the
|
|
86
|
+
# sport is found or the feed ends (probed from the owner's Mac 2026-10-06; the docs site is JS-only and unreadable).
|
|
87
|
+
path = "/get-expired-settlement-price"
|
|
88
|
+
data = "result.data"
|
|
89
|
+
next = "result.next_cursor" # paged with cursor=<next>, like get-events; the last page has none
|
|
90
|
+
cursor_param = "cursor"
|
|
91
|
+
start_param = "since" # nanoseconds; the feed goes back to about 2026-07-08
|
|
92
|
+
start_unit = "ns"
|
|
93
|
+
params = { limit = 1000 } # 1,000 rows a call worked; about 20 calls cover 12 hours
|
|
94
|
+
max_pages = 500 # our own cap per pass (500,000 rows, about 12 days); the next pass resumes
|
|
95
|
+
|
|
96
|
+
# Where each thing lives in a response: dotted paths into the JSON ("a.b" = obj["a"]["b"]). `unit` says how a time
|
|
97
|
+
# is written: ms / ns since the epoch, or iso.
|
|
98
|
+
[fields.event]
|
|
99
|
+
id = "symbol"
|
|
100
|
+
name = "name"
|
|
101
|
+
sports_grouping = "event_details.metaData.SPORTS_GROUPING"
|
|
102
|
+
|
|
103
|
+
[fields.instrument]
|
|
104
|
+
id = "symbol"
|
|
105
|
+
event = "underlying_symbol"
|
|
106
|
+
subject = "event_details.metaData.PARTICIPANT" # the driver, team or player
|
|
107
|
+
contract = "event_details.metaData.PREDICT_CONTRACT_TYPE" # the market's name, e.g. "F1 Drivers' Champion 2026"
|
|
108
|
+
event_title = "event_details.metaData.NAME"
|
|
109
|
+
title = "display_name"
|
|
110
|
+
tick = "price_tick_size"
|
|
111
|
+
tradable = "tradable"
|
|
112
|
+
expiry = "expiry_timestamp_ms"
|
|
113
|
+
expiry_unit = "ms"
|
|
114
|
+
|
|
115
|
+
[fields.ticker]
|
|
116
|
+
instrument = "i"
|
|
117
|
+
bid = "b"
|
|
118
|
+
ask = "k"
|
|
119
|
+
last = "a"
|
|
120
|
+
volume = "v"
|
|
121
|
+
|
|
122
|
+
[fields.book]
|
|
123
|
+
instrument = "instrument_name"
|
|
124
|
+
bids = "data.0.bids" # levels [price, quantity], strings
|
|
125
|
+
asks = "data.0.asks"
|
|
126
|
+
ts = "data.0.t"
|
|
127
|
+
ts_unit = "ms"
|
|
128
|
+
|
|
129
|
+
[fields.trade]
|
|
130
|
+
id = "d"
|
|
131
|
+
ts = "t"
|
|
132
|
+
ts_unit = "ms"
|
|
133
|
+
price = "p"
|
|
134
|
+
size = "q"
|
|
135
|
+
side = "s" # "buy" / "sell", the taker's side of the YES contract
|
|
136
|
+
|
|
137
|
+
[fields.history]
|
|
138
|
+
instrument = "i"
|
|
139
|
+
ts = "t"
|
|
140
|
+
ts_unit = "ms"
|
|
141
|
+
bid = "b"
|
|
142
|
+
ask = "k"
|
|
143
|
+
last = "a"
|
|
144
|
+
|
|
145
|
+
[fields.settlement]
|
|
146
|
+
# One row per settled instrument: {"i": symbol, "x": expiry ms, "v": "1.00" | "0.00" | "0.50", "t": settled at ms}.
|
|
147
|
+
# `value` is what one YES contract paid: 1 = YES, 0 = NO, anything between (0.50 seen) is a void, which leaves
|
|
148
|
+
# resolved_yes empty. Sports contracts settle when decided, not at the nominal expiry (the Sepang race winners
|
|
149
|
+
# expire 2026-11-30; 21 of 22 settled 2026-10-04 11:36 UTC), so `ts` is the settle time and `expiry` only a note.
|
|
150
|
+
instrument = "i" # equals market_links.token_id (and market_slug)
|
|
151
|
+
value = "v"
|
|
152
|
+
ts = "t"
|
|
153
|
+
ts_unit = "ms"
|
|
154
|
+
expiry = "x"
|
|
155
|
+
expiry_unit = "ms"
|
|
156
|
+
|
|
157
|
+
[prices]
|
|
158
|
+
unit = "dollars" # 0 to 1, decimal strings; a contract pays $1
|
|
159
|
+
|
|
160
|
+
# What the exchange lists of each of our sports: how to find its events and how a market is named. A sport listed
|
|
161
|
+
# here without `modeled = true` is tape-only (every link unmodeled, recorded like Kalshi's NASCAR). Its rules map a
|
|
162
|
+
# market's contract name (regex, case-insensitive, first match wins) to one of our prediction kinds and to what its
|
|
163
|
+
# `subject` field names (driver, team). The sport's own schema (sports/<code>.toml) says which competition it is.
|
|
164
|
+
[sports.f1]
|
|
165
|
+
event_prefixes = ["F1-"] # season futures carry no SPORTS_GROUPING, so events are found by symbol
|
|
166
|
+
modeled = true
|
|
167
|
+
[[sports.f1.rules]]
|
|
168
|
+
contract = "constructors'? champion"
|
|
169
|
+
kind = "constructors_champion"
|
|
170
|
+
subject = "team"
|
|
171
|
+
[[sports.f1.rules]]
|
|
172
|
+
contract = "drivers'? champion"
|
|
173
|
+
kind = "champion"
|
|
174
|
+
subject = "driver"
|
|
175
|
+
[[sports.f1.rules]]
|
|
176
|
+
contract = "^race winner$" # a Grand Prix's winner (event "Bahrain Grand Prix 2026"): linked to that race
|
|
177
|
+
kind = "race_win"
|
|
178
|
+
subject = "driver"
|
|
179
|
+
|
|
180
|
+
[sports.nascar]
|
|
181
|
+
event_prefixes = ["NSCAR-"] # 17 Cup Champion contracts; tape only
|
|
182
|
+
modeled = false
|
|
183
|
+
|
|
184
|
+
[sports.sailgp]
|
|
185
|
+
# 13 Championship Winner contracts plus per-event Overall Winner events (tests/fixtures/market/og_events_sailgp.json,
|
|
186
|
+
# symbols SAIL-000NN-26); tape only
|
|
187
|
+
event_prefixes = ["SAIL-"]
|
|
188
|
+
modeled = false
|