Quant Trading for Programmers 28: Abstract Price Inputs Into Price Providers
· 11 min read · Views --
Last updated on

Quant Trading for Programmers 28: Abstract Price Inputs Into Price Providers

Author: Alex Xiang


Quant Trading for Programmers 28: Abstract Price Inputs Into Price Providers

So far, prices in the daily flow have been passed in by the caller as a last_prices dictionary.

That is convenient for tests, but the system boundary is still not clear enough. Article 28 adds a price-source abstraction, separating “which prices are needed” from “where those prices come from.”

A ZiCode engineer connecting a paper-trading price provider

What A Price Provider Solves

Paper trading needs at least two kinds of stock prices:

  • Stocks currently held in the account.
  • Stocks that the target weights plan to buy or keep watching.

If either category is missing, rebalancing and snapshots may both become distorted.

The price here is not tick-by-tick trade data or five-level order-book quotes. It is the “latest usable price” used by the daily flow to estimate account equity and target positions. In a daily-frequency paper-trading system, this can usually be the close price, adjusted close price, or a cleaned latest price. The key is that the definition must stay stable. The system should not use close prices today and accidentally mix in intraday prices tomorrow.

Price Snapshot

Chapter 28 adds app/price_providers.py.

@dataclass(frozen=True)
class PriceSnapshot:
    trade_date: date
    prices: dict[str, float]
    missing_symbols: tuple[str, ...]

Missing prices are placed explicitly in missing_symbols instead of being quietly ignored.

Static Price Provider

provider = StaticPriceProvider({"000001.SZ": 10.0})
snapshot = provider.get_last_prices(["000001.SZ", "600000.SH"], trade_date=today)

The static implementation only exists for tests and article examples. When real market data is connected later, it can implement the same protocol without changing the upper-level structure of the daily flow.

Current Integrated Run

The paper-notify command first merges the symbols from current positions and target weights, then asks StaticPriceProvider for prices:

uv run python -m scripts.chapter_examples paper-notify

Price-provider run result generated by the paper-notify command

This run needs prices for 000001.SZ and 600519.SH, and the static price provider returns both, so missing_symbols=(). If a real price provider misses one stock, later production checks and health reports can expose that problem explicitly.

Chapter Update And Repository

This chapter adds:

  • app/price_providers.py.
  • The PriceProvider protocol and PriceSnapshot.
  • StaticPriceProvider.
  • collect_required_price_symbols(), which merges the prices required by positions and target weights.
  • An integrated paper-notify example showing symbol merging, static price lookup, and missing-price checks.
  • Background on keeping a stable price definition in daily-frequency paper trading.
  • tests/test_price_providers.py, covering price hits, missing prices, and symbol merging.

Repository:

https://github.com/ax2/zi-quant-platform

Code for this chapter:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-28
uv sync --extra dev
uv run pytest tests/test_price_providers.py

Chapter 28 is commit 985e045, tagged as chapter-28.

Summary

Price inputs should not remain scattered across callers forever.

Article 28 extracts the price-provider abstraction and turns missing prices into a checkable state. The next article adds a target-weight policy so the daily flow no longer depends only on handwritten weight dictionaries.