Skip to content

Commit 65cc3a5

Browse files
committed
Standardize instruments between Python and Rust
- Fix CryptoPerpetual/Future/Option for multiplier and is_inverse - Fix OKX swap to use lot_sz - Fix OKX option parser to create `CryptoOption` - Fix PyO3 <-> Cython bridges to propagate all fields - Add test coverage with additional field assertions
1 parent 598197c commit 65cc3a5

File tree

20 files changed

+443
-117
lines changed

20 files changed

+443
-117
lines changed

crates/adapters/okx/src/common/parse.rs

Lines changed: 172 additions & 95 deletions
Large diffs are not rendered by default.

crates/adapters/okx/src/websocket/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn extract_fees_from_cached_instrument(
9090
Some(future.maker_fee),
9191
Some(future.taker_fee),
9292
),
93-
InstrumentAny::OptionContract(option) => (
93+
InstrumentAny::CryptoOption(option) => (
9494
Some(option.margin_init),
9595
Some(option.margin_maint),
9696
Some(option.maker_fee),

crates/adapters/okx/test_data/http_get_instruments_swap.json

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
"auctionEndTime": "",
88
"baseCcy": "",
99
"category": "1",
10+
"contTdSwTime": "",
1011
"ctMult": "1",
1112
"ctType": "inverse",
1213
"ctVal": "100",
1314
"ctValCcy": "USD",
1415
"expTime": "",
16+
"futureSettlement": false,
1517
"instFamily": "BTC-USD",
1618
"instId": "BTC-USD-SWAP",
19+
"instIdCode": 10458,
1720
"instType": "SWAP",
1821
"lever": "100",
1922
"listTime": "1535424203000",
@@ -23,18 +26,110 @@
2326
"maxLmtSz": "100000000",
2427
"maxMktAmt": "",
2528
"maxMktSz": "30000",
29+
"maxPlatOILmt": "",
2630
"maxStopSz": "30000",
2731
"maxTriggerSz": "100000000.0000000000000000",
2832
"maxTwapSz": "100000000.0000000000000000",
2933
"minSz": "1",
34+
"openType": "",
3035
"optType": "",
36+
"posLmtAmt": "",
37+
"posLmtPct": "",
38+
"preMktSwTime": "",
3139
"quoteCcy": "",
3240
"ruleType": "normal",
3341
"settleCcy": "BTC",
3442
"state": "live",
3543
"stk": "",
3644
"tickSz": "0.1",
45+
"tradeQuoteCcyList": [],
3746
"uly": "BTC-USD"
47+
},
48+
{
49+
"alias": "",
50+
"auctionEndTime": "",
51+
"baseCcy": "",
52+
"category": "1",
53+
"contTdSwTime": "",
54+
"ctMult": "1",
55+
"ctType": "linear",
56+
"ctVal": "0.1",
57+
"ctValCcy": "ETH",
58+
"expTime": "",
59+
"futureSettlement": false,
60+
"instFamily": "ETH-USDT",
61+
"instId": "ETH-USDT-SWAP",
62+
"instIdCode": 10461,
63+
"instType": "SWAP",
64+
"lever": "100",
65+
"listTime": "1573557408000",
66+
"lotSz": "0.01",
67+
"maxIcebergSz": "100000000.0000000000000000",
68+
"maxLmtAmt": "20000000",
69+
"maxLmtSz": "100000000",
70+
"maxMktAmt": "",
71+
"maxMktSz": "20000",
72+
"maxPlatOILmt": "",
73+
"maxStopSz": "20000",
74+
"maxTriggerSz": "100000000.0000000000000000",
75+
"maxTwapSz": "100000000.0000000000000000",
76+
"minSz": "0.01",
77+
"openType": "",
78+
"optType": "",
79+
"posLmtAmt": "",
80+
"posLmtPct": "",
81+
"preMktSwTime": "",
82+
"quoteCcy": "",
83+
"ruleType": "normal",
84+
"settleCcy": "USDT",
85+
"state": "live",
86+
"stk": "",
87+
"tickSz": "0.01",
88+
"tradeQuoteCcyList": [],
89+
"uly": "ETH-USDT"
90+
},
91+
{
92+
"alias": "",
93+
"auctionEndTime": "",
94+
"baseCcy": "",
95+
"category": "1",
96+
"contTdSwTime": "",
97+
"ctMult": "1",
98+
"ctType": "linear",
99+
"ctVal": "0.01",
100+
"ctValCcy": "BTC",
101+
"expTime": "",
102+
"futureSettlement": false,
103+
"instFamily": "BTC-USDT",
104+
"instId": "BTC-USDT-SWAP",
105+
"instIdCode": 10459,
106+
"instType": "SWAP",
107+
"lever": "100",
108+
"listTime": "1573557408000",
109+
"lotSz": "0.01",
110+
"maxIcebergSz": "100000000.0000000000000000",
111+
"maxLmtAmt": "20000000",
112+
"maxLmtSz": "100000000",
113+
"maxMktAmt": "",
114+
"maxMktSz": "12000",
115+
"maxPlatOILmt": "",
116+
"maxStopSz": "12000",
117+
"maxTriggerSz": "100000000.0000000000000000",
118+
"maxTwapSz": "100000000.0000000000000000",
119+
"minSz": "0.01",
120+
"openType": "",
121+
"optType": "",
122+
"posLmtAmt": "",
123+
"posLmtPct": "",
124+
"preMktSwTime": "",
125+
"quoteCcy": "",
126+
"ruleType": "normal",
127+
"settleCcy": "USDT",
128+
"state": "live",
129+
"stk": "",
130+
"tickSz": "0.1",
131+
"tradeQuoteCcyList": [],
132+
"uly": "BTC-USDT"
38133
}
39134
]
40-
}
135+
}

