price-handling
Load when comparing, rounding, formatting, or parsing prices, or designing price types.
- License 许可
- MIT
- 最近更新
- 2026-11-13
- Stars
- ★ 93
- Forks
- 37
01 前言 Front Matter
- name
- price-handling
- tags
- [ "data" ]
- license
- MIT
- summary
- f64 price patterns for trading systems: comparing prices, rounding to tick size, formatting for display and broker APIs, parsing market feeds, designing price types.
- metadata
- { "bugs": "https://github.com/vanillagreencom/kendex/issues", "author": "vanillagreen", "source": "kendex", "repository": "https://github.com/vanillagreencom/kendex" }
- description
- Load when comparing, rounding, formatting, or parsing prices, or designing price types.
- user-invocable
- true
02 资源文件 1
- 参考文档README.md793 B
03 SKILL.md 正文
Price Handling Patterns
The price type is f64
IEEE 754 double precision. No fixed-point, no decimal types.
Use i64 fixed-point only for a matching engine (bit-exact required), a regulatory audit trail mandating reproducibility, or a settlement system with legal precision requirements. Hybrid: i64 on the execution hot path, f64 for display and analytics.
Never == on prices
use float_cmp::{approx_eq, F64Margin};
pub const PRICE_EPSILON: f64 = 1e-10; // sub-pipette tolerance
pub fn prices_equal(a: f64, b: f64) -> bool {
approx_eq!(f64, a, b, epsilon = PRICE_EPSILON, ulps = 4)
}
pub fn price_gte(a: f64, b: f64) -> bool { a > b || prices_equal(a, b) }
pub fn price_lte(a: f64, b: f64) -> bool { a < b || prices_equal(a, b) }
Round only at the boundaries
| Boundary | Rounding |
|---|---|
| Order submission (OrderRequest → broker API) | Round to tick, then validate alignment |
| Display formatting | Round to the symbol's display_decimals |
| Market data ingestion (ticks, bars, quotes) | Never. Preserve full feed precision |
| P&L calculation | Never. Use raw values |
pub fn round_to_tick(price: f64, tick_size: f64) -> f64 {
(price / tick_size).round() * tick_size
}
pub fn validate_tick_alignment(price: f64, tick_size: f64) -> bool {
prices_equal(price, round_to_tick(price, tick_size))
}
Order submission order: round to tick, validate alignment (on failure return an error, never re-round), then format for the broker API if it takes a string.
Format with the symbol's precision, never hardcoded decimals (EURUSD 5, AAPL 2, BTC 8):
format!("{:.1$}", price, symbol.display_decimals as usize)
Symbol metadata owns precision
Tick size and display precision belong to the symbol, not to the price value. A Price { value, decimals } struct is the wrong shape.
#[derive(Clone, Copy)]
pub struct SymbolSpec {
pub symbol_id: u32,
pub tick_size: f64, // minimum price increment
pub display_decimals: u8, // decimal places for UI
pub lot_size: f64, // minimum quantity
}
impl SymbolSpec {
pub fn round_price(&self, price: f64) -> f64 {
round_to_tick(price, self.tick_size)
}
pub fn format_price(&self, price: f64) -> String {
format!("{:.1$}", price, self.display_decimals as usize)
}
}
The symbol table loads at subscription setup (cold path), is keyed by symbol ID, and re-syncs on reconnect or symbol list change.
Price newtype
Optional: wrap f64 in a #[repr(transparent)] newtype with PartialOrd but no PartialEq; equality goes through prices_equal. Constructor debug_assert!s is_finite(). Use for order types; skip on the market-data hot path.
Normalize feeds to f64 at ingest
Convert at the entry boundary; downstream code sees plain f64 regardless of feed source.
// doubles (IB, dxFeed, Rithmic): pass through
fn ingest_double(value: f64) -> f64 { value }
// strings (Binance, Coinbase): parse
fn ingest_string(s: &str) -> Result<f64, ParseFloatError> { s.parse() }
// scaled integers (CME MDP): unscale
fn ingest_scaled(mantissa: i64, exponent: i8) -> f64 {
mantissa as f64 * 10f64.powi(exponent as i32)
}
04 同仓库更多 Skills
youtube-publish
Load to draft a YouTube upload, comment or reply, or send a draft after the user's recorded approval.
xcode-run
Load to install or dispatch a macOS GitHub Actions build, test or simulator screenshot run for an Xcode project.
worktree
Load to create, list, remove, push, or repair a git worktree.
social-media-content-calendar
Load to plan a social media campaign, build a content calendar, or adapt existing material into post drafts.
slack
Load to bind an overseer's mailbox to a private Slack channel, run or check the relay, or post an alert or a file to Slack.
second-opinion
Load for a cross-model review, challenge, audit, or quick consult.