Skip to content

Commit

Permalink
Equity pyo3 Rust Cython conversion (#1542)
Browse files Browse the repository at this point in the history
  • Loading branch information
filipmacek authored Mar 15, 2024
1 parent d0b3f37 commit e6d78c9
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 11 deletions.
8 changes: 8 additions & 0 deletions nautilus_core/adapters/src/databento/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ pub fn decode_equity_v1(
currency,
currency.precision,
decode_price(msg.min_price_increment, currency.precision)?,
None, // TBD
None, // TBD
None, // TBD
None, // TBD
Some(Quantity::new(msg.min_lot_size_round_lot.into(), 0)?),
None, // TBD
None, // TBD
Expand Down Expand Up @@ -743,6 +747,10 @@ pub fn decode_equity(
currency,
currency.precision,
decode_price(msg.min_price_increment, currency.precision)?,
None, // TBD
None, // TBD
None, // TBD
None, // TBD
Some(Quantity::new(msg.min_lot_size_round_lot.into(), 0)?),
None, // TBD
None, // TBD
Expand Down
13 changes: 13 additions & 0 deletions nautilus_core/model/src/instruments/equity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::{

use anyhow::Result;
use nautilus_core::time::UnixNanos;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use ustr::Ustr;

Expand All @@ -45,6 +46,10 @@ pub struct Equity {
pub currency: Currency,
pub price_precision: u8,
pub price_increment: Price,
pub maker_fee: Decimal,
pub taker_fee: Decimal,
pub margin_init: Decimal,
pub margin_maint: Decimal,
pub lot_size: Option<Quantity>,
pub max_quantity: Option<Quantity>,
pub min_quantity: Option<Quantity>,
Expand All @@ -63,6 +68,10 @@ impl Equity {
currency: Currency,
price_precision: u8,
price_increment: Price,
maker_fee: Option<Decimal>,
taker_fee: Option<Decimal>,
margin_init: Option<Decimal>,
margin_maint: Option<Decimal>,
lot_size: Option<Quantity>,
max_quantity: Option<Quantity>,
min_quantity: Option<Quantity>,
Expand All @@ -78,6 +87,10 @@ impl Equity {
currency,
price_precision,
price_increment,
maker_fee: maker_fee.unwrap_or(0.into()),
taker_fee: taker_fee.unwrap_or(0.into()),
margin_init: margin_init.unwrap_or(0.into()),
margin_maint: margin_maint.unwrap_or(0.into()),
lot_size,
max_quantity,
min_quantity,
Expand Down
6 changes: 5 additions & 1 deletion nautilus_core/model/src/instruments/stubs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,11 @@ pub fn equity_aapl() -> Equity {
Currency::from("USD"),
2,
Price::from("0.01"),
Some(Quantity::from(1)),
None,
None,
None,
None,
None,
None,
None,
None,
Expand Down
13 changes: 13 additions & 0 deletions nautilus_core/model/src/python/instruments/equity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use nautilus_core::{
time::UnixNanos,
};
use pyo3::{basic::CompareOp, prelude::*, types::PyDict};
use rust_decimal::Decimal;
use ustr::Ustr;

use crate::{
Expand All @@ -43,6 +44,10 @@ impl Equity {
price_increment: Price,
ts_event: UnixNanos,
ts_init: UnixNanos,
maker_fee: Option<Decimal>,
taker_fee: Option<Decimal>,
margin_init: Option<Decimal>,
margin_maint: Option<Decimal>,
isin: Option<String>,
lot_size: Option<Quantity>,
max_quantity: Option<Quantity>,
Expand All @@ -57,6 +62,10 @@ impl Equity {
currency,
price_precision,
price_increment,
maker_fee,
taker_fee,
margin_init,
margin_maint,
lot_size,
max_quantity,
min_quantity,
Expand Down Expand Up @@ -185,6 +194,10 @@ impl Equity {
dict.set_item("price_increment", self.price_increment.to_string())?;
dict.set_item("ts_event", self.ts_event)?;
dict.set_item("ts_init", self.ts_init)?;
dict.set_item("maker_fee", self.maker_fee.to_string())?;
dict.set_item("taker_fee", self.taker_fee.to_string())?;
dict.set_item("margin_init", self.margin_init.to_string())?;
dict.set_item("margin_maint", self.margin_maint.to_string())?;
match &self.isin {
Some(value) => dict.set_item("isin", value.to_string())?,
None => dict.set_item("isin", py.None())?,
Expand Down
2 changes: 2 additions & 0 deletions nautilus_trader/core/nautilus_pyo3.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,8 @@ class Equity:
max_price: Price | None = None,
min_price: Price | None = None,
) -> None: ...
@classmethod
def from_dict(cls, values: dict[str, str]) -> Equity: ...
@property
def id(self) -> InstrumentId: ...
@property
Expand Down
18 changes: 12 additions & 6 deletions nautilus_trader/model/instruments/equity.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ cdef class Equity(Instrument):
margin_maint: Decimal | None = None,
maker_fee: Decimal | None = None,
taker_fee: Decimal | None = None,
max_quantity: Quantity | None = None,
min_quantity: Quantity | None = None,
dict info = None,
):
if isin is not None:
Expand All @@ -108,8 +110,8 @@ cdef class Equity(Instrument):
size_increment=Quantity.from_int_c(1),
multiplier=Quantity.from_int_c(1),
lot_size=lot_size,
max_quantity=None,
min_quantity=Quantity.from_int_c(1),
max_quantity=max_quantity,
min_quantity=min_quantity,
max_notional=None,
min_notional=None,
max_price=None,
Expand All @@ -135,10 +137,10 @@ cdef class Equity(Instrument):
price_increment=Price.from_str(values["price_increment"]),
lot_size=Quantity.from_str(values["lot_size"]),
isin=values.get("isin"), # Can be None,
margin_init=Decimal(values.get("margin_init", 0)), # Can be None,
margin_maint=Decimal(values.get("margin_maint", 0)), # Can be None,
maker_fee=Decimal(values.get("maker_fee", 0)), # Can be None,
taker_fee=Decimal(values.get("taker_fee", 0)), # Can be None,
margin_init=Decimal(values.get("margin_init", 0)) if values.get("margin_init") is not None else None,
margin_maint=Decimal(values.get("margin_maint", 0)) if values.get("margin_maint") is not None else None,
maker_fee=Decimal(values.get("maker_fee", 0)) if values.get("maker_fee") is not None else None,
taker_fee=Decimal(values.get("taker_fee", 0)) if values.get("taker_fee") is not None else None,
ts_event=values["ts_event"],
ts_init=values["ts_init"],
)
Expand All @@ -159,6 +161,10 @@ cdef class Equity(Instrument):
"margin_maint": str(obj.margin_maint),
"maker_fee": str(obj.maker_fee),
"taker_fee": str(obj.taker_fee),
"min_price": str(obj.min_price) if obj.min_price is not None else None,
"max_price": str(obj.max_price) if obj.max_price is not None else None,
"max_quantity": str(obj.max_quantity) if obj.max_quantity is not None else None,
"min_quantity": str(obj.min_quantity) if obj.min_quantity is not None else None,
"ts_event": obj.ts_event,
"ts_init": obj.ts_init,
}
Expand Down
22 changes: 18 additions & 4 deletions tests/unit_tests/model/instruments/test_equity_pyo3.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
# limitations under the License.
# -------------------------------------------------------------------------------------------------

from nautilus_trader.core.nautilus_pyo3 import Equity
from nautilus_trader.core import nautilus_pyo3
from nautilus_trader.core.nautilus_pyo3 import InstrumentId
from nautilus_trader.model.instruments import Equity as LegacyEquity
from nautilus_trader.model.instruments import Equity
from nautilus_trader.test_kit.rust.instruments_pyo3 import TestInstrumentProviderPyo3


Expand All @@ -38,7 +38,7 @@ def test_hash():

def test_to_dict():
result = _AAPL_EQUITY.to_dict()
assert Equity.from_dict(result) == _AAPL_EQUITY
assert nautilus_pyo3.Equity.from_dict(result) == _AAPL_EQUITY
assert result == {
"type": "Equity",
"id": "AAPL.XNAS",
Expand All @@ -47,6 +47,10 @@ def test_to_dict():
"currency": "USD",
"price_precision": 2,
"price_increment": "0.01",
"maker_fee": "0",
"taker_fee": "0",
"margin_init": "0",
"margin_maint": "0",
"lot_size": "100",
"max_quantity": None,
"min_quantity": None,
Expand All @@ -58,6 +62,16 @@ def test_to_dict():


def test_legacy_equity_from_pyo3():
equity = LegacyEquity.from_pyo3(_AAPL_EQUITY)
equity = Equity.from_pyo3(_AAPL_EQUITY)

assert equity.id.value == "AAPL.XNAS"


def test_pyo3_cython_conversion():
equity_pyo3 = TestInstrumentProviderPyo3.aapl_equity()
equity_pyo3_dict = equity_pyo3.to_dict()
equity_cython = Equity.from_pyo3(equity_pyo3)
equity_cython_dict = Equity.to_dict(equity_cython)
equity_pyo3_back = nautilus_pyo3.Equity.from_dict(equity_cython_dict)
assert equity_cython_dict == equity_pyo3_dict
assert equity_pyo3 == equity_pyo3_back
4 changes: 4 additions & 0 deletions tests/unit_tests/model/test_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ def test_equity_instrument_to_dict(self):
"price_precision": 2,
"price_increment": "0.01",
"lot_size": "100",
"max_price": None,
"max_quantity": None,
"min_price": None,
"min_quantity": None,
"isin": "US0378331005",
"margin_init": "0",
"margin_maint": "0",
Expand Down

0 comments on commit e6d78c9

Please sign in to comment.