crates/adapters/tardis/src/http/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ mod tests {
945945
assert_eq!(instrument.base_currency(), Some(Currency::BTC()));
946946
assert_eq!(instrument.quote_currency(), Currency::BTC());
947947
assert_eq!(instrument.settlement_currency(), Currency::BTC());
948-
assert!(!instrument.is_inverse());
948+
assert!(instrument.is_inverse());
949949
assert_eq!(instrument.price_precision(), 4);
950950
assert_eq!(instrument.size_precision(), 1); // from amountIncrement 0.1
951951
assert_eq!(instrument.price_increment(), Price::from("0.0001"));

crates/model/src/instruments/crypto_future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl Instrument for CryptoFuture {
330330
}
331331

332332
fn multiplier(&self) -> Quantity {
333-
Quantity::from(1)
333+
self.multiplier
334334
}
335335

336336
fn lot_size(&self) -> Option<Quantity> {

crates/model/src/instruments/crypto_option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl Instrument for CryptoOption {
312312
}
313313

314314
fn is_inverse(&self) -> bool {
315-
false
315+
self.is_inverse
316316
}
317317

318318
fn isin(&self) -> Option<Ustr> {

crates/model/src/instruments/crypto_perpetual.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl Instrument for CryptoPerpetual {
327327
}
328328

329329
fn multiplier(&self) -> Quantity {
330-
Quantity::from(1)
330+
self.multiplier
331331
}
332332

333333
fn lot_size(&self) -> Option<Quantity> {

crates/model/src/python/account/margin.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,13 @@ impl MarginAccount {
171171
) -> PyResult<Money> {
172172
let instrument_type = pyobject_to_instrument_any(py, instrument)?;
173173
match instrument_type {
174+
InstrumentAny::CryptoPerpetual(inst) => self
175+
.calculate_initial_margin(inst, quantity, price, use_quote_for_inverse)
176+
.map_err(to_pyvalue_err),
174177
InstrumentAny::CryptoFuture(inst) => self
175178
.calculate_initial_margin(inst, quantity, price, use_quote_for_inverse)
176179
.map_err(to_pyvalue_err),
177-
InstrumentAny::CryptoPerpetual(inst) => self
180+
InstrumentAny::CryptoOption(inst) => self
178181
.calculate_initial_margin(inst, quantity, price, use_quote_for_inverse)
179182
.map_err(to_pyvalue_err),
180183
InstrumentAny::CurrencyPair(inst) => self
@@ -217,6 +220,9 @@ impl MarginAccount {
217220
InstrumentAny::CryptoPerpetual(inst) => self
218221
.calculate_maintenance_margin(inst, quantity, price, use_quote_for_inverse)
219222
.map_err(to_pyvalue_err),
223+
InstrumentAny::CryptoOption(inst) => self
224+
.calculate_maintenance_margin(inst, quantity, price, use_quote_for_inverse)
225+
.map_err(to_pyvalue_err),
220226
InstrumentAny::CurrencyPair(inst) => self
221227
.calculate_maintenance_margin(inst, quantity, price, use_quote_for_inverse)
222228
.map_err(to_pyvalue_err),

crates/model/src/python/instruments/equity.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,30 @@ impl Equity {
177177
self.min_price
178178
}
179179

180+
#[getter]
181+
#[pyo3(name = "margin_init")]
182+
fn py_margin_init(&self) -> Decimal {
183+
self.margin_init
184+
}
185+
186+
#[getter]
187+
#[pyo3(name = "margin_maint")]
188+
fn py_margin_maint(&self) -> Decimal {
189+
self.margin_maint
190+
}
191+
192+
#[getter]
193+
#[pyo3(name = "maker_fee")]
194+
fn py_maker_fee(&self) -> Decimal {
195+
self.maker_fee
196+
}
197+
198+
#[getter]
199+
#[pyo3(name = "taker_fee")]
200+
fn py_taker_fee(&self) -> Decimal {
201+
self.taker_fee
202+
}
203+
180204
#[getter]
181205
#[pyo3(name = "ts_event")]
182206
fn py_ts_event(&self) -> u64 {

crates/model/src/python/instruments/futures_contract.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ impl FuturesContract {
239239
self.margin_maint
240240
}
241241

242+
#[getter]
243+
#[pyo3(name = "maker_fee")]
244+
fn py_maker_fee(&self) -> Decimal {
245+
self.maker_fee
246+
}
247+
248+
#[getter]
249+
#[pyo3(name = "taker_fee")]
250+
fn py_taker_fee(&self) -> Decimal {
251+
self.taker_fee
252+
}
253+
242254
#[getter]
243255
#[pyo3(name = "info")]
244256
fn py_info(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {

0 commit comments

Comments
 (0)