BANGER
Product status: Banger’s public beta is paper-only. References to live execution are future-looking. Venue rules and legal claims can change; verify current primary sources for your jurisdiction.
2026-10-16 · 6 min read · facts as of 2026-10-16

Keep Market Identifiers Consistent Across Research Artifacts

A backtest that says "this strategy worked on the NYC high-temperature market" is almost useless six weeks later. Which NYC high-temperature market? Which day? Which strike? Which side? If your saved result does not pin down the exact instrument, you will eventually compare two different contracts as if they were one, and you will not notice until the numbers stop making sense.

Kalshi's own data model gives you the vocabulary to avoid this. The fix is to record the full identity chain next to every artifact, not just a human-readable title. Here is how the levels work and what to persist.

The four levels of identity

Kalshi organizes everything in a three-level hierarchy, and a market carries one more distinction below it: which side you hold.

The series is the top-level object. A series is a template for recurring events that follow the same format and rules, for example a monthly jobs report or daily NYC weather. Series define the structure, settlement sources, and metadata applied to each recurring event.

An event is a collection of markets and the basic unit members interact with. An event represents one real-world occurrence, like a specific election, game, or indicator release, and contains one or more markets covering different outcomes or strikes.

A market is a single binary contract within an event. Each event belongs to exactly one series, identified by series_ticker, and each market belongs to exactly one event, identified by event_ticker.

The documented example makes the nesting concrete: a series like KXHIGHNY has an event such as KXHIGHNY-24JAN01, which in turn has a market such as KXHIGHNY-24JAN01-T60. The best practice is to filter and group by the series rather than inferring structure from the string.

Do not parse the ticker to infer relationships

It is tempting to split KXHIGHNY-24JAN01-T60 on the hyphens and assume you have recovered the series, event, and strike. Developer guides tracking the current API warn explicitly against parsing ticker strings to infer relationships, and recommend using the API's actual relationship fields instead. Tickers often follow the Series to Event to Market pattern, but categories and subcategories are not part of the ticker convention, and the string format is not a contract you should build on.

Store series_ticker, event_ticker, and the market ticker as separate fields that you read from the API response, not substrings you reconstructed. That way a formatting change does not silently corrupt your joins.

Why the outcome side has to be explicit

For a standard binary market the YES and NO sides are complements: the winning side pays out one dollar per contract and the losing side expires worthless. A result that logs "bought the market" without logging the side is ambiguous about the entire payoff.

Do not universalize that one-dollar payoff. Kalshi also runs scalar markets, where both YES and NO can be redeemable at proportional payouts rather than a clean one-or-zero. The market result field takes a third value, scalar, for fractionally-settled markets; a query filtering only on yes or no silently drops them. If your artifact assumes every contract is a $1/$0 binary, it will misprice scalar and exceptional contracts. Record the market type, not just the side.

A title is not an identifier, and listings get replaced

Two markets in the same weather series on different days can share nearly identical titles. Worse, a single market moves through a lifecycle, and the listing you tested against may not be the one you look at later.

Kalshi documents distinct lifecycle statuses: initialized, active, inactive, closed, determined, disputed, amended, and finalized. A disputed result can be re-determined, and an amended market restarts its settlement timer. The API's status filter values (unopened, open, paused, closed, settled) overlap with but are not identical to those underlying states, so treat the filter enum and the lifecycle field as separate things and join on the underlying field.

Close time is also not determination time. A market's close_time marks when trading stops; determination follows only after an official source publishes finalized data. So an artifact that captured a market mid-window is describing a different state than one captured after determination, even for the same ticker.

What to save beside every result

Treat the identity block as mandatory metadata on any backtest or paper record. At minimum:

If any of these is unknown, record it as unknown rather than guessing. Preserving a missing field is honest; backfilling it from a parsed ticker is how two contracts quietly become one.

Where this shows up in Banger

Banger is a paper-research beta for prediction-market strategies, and its hosted historical backtesting currently supports Kalshi binary markets. The package installs with pip install bangertrades, and its public listing describes it as a paper beta. The same identifier discipline applies: pick and preserve an exact current market ticker for a run rather than trusting that "take the first discovery result" will reproduce tomorrow. A strategy's on_market_tick(self, market, tick, ctx) callback sees a specific market object, and your saved artifact should carry that market's full identity chain alongside whatever fill and fee model produced the paper fills. A paper result is evidence under one model, not a venue execution, so the model itself belongs in the record too.

None of this is glamorous. It is bookkeeping. But the difference between a research archive you can trust and a pile of ambiguous numbers is entirely in whether you wrote down which instrument you were actually looking at.

Sources

Keep reading

Run your first strategy free

Paper-trade on Polymarket and Kalshi market data without venue keys.

Start free