diff --git a/nightly/.doctrees/api_reference/accounting.doctree b/nightly/.doctrees/api_reference/accounting.doctree index bcde03fa666e..cde405da138f 100644 Binary files a/nightly/.doctrees/api_reference/accounting.doctree and b/nightly/.doctrees/api_reference/accounting.doctree differ diff --git a/nightly/.doctrees/api_reference/adapters/betfair.doctree b/nightly/.doctrees/api_reference/adapters/betfair.doctree index 7068ada87aac..980943a91e75 100644 Binary files a/nightly/.doctrees/api_reference/adapters/betfair.doctree and b/nightly/.doctrees/api_reference/adapters/betfair.doctree differ diff --git a/nightly/.doctrees/api_reference/adapters/binance.doctree b/nightly/.doctrees/api_reference/adapters/binance.doctree index 0efe9c2dce92..2b65418c3e10 100644 Binary files a/nightly/.doctrees/api_reference/adapters/binance.doctree and b/nightly/.doctrees/api_reference/adapters/binance.doctree differ diff --git a/nightly/.doctrees/api_reference/adapters/interactive_brokers.doctree b/nightly/.doctrees/api_reference/adapters/interactive_brokers.doctree index 4f404ba1134d..1003ceaa4cb5 100644 Binary files a/nightly/.doctrees/api_reference/adapters/interactive_brokers.doctree and b/nightly/.doctrees/api_reference/adapters/interactive_brokers.doctree differ diff --git a/nightly/.doctrees/api_reference/analysis.doctree b/nightly/.doctrees/api_reference/analysis.doctree index c1f717cc13ec..f31bae0596d0 100644 Binary files a/nightly/.doctrees/api_reference/analysis.doctree and b/nightly/.doctrees/api_reference/analysis.doctree differ diff --git a/nightly/.doctrees/api_reference/backtest.doctree b/nightly/.doctrees/api_reference/backtest.doctree index 18faabaec7a6..e0e15cfd5d83 100644 Binary files a/nightly/.doctrees/api_reference/backtest.doctree and b/nightly/.doctrees/api_reference/backtest.doctree differ diff --git a/nightly/.doctrees/api_reference/cache.doctree b/nightly/.doctrees/api_reference/cache.doctree index eb7e174f6018..7db5d1321ab7 100644 Binary files a/nightly/.doctrees/api_reference/cache.doctree and b/nightly/.doctrees/api_reference/cache.doctree differ diff --git a/nightly/.doctrees/api_reference/common.doctree b/nightly/.doctrees/api_reference/common.doctree index bf3699519193..33171e84af2a 100644 Binary files a/nightly/.doctrees/api_reference/common.doctree and b/nightly/.doctrees/api_reference/common.doctree differ diff --git a/nightly/.doctrees/api_reference/core.doctree b/nightly/.doctrees/api_reference/core.doctree index b79b4fb9ed1f..617bdb05198f 100644 Binary files a/nightly/.doctrees/api_reference/core.doctree and b/nightly/.doctrees/api_reference/core.doctree differ diff --git a/nightly/.doctrees/api_reference/data.doctree b/nightly/.doctrees/api_reference/data.doctree index 1e767c870bdf..73a507910c1c 100644 Binary files a/nightly/.doctrees/api_reference/data.doctree and b/nightly/.doctrees/api_reference/data.doctree differ diff --git a/nightly/.doctrees/api_reference/execution.doctree b/nightly/.doctrees/api_reference/execution.doctree index fd5271b397f1..227310555ae5 100644 Binary files a/nightly/.doctrees/api_reference/execution.doctree and b/nightly/.doctrees/api_reference/execution.doctree differ diff --git a/nightly/.doctrees/api_reference/indicators.doctree b/nightly/.doctrees/api_reference/indicators.doctree index c2a1331aa29e..3f87f9ddba0d 100644 Binary files a/nightly/.doctrees/api_reference/indicators.doctree and b/nightly/.doctrees/api_reference/indicators.doctree differ diff --git a/nightly/.doctrees/api_reference/live.doctree b/nightly/.doctrees/api_reference/live.doctree index b5dd37ef20f7..310c2f00328e 100644 Binary files a/nightly/.doctrees/api_reference/live.doctree and b/nightly/.doctrees/api_reference/live.doctree differ diff --git a/nightly/.doctrees/api_reference/model/book.doctree b/nightly/.doctrees/api_reference/model/book.doctree index c40c5fcf3aaa..7ea79cff97af 100644 Binary files a/nightly/.doctrees/api_reference/model/book.doctree and b/nightly/.doctrees/api_reference/model/book.doctree differ diff --git a/nightly/.doctrees/api_reference/model/data.doctree b/nightly/.doctrees/api_reference/model/data.doctree index 5638d94f9c21..df878d6ec923 100644 Binary files a/nightly/.doctrees/api_reference/model/data.doctree and b/nightly/.doctrees/api_reference/model/data.doctree differ diff --git a/nightly/.doctrees/api_reference/model/events.doctree b/nightly/.doctrees/api_reference/model/events.doctree index 345d9e1a60a1..b36cd36071e1 100644 Binary files a/nightly/.doctrees/api_reference/model/events.doctree and b/nightly/.doctrees/api_reference/model/events.doctree differ diff --git a/nightly/.doctrees/api_reference/model/identifiers.doctree b/nightly/.doctrees/api_reference/model/identifiers.doctree index 3609a1330809..6a5872770d7f 100644 Binary files a/nightly/.doctrees/api_reference/model/identifiers.doctree and b/nightly/.doctrees/api_reference/model/identifiers.doctree differ diff --git a/nightly/.doctrees/api_reference/model/instruments.doctree b/nightly/.doctrees/api_reference/model/instruments.doctree index bc2bf19ff54d..b271e40f0749 100644 Binary files a/nightly/.doctrees/api_reference/model/instruments.doctree and b/nightly/.doctrees/api_reference/model/instruments.doctree differ diff --git a/nightly/.doctrees/api_reference/model/objects.doctree b/nightly/.doctrees/api_reference/model/objects.doctree index 657c24c4d748..e3d8a27455fb 100644 Binary files a/nightly/.doctrees/api_reference/model/objects.doctree and b/nightly/.doctrees/api_reference/model/objects.doctree differ diff --git a/nightly/.doctrees/api_reference/model/orders.doctree b/nightly/.doctrees/api_reference/model/orders.doctree index d8accd9dfca4..3c5e819e9343 100644 Binary files a/nightly/.doctrees/api_reference/model/orders.doctree and b/nightly/.doctrees/api_reference/model/orders.doctree differ diff --git a/nightly/.doctrees/api_reference/model/position.doctree b/nightly/.doctrees/api_reference/model/position.doctree index 682e4a01f463..e4cca64f520e 100644 Binary files a/nightly/.doctrees/api_reference/model/position.doctree and b/nightly/.doctrees/api_reference/model/position.doctree differ diff --git a/nightly/.doctrees/api_reference/model/tick_scheme.doctree b/nightly/.doctrees/api_reference/model/tick_scheme.doctree index fff82b092a84..9139e3a3b0ec 100644 Binary files a/nightly/.doctrees/api_reference/model/tick_scheme.doctree and b/nightly/.doctrees/api_reference/model/tick_scheme.doctree differ diff --git a/nightly/.doctrees/api_reference/persistence.doctree b/nightly/.doctrees/api_reference/persistence.doctree index bde1fcadf2ec..0f10e3c4f5fe 100644 Binary files a/nightly/.doctrees/api_reference/persistence.doctree and b/nightly/.doctrees/api_reference/persistence.doctree differ diff --git a/nightly/.doctrees/api_reference/portfolio.doctree b/nightly/.doctrees/api_reference/portfolio.doctree index ecd9d179ca9d..5aaf2e9e080a 100644 Binary files a/nightly/.doctrees/api_reference/portfolio.doctree and b/nightly/.doctrees/api_reference/portfolio.doctree differ diff --git a/nightly/.doctrees/api_reference/risk.doctree b/nightly/.doctrees/api_reference/risk.doctree index 42383fcbda95..8740ce68aa64 100644 Binary files a/nightly/.doctrees/api_reference/risk.doctree and b/nightly/.doctrees/api_reference/risk.doctree differ diff --git a/nightly/.doctrees/api_reference/serialization.doctree b/nightly/.doctrees/api_reference/serialization.doctree index be93ac20fc35..ccefc9626d44 100644 Binary files a/nightly/.doctrees/api_reference/serialization.doctree and b/nightly/.doctrees/api_reference/serialization.doctree differ diff --git a/nightly/.doctrees/api_reference/system.doctree b/nightly/.doctrees/api_reference/system.doctree index 50752d25f55c..642230c250bb 100644 Binary files a/nightly/.doctrees/api_reference/system.doctree and b/nightly/.doctrees/api_reference/system.doctree differ diff --git a/nightly/.doctrees/api_reference/trading.doctree b/nightly/.doctrees/api_reference/trading.doctree index ed48939b0bc1..ef4c9bbd3753 100644 Binary files a/nightly/.doctrees/api_reference/trading.doctree and b/nightly/.doctrees/api_reference/trading.doctree differ diff --git a/nightly/.doctrees/environment.pickle b/nightly/.doctrees/environment.pickle index 0b8271721031..5e61c2462d69 100644 Binary files a/nightly/.doctrees/environment.pickle and b/nightly/.doctrees/environment.pickle differ diff --git a/nightly/api_reference/adapters/interactive_brokers.html b/nightly/api_reference/adapters/interactive_brokers.html index 69277b3c46c3..4c76da7d385e 100644 --- a/nightly/api_reference/adapters/interactive_brokers.html +++ b/nightly/api_reference/adapters/interactive_brokers.html @@ -12085,7 +12085,7 @@

at - 0x7f47ddcba2d0> + 0x7fe0bd946bd0> = diff --git a/nightly/api_reference/backtest.html b/nightly/api_reference/backtest.html index bfb0ccb8eff5..b4a6a52370ec 100644 --- a/nightly/api_reference/backtest.html +++ b/nightly/api_reference/backtest.html @@ -24818,9 +24818,6 @@

, - - OrderBookDeltas - deltas @@ -24850,7 +24847,7 @@

Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -24859,6 +24856,16 @@

. +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

@@ -24878,6 +24885,12 @@

OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

@@ -27212,9 +27225,6 @@

, - - OrderBookDeltas - deltas @@ -27259,6 +27269,12 @@

OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

@@ -32322,6 +32338,17 @@

+ , + + + + bool + + + pyo3_conversion=False + + + ) @@ -32474,6 +32501,32 @@

) – If an order book should be managed by the data engine based on the subscribed feed.

+
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • @@ -36297,9 +36350,6 @@

    , - - OrderBookDeltas - deltas @@ -36329,7 +36379,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -36338,6 +36388,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -36357,6 +36417,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -38665,9 +38731,6 @@

    , - - OrderBookDeltas - deltas @@ -38712,6 +38775,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -43758,6 +43827,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -43910,6 +43990,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

    +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • diff --git a/nightly/api_reference/common.html b/nightly/api_reference/common.html index fad3553ab814..cff9c1913273 100644 --- a/nightly/api_reference/common.html +++ b/nightly/api_reference/common.html @@ -3012,6 +3012,15 @@ +
  • + + + + deregister_component_clock() + + + +
  • @@ -3102,6 +3111,24 @@
  • +
  • + + + + register_component_clock() + + + +
  • +
  • + + + + remove_instance_component_clocks() + + + +
  • @@ -5689,9 +5716,6 @@

    , - - OrderBookDeltas - deltas @@ -5721,7 +5745,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -5730,6 +5754,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -5749,6 +5783,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -8006,9 +8046,6 @@

    , - - OrderBookDeltas - deltas @@ -8053,6 +8090,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -12949,6 +12992,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -13101,6 +13155,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

  • +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • @@ -26175,6 +26255,57 @@

    +
    +
    + + + deregister_component_clock + + + + ( + + + + + UUID4 + + + instance_id + + + + , + + + + Clock + + + clock + + + + + ) + + + + → + + + + void + + + + + ¶ + +
    +
    +
    +
    @@ -27048,6 +27179,97 @@

    +
    +
    + + + register_component_clock + + + + ( + + + + + UUID4 + + + instance_id + + + + , + + + + Clock + + + clock + + + + + ) + + + + → + + + + void + + + + + ¶ + +
    +
    +
    +
    +
    +
    + + + remove_instance_component_clocks + + + + ( + + + + + UUID4 + + + instance_id + + + + + ) + + + + → + + + + void + + + + + ¶ + +
    +
    +
    +
    diff --git a/nightly/api_reference/execution.html b/nightly/api_reference/execution.html index 68596163bff4..546341273c7b 100644 --- a/nightly/api_reference/execution.html +++ b/nightly/api_reference/execution.html @@ -7664,9 +7664,6 @@

    , - - OrderBookDeltas - deltas @@ -7696,7 +7693,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -7705,6 +7702,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -7724,6 +7731,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -10728,9 +10741,6 @@

    , - - OrderBookDeltas - deltas @@ -10775,6 +10785,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -19030,6 +19046,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -19182,6 +19209,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

    +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • @@ -28165,9 +28218,6 @@

    , - - OrderBookDeltas - deltas @@ -28197,7 +28247,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -28206,6 +28256,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -28225,6 +28285,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -30464,9 +30530,6 @@

    , - - OrderBookDeltas - deltas @@ -30511,6 +30574,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -35289,6 +35358,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -35441,6 +35521,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

    +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • diff --git a/nightly/api_reference/model/data.html b/nightly/api_reference/model/data.html index c3ac4ef49f1c..378b5e5fae02 100644 --- a/nightly/api_reference/model/data.html +++ b/nightly/api_reference/model/data.html @@ -1839,6 +1839,15 @@ +
  • + + + + OrderBookDeltas.to_pyo3() + + + +
  • @@ -11120,6 +11129,33 @@

    +
    +
    + + + to_pyo3 + + + + ( + + + + + self + + + + + ) + + + ¶ + +
    +
    +
    +
    diff --git a/nightly/api_reference/trading.html b/nightly/api_reference/trading.html index 20169dc7af15..ff9c25d2fbd5 100644 --- a/nightly/api_reference/trading.html +++ b/nightly/api_reference/trading.html @@ -3460,6 +3460,15 @@ @@ -6755,9 +6764,6 @@

    , - - OrderBookDeltas - deltas @@ -6787,7 +6793,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -6796,6 +6802,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -6815,6 +6831,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -9072,9 +9094,6 @@

    , - - OrderBookDeltas - deltas @@ -9119,6 +9138,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -14015,6 +14040,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -14167,6 +14203,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

  • +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • @@ -21442,9 +21504,6 @@

    , - - OrderBookDeltas - deltas @@ -21474,7 +21533,7 @@

    Passes to - on_order_book_delta + on_order_book_deltas if state is @@ -21483,6 +21542,16 @@

    . +The + + deltas + + will be + + nautilus_pyo3.OrderBookDeltas + + if the +pyo3_conversion flag was set for the subscription.

    @@ -21502,6 +21571,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -24251,9 +24326,6 @@

    , - - OrderBookDeltas - deltas @@ -24298,6 +24370,12 @@

    OrderBookDeltas + + or + + + nautilus_pyo3.OrderBookDeltas + ) – The order book deltas received.

    @@ -31559,6 +31637,17 @@

    + , + + + + bool + + + pyo3_conversion=False + + + ) @@ -31711,6 +31800,32 @@

    ) – If an order book should be managed by the data engine based on the subscribed feed.

    +
  • +

    + + pyo3_conversion + + ( + + bool + + + , + + + default False + + ) – If received deltas should be converted to + + nautilus_pyo3.OrderBookDeltas + + prior to being passed to the + + on_order_book_deltas + + handler. +

    +
  • @@ -33862,6 +33977,28 @@

    , + + + + instance_id + + + + + : + + + + + + + + UUID4 + + + + + , @@ -34140,6 +34277,20 @@

    ) – The ID for the trader.

    +
  • +

    + + instance_id + + ( + + + UUID4 + + + ) – The instance ID for the trader. +

    +
  • @@ -34349,6 +34500,59 @@

    +
    +
    + + + property + + + + + + + instance_id + + + + + + : + + + + + + + UUID4 + + + + + ¶ + +
    +
    +

    + Return the traders instance ID. +

    +
    +
    + Returns + + : + +
    +
    +

    + + UUID4 + +

    +
    +
    +
    +
    diff --git a/nightly/core/drop_db/all.html b/nightly/core/drop_db/all.html index 2284965cfd8d..cc193a1e9646 100644 --- a/nightly/core/drop_db/all.html +++ b/nightly/core/drop_db/all.html @@ -1,2 +1,2 @@ -List of all items in this crate +List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file diff --git a/nightly/core/drop_db/fn.main.html b/nightly/core/drop_db/fn.main.html index ebce7d601bf4..87bef6c52cad 100644 --- a/nightly/core/drop_db/fn.main.html +++ b/nightly/core/drop_db/fn.main.html @@ -1,2 +1,2 @@ -main in drop_db - Rust +main in drop_db - Rust

    Function drop_db::main

    source ·
    pub(crate) fn main() -> Result<(), Box<dyn Error>>
    \ No newline at end of file diff --git a/nightly/core/drop_db/index.html b/nightly/core/drop_db/index.html index 9fc46269fb83..be1bf83719f7 100644 --- a/nightly/core/drop_db/index.html +++ b/nightly/core/drop_db/index.html @@ -1,3 +1,3 @@ -drop_db - Rust

  • \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/cash/index.html b/nightly/core/nautilus_accounting/account/cash/index.html index 831cc0558ac7..cbe364e62464 100644 --- a/nightly/core/nautilus_accounting/account/cash/index.html +++ b/nightly/core/nautilus_accounting/account/cash/index.html @@ -1,2 +1,2 @@ -nautilus_accounting::account::cash - Rust -
    \ No newline at end of file +nautilus_accounting::account::cash - Rust +
    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/cash/struct.CashAccount.html b/nightly/core/nautilus_accounting/account/cash/struct.CashAccount.html index d6f0d15af8a8..1bf984a81d9c 100644 --- a/nightly/core/nautilus_accounting/account/cash/struct.CashAccount.html +++ b/nightly/core/nautilus_accounting/account/cash/struct.CashAccount.html @@ -1,51 +1,51 @@ -CashAccount in nautilus_accounting::account::cash - Rust +CashAccount in nautilus_accounting::account::cash - Rust
    pub struct CashAccount {
         pub base: BaseAccount,
    -}

    Fields§

    §base: BaseAccount

    Implementations§

    source§

    impl CashAccount

    source

    pub fn new(event: AccountState, calculate_account_state: bool) -> Result<Self>

    source

    pub fn is_cash_account(&self) -> bool

    source

    pub fn is_margin_account(&self) -> bool

    source

    pub fn is_unleveraged(&self) -> bool

    source§

    impl CashAccount

    source

    pub fn py_new( - event: AccountState, +}

    Fields§

    §base: BaseAccount

    Implementations§

    source§

    impl CashAccount

    source

    pub fn new(event: AccountState, calculate_account_state: bool) -> Result<Self>

    source

    pub fn is_cash_account(&self) -> bool

    source

    pub fn is_margin_account(&self) -> bool

    source

    pub fn is_unleveraged(&self) -> bool

    source§

    impl CashAccount

    source

    pub fn py_new( + event: AccountState, calculate_account_state: bool -) -> PyResult<Self>

    Methods from Deref<Target = BaseAccount>§

    Methods from Deref<Target = BaseAccount>§

    source

    pub fn base_balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_total(&self) -> HashMap<Currency, Money>

    source

    pub fn base_balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_free(&self) -> HashMap<Currency, Money>

    source

    pub fn base_balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_locked(&self) -> HashMap<Currency, Money>

    source

    pub fn base_last_event(&self) -> Option<AccountState>

    source

    pub fn update_balances(&mut self, balances: Vec<AccountBalance>)

    source

    pub fn base_apply(&mut self, event: AccountState)

    source

    pub fn base_calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source

    pub fn base_calculate_pnls<T: Instrument>( +) -> Result<Money>

    source

    pub fn base_calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> -) -> Result<Vec<Money>>

    source

    pub fn base_calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> +) -> Result<Vec<Money>>

    source

    pub fn base_calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    Trait Implementations§

    source§

    impl Account for CashAccount

    Trait Implementations§

    source§

    impl Account for CashAccount

    source§

    fn balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_total(&self) -> HashMap<Currency, Money>

    source§

    fn balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_free(&self) -> HashMap<Currency, Money>

    source§

    fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_locked(&self) -> HashMap<Currency, Money>

    source§

    fn last_event(&self) -> Option<AccountState>

    source§

    fn events(&self) -> Vec<AccountState>

    source§

    fn event_count(&self) -> usize

    source§

    fn currencies(&self) -> Vec<Currency>

    source§

    fn starting_balances(&self) -> HashMap<Currency, Money>

    source§

    fn balances(&self) -> HashMap<Currency, AccountBalance>

    source§

    fn apply(&mut self, event: AccountState)

    source§

    fn calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source§

    fn calculate_pnls<T: Instrument>( +) -> Result<Money>

    source§

    fn calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> -) -> Result<Vec<Money>>

    source§

    fn calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> +) -> Result<Vec<Money>>

    source§

    fn calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source§

    impl Debug for CashAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for CashAccount

    §

    type Target = BaseAccount

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl DerefMut for CashAccount

    source§

    fn deref_mut(&mut self) -> &mut Self::Target

    Mutably dereferences the value.
    source§

    impl Display for CashAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl IntoPy<Py<PyAny>> for CashAccount

    source§

    fn into_py(self, py: Python<'_>) -> PyObject

    Performs the conversion.
    source§

    impl PartialEq for CashAccount

    source§

    fn eq(&self, other: &Self) -> bool

    This method tests for self and other values to be equal, and is used +) -> Result<Money>

    source§

    impl Debug for CashAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for CashAccount

    §

    type Target = BaseAccount

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl DerefMut for CashAccount

    source§

    fn deref_mut(&mut self) -> &mut Self::Target

    Mutably dereferences the value.
    source§

    impl Display for CashAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl IntoPy<Py<PyAny>> for CashAccount

    source§

    fn into_py(self, py: Python<'_>) -> PyObject

    Performs the conversion.
    source§

    impl PartialEq for CashAccount

    source§

    fn eq(&self, other: &Self) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl PyClass for CashAccount

    §

    type Frozen = False

    Whether the pyclass is frozen. Read more
    source§

    impl PyClassImpl for CashAccount

    source§

    const IS_BASETYPE: bool = false

    #[pyclass(subclass)]
    source§

    const IS_SUBCLASS: bool = false

    #[pyclass(extends=…)]
    source§

    const IS_MAPPING: bool = false

    #[pyclass(mapping)]
    source§

    const IS_SEQUENCE: bool = false

    #[pyclass(sequence)]
    §

    type BaseType = PyAny

    Base class
    §

    type ThreadChecker = SendablePyClass<CashAccount>

    This handles following two situations: Read more
    §

    type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild

    Immutable or mutable
    §

    type Dict = PyClassDummySlot

    Specify this class has #[pyclass(dict)] or not.
    §

    type WeakRef = PyClassDummySlot

    Specify this class has #[pyclass(weakref)] or not.
    §

    type BaseNativeType = PyAny

    The closest native ancestor. This is PyAny by default, and when you declare -#[pyclass(extends=PyDict)], it’s PyDict.
    source§

    fn items_iter() -> PyClassItemsIter

    source§

    fn doc(py: Python<'_>) -> PyResult<&'static CStr>

    Rendered class doc
    source§

    fn lazy_type_object() -> &'static LazyTypeObject<Self>

    §

    fn dict_offset() -> Option<isize>

    §

    fn weaklist_offset() -> Option<isize>

    source§

    impl PyClassNewTextSignature<CashAccount> for PyClassImplCollector<CashAccount>

    source§

    fn new_text_signature(self) -> Option<&'static str>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a CashAccount

    §

    type Holder = Option<PyRef<'py, CashAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a mut CashAccount

    §

    type Holder = Option<PyRefMut<'py, CashAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl PyMethods<CashAccount> for PyClassImplCollector<CashAccount>

    source§

    fn py_methods(self) -> &'static PyClassItems

    source§

    impl PyTypeInfo for CashAccount

    §

    type AsRefTarget = PyCell<CashAccount>

    Utility type to make Py::as_ref work.
    source§

    const NAME: &'static str = "CashAccount"

    Class name.
    source§

    const MODULE: Option<&'static str> = _

    Module name, if any.
    source§

    fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject

    Returns the PyTypeObject instance for this type.
    §

    fn type_object(py: Python<'_>) -> &PyType

    Returns the safe abstraction over the type object.
    §

    fn is_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type or a subclass of this type.
    §

    fn is_exact_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type.
    source§

    impl Eq for CashAccount

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +#[pyclass(extends=PyDict)], it’s PyDict.

    source§

    fn items_iter() -> PyClassItemsIter

    source§

    fn doc(py: Python<'_>) -> PyResult<&'static CStr>

    Rendered class doc
    source§

    fn lazy_type_object() -> &'static LazyTypeObject<Self>

    §

    fn dict_offset() -> Option<isize>

    §

    fn weaklist_offset() -> Option<isize>

    source§

    impl PyClassNewTextSignature<CashAccount> for PyClassImplCollector<CashAccount>

    source§

    fn new_text_signature(self) -> Option<&'static str>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a CashAccount

    §

    type Holder = Option<PyRef<'py, CashAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a mut CashAccount

    §

    type Holder = Option<PyRefMut<'py, CashAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl PyMethods<CashAccount> for PyClassImplCollector<CashAccount>

    source§

    fn py_methods(self) -> &'static PyClassItems

    source§

    impl PyTypeInfo for CashAccount

    §

    type AsRefTarget = PyCell<CashAccount>

    Utility type to make Py::as_ref work.
    source§

    const NAME: &'static str = "CashAccount"

    Class name.
    source§

    const MODULE: Option<&'static str> = _

    Module name, if any.
    source§

    fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject

    Returns the PyTypeObject instance for this type.
    §

    fn type_object(py: Python<'_>) -> &PyType

    Returns the safe abstraction over the type object.
    §

    fn is_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type or a subclass of this type.
    §

    fn is_exact_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type.
    source§

    impl Eq for CashAccount

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    §

    impl<Q, K> Equivalent<K> for Q
    where @@ -61,6 +61,6 @@ T: IntoPy<Py<PyAny>> + Send + Sync,

    §

    fn arguments(self, py: Python<'_>) -> Py<PyAny>

    Arguments for exception
    source§

    impl<T> Separable for T
    where T: Display,

    source§

    fn separate_by_policy(&self, policy: SeparatorPolicy<'_>) -> String

    Adds separators according to the given SeparatorPolicy. Read more
    source§

    fn separate_with_commas(&self) -> String

    Inserts a comma every three digits from the right. Read more
    source§

    fn separate_with_spaces(&self) -> String

    Inserts a space every three digits from the right. Read more
    source§

    fn separate_with_dots(&self) -> String

    Inserts a period every three digits from the right. Read more
    source§

    fn separate_with_underscores(&self) -> String

    Inserts an underscore every three digits from the right. Read more
    source§

    impl<T> ToString for T
    where T: Display + ?Sized,

    source§

    default fn to_string(&self) -> String

    Converts the given value to a String. Read more
    source§

    impl<T, U> TryFrom<U> for T
    where - U: Into<T>,

    §

    type Error = Infallible

    The type returned in the event of a conversion error.
    source§

    fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

    Performs the conversion.
    source§

    impl<T, U> TryInto<U> for T
    where - U: TryFrom<T>,

    §

    type Error = <U as TryFrom<T>>::Error

    The type returned in the event of a conversion error.
    source§

    fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

    Performs the conversion.
    §

    impl<T> Ungil for T
    where + U: Into<T>,

    §

    type Error = Infallible

    The type returned in the event of a conversion error.
    source§

    fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

    Performs the conversion.
    source§

    impl<T, U> TryInto<U> for T
    where + U: TryFrom<T>,

    §

    type Error = <U as TryFrom<T>>::Error

    The type returned in the event of a conversion error.
    source§

    fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

    Performs the conversion.
    §

    impl<T> Ungil for T
    where T: Send,

    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/index.html b/nightly/core/nautilus_accounting/account/index.html index a5451fc4402f..3f6b8f1ad427 100644 --- a/nightly/core/nautilus_accounting/account/index.html +++ b/nightly/core/nautilus_accounting/account/index.html @@ -1,2 +1,2 @@ -nautilus_accounting::account - Rust +nautilus_accounting::account - Rust
    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/margin/index.html b/nightly/core/nautilus_accounting/account/margin/index.html index 08fa2bb5a3d7..c0721930ca9c 100644 --- a/nightly/core/nautilus_accounting/account/margin/index.html +++ b/nightly/core/nautilus_accounting/account/margin/index.html @@ -1,2 +1,2 @@ -nautilus_accounting::account::margin - Rust -
    \ No newline at end of file +nautilus_accounting::account::margin - Rust +
    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/margin/struct.MarginAccount.html b/nightly/core/nautilus_accounting/account/margin/struct.MarginAccount.html index cbc4f854f4f5..579aa5b68589 100644 --- a/nightly/core/nautilus_accounting/account/margin/struct.MarginAccount.html +++ b/nightly/core/nautilus_accounting/account/margin/struct.MarginAccount.html @@ -1,87 +1,87 @@ -MarginAccount in nautilus_accounting::account::margin - Rust -
    pub struct MarginAccount {
    +MarginAccount in nautilus_accounting::account::margin - Rust
    +    
    pub struct MarginAccount {
         pub base: BaseAccount,
    -    pub leverages: HashMap<InstrumentId, f64>,
    -    pub margins: HashMap<InstrumentId, MarginBalance>,
    +    pub leverages: HashMap<InstrumentId, f64>,
    +    pub margins: HashMap<InstrumentId, MarginBalance>,
         pub default_leverage: f64,
    -}

    Fields§

    §base: BaseAccount§leverages: HashMap<InstrumentId, f64>§margins: HashMap<InstrumentId, MarginBalance>§default_leverage: f64

    Implementations§

    source§

    impl MarginAccount

    source

    pub fn new(event: AccountState, calculate_account_state: bool) -> Result<Self>

    source

    pub fn set_default_leverage(&mut self, leverage: f64)

    source

    pub fn set_leverage(&mut self, instrument_id: InstrumentId, leverage: f64)

    source

    pub fn get_leverage(&self, instrument_id: &InstrumentId) -> f64

    source

    pub fn is_unleveraged(&self, instrument_id: InstrumentId) -> bool

    source

    pub fn is_cash_account(&self) -> bool

    source

    pub fn is_margin_account(&self) -> bool

    source

    pub fn initial_margins(&self) -> HashMap<InstrumentId, Money>

    source

    pub fn maintenance_margins(&self) -> HashMap<InstrumentId, Money>

    source

    pub fn update_initial_margin( +}

    Fields§

    §base: BaseAccount§leverages: HashMap<InstrumentId, f64>§margins: HashMap<InstrumentId, MarginBalance>§default_leverage: f64

    Implementations§

    source§

    impl MarginAccount

    source

    pub fn new(event: AccountState, calculate_account_state: bool) -> Result<Self>

    source

    pub fn set_default_leverage(&mut self, leverage: f64)

    source

    pub fn set_leverage(&mut self, instrument_id: InstrumentId, leverage: f64)

    source

    pub fn get_leverage(&self, instrument_id: &InstrumentId) -> f64

    source

    pub fn is_unleveraged(&self, instrument_id: InstrumentId) -> bool

    source

    pub fn is_cash_account(&self) -> bool

    source

    pub fn is_margin_account(&self) -> bool

    source

    pub fn initial_margins(&self) -> HashMap<InstrumentId, Money>

    source

    pub fn maintenance_margins(&self) -> HashMap<InstrumentId, Money>

    source

    pub fn update_initial_margin( &mut self, - instrument_id: InstrumentId, - margin_init: Money -)

    source

    pub fn initial_margin(&self, instrument_id: InstrumentId) -> Money

    source

    pub fn update_maintenance_margin( + instrument_id: InstrumentId, + margin_init: Money +)

    source

    pub fn initial_margin(&self, instrument_id: InstrumentId) -> Money

    source

    pub fn update_maintenance_margin( &mut self, - instrument_id: InstrumentId, - margin_maintenance: Money -)

    source

    pub fn maintenance_margin(&self, instrument_id: InstrumentId) -> Money

    source

    pub fn calculate_initial_margin<T: Instrument>( + instrument_id: InstrumentId, + margin_maintenance: Money +)

    source

    pub fn maintenance_margin(&self, instrument_id: InstrumentId) -> Money

    source

    pub fn calculate_initial_margin<T: Instrument>( &mut self, instrument: T, - quantity: Quantity, - price: Price, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Money

    source

    pub fn calculate_maintenance_margin<T: Instrument>( +) -> Money

    source

    pub fn calculate_maintenance_margin<T: Instrument>( &mut self, instrument: T, - quantity: Quantity, - price: Price, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Money

    source

    pub fn recalculate_balance(&mut self, currency: Currency)

    source§

    impl MarginAccount

    source

    pub fn py_calculate_initial_margin( +) -> Money

    source

    pub fn recalculate_balance(&mut self, currency: Currency)

    source§

    impl MarginAccount

    source

    pub fn py_calculate_initial_margin( &mut self, instrument: PyObject, - quantity: Quantity, - price: Price, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool>, py: Python<'_> -) -> PyResult<Money>

    source

    pub fn py_calculate_maintenance_margin( +) -> PyResult<Money>

    source

    pub fn py_calculate_maintenance_margin( &mut self, instrument: PyObject, - quantity: Quantity, - price: Price, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool>, py: Python<'_> -) -> PyResult<Money>

    Methods from Deref<Target = BaseAccount>§

    Methods from Deref<Target = BaseAccount>§

    source

    pub fn base_balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_total(&self) -> HashMap<Currency, Money>

    source

    pub fn base_balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_free(&self) -> HashMap<Currency, Money>

    source

    pub fn base_balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source

    pub fn base_balances_locked(&self) -> HashMap<Currency, Money>

    source

    pub fn base_last_event(&self) -> Option<AccountState>

    source

    pub fn update_balances(&mut self, balances: Vec<AccountBalance>)

    source

    pub fn base_apply(&mut self, event: AccountState)

    source

    pub fn base_calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source

    pub fn base_calculate_pnls<T: Instrument>( +) -> Result<Money>

    source

    pub fn base_calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> -) -> Result<Vec<Money>>

    source

    pub fn base_calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> +) -> Result<Vec<Money>>

    source

    pub fn base_calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    Trait Implementations§

    source§

    impl Account for MarginAccount

    Trait Implementations§

    source§

    impl Account for MarginAccount

    source§

    fn balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_total(&self) -> HashMap<Currency, Money>

    source§

    fn balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_free(&self) -> HashMap<Currency, Money>

    source§

    fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source§

    fn balances_locked(&self) -> HashMap<Currency, Money>

    source§

    fn last_event(&self) -> Option<AccountState>

    source§

    fn events(&self) -> Vec<AccountState>

    source§

    fn event_count(&self) -> usize

    source§

    fn currencies(&self) -> Vec<Currency>

    source§

    fn starting_balances(&self) -> HashMap<Currency, Money>

    source§

    fn balances(&self) -> HashMap<Currency, AccountBalance>

    source§

    fn apply(&mut self, event: AccountState)

    source§

    fn calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source§

    fn calculate_pnls<T: Instrument>( +) -> Result<Money>

    source§

    fn calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> -) -> Result<Vec<Money>>

    source§

    fn calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> +) -> Result<Vec<Money>>

    source§

    fn calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source§

    impl Debug for MarginAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for MarginAccount

    §

    type Target = BaseAccount

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl DerefMut for MarginAccount

    source§

    fn deref_mut(&mut self) -> &mut Self::Target

    Mutably dereferences the value.
    source§

    impl Display for MarginAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Hash for MarginAccount

    source§

    fn hash<H: Hasher>(&self, state: &mut H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where +) -> Result<Money>

    source§

    impl Debug for MarginAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for MarginAccount

    §

    type Target = BaseAccount

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl DerefMut for MarginAccount

    source§

    fn deref_mut(&mut self) -> &mut Self::Target

    Mutably dereferences the value.
    source§

    impl Display for MarginAccount

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Hash for MarginAccount

    source§

    fn hash<H: Hasher>(&self, state: &mut H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl IntoPy<Py<PyAny>> for MarginAccount

    source§

    fn into_py(self, py: Python<'_>) -> PyObject

    Performs the conversion.
    source§

    impl PartialEq for MarginAccount

    source§

    fn eq(&self, other: &Self) -> bool

    This method tests for self and other values to be equal, and is used + Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl IntoPy<Py<PyAny>> for MarginAccount

    source§

    fn into_py(self, py: Python<'_>) -> PyObject

    Performs the conversion.
    source§

    impl PartialEq for MarginAccount

    source§

    fn eq(&self, other: &Self) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason.
    source§

    impl PyClass for MarginAccount

    §

    type Frozen = False

    Whether the pyclass is frozen. Read more
    source§

    impl PyClassImpl for MarginAccount

    source§

    const IS_BASETYPE: bool = false

    #[pyclass(subclass)]
    source§

    const IS_SUBCLASS: bool = false

    #[pyclass(extends=…)]
    source§

    const IS_MAPPING: bool = false

    #[pyclass(mapping)]
    source§

    const IS_SEQUENCE: bool = false

    #[pyclass(sequence)]
    §

    type BaseType = PyAny

    Base class
    §

    type ThreadChecker = SendablePyClass<MarginAccount>

    This handles following two situations: Read more
    §

    type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild

    Immutable or mutable
    §

    type Dict = PyClassDummySlot

    Specify this class has #[pyclass(dict)] or not.
    §

    type WeakRef = PyClassDummySlot

    Specify this class has #[pyclass(weakref)] or not.
    §

    type BaseNativeType = PyAny

    The closest native ancestor. This is PyAny by default, and when you declare -#[pyclass(extends=PyDict)], it’s PyDict.
    source§

    fn items_iter() -> PyClassItemsIter

    source§

    fn doc(py: Python<'_>) -> PyResult<&'static CStr>

    Rendered class doc
    source§

    fn lazy_type_object() -> &'static LazyTypeObject<Self>

    §

    fn dict_offset() -> Option<isize>

    §

    fn weaklist_offset() -> Option<isize>

    source§

    impl PyClassNewTextSignature<MarginAccount> for PyClassImplCollector<MarginAccount>

    source§

    fn new_text_signature(self) -> Option<&'static str>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a MarginAccount

    §

    type Holder = Option<PyRef<'py, MarginAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a mut MarginAccount

    §

    type Holder = Option<PyRefMut<'py, MarginAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl PyMethods<MarginAccount> for PyClassImplCollector<MarginAccount>

    source§

    fn py_methods(self) -> &'static PyClassItems

    source§

    impl PyTypeInfo for MarginAccount

    §

    type AsRefTarget = PyCell<MarginAccount>

    Utility type to make Py::as_ref work.
    source§

    const NAME: &'static str = "MarginAccount"

    Class name.
    source§

    const MODULE: Option<&'static str> = _

    Module name, if any.
    source§

    fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject

    Returns the PyTypeObject instance for this type.
    §

    fn type_object(py: Python<'_>) -> &PyType

    Returns the safe abstraction over the type object.
    §

    fn is_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type or a subclass of this type.
    §

    fn is_exact_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type.
    source§

    impl Eq for MarginAccount

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for MarginAccount

    §

    impl Send for MarginAccount

    §

    impl Sync for MarginAccount

    §

    impl Unpin for MarginAccount

    §

    impl UnwindSafe for MarginAccount

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +sufficient, and should not be overridden without very good reason.

    source§

    impl PyClass for MarginAccount

    §

    type Frozen = False

    Whether the pyclass is frozen. Read more
    source§

    impl PyClassImpl for MarginAccount

    source§

    const IS_BASETYPE: bool = false

    #[pyclass(subclass)]
    source§

    const IS_SUBCLASS: bool = false

    #[pyclass(extends=…)]
    source§

    const IS_MAPPING: bool = false

    #[pyclass(mapping)]
    source§

    const IS_SEQUENCE: bool = false

    #[pyclass(sequence)]
    §

    type BaseType = PyAny

    Base class
    §

    type ThreadChecker = SendablePyClass<MarginAccount>

    This handles following two situations: Read more
    §

    type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild

    Immutable or mutable
    §

    type Dict = PyClassDummySlot

    Specify this class has #[pyclass(dict)] or not.
    §

    type WeakRef = PyClassDummySlot

    Specify this class has #[pyclass(weakref)] or not.
    §

    type BaseNativeType = PyAny

    The closest native ancestor. This is PyAny by default, and when you declare +#[pyclass(extends=PyDict)], it’s PyDict.
    source§

    fn items_iter() -> PyClassItemsIter

    source§

    fn doc(py: Python<'_>) -> PyResult<&'static CStr>

    Rendered class doc
    source§

    fn lazy_type_object() -> &'static LazyTypeObject<Self>

    §

    fn dict_offset() -> Option<isize>

    §

    fn weaklist_offset() -> Option<isize>

    source§

    impl PyClassNewTextSignature<MarginAccount> for PyClassImplCollector<MarginAccount>

    source§

    fn new_text_signature(self) -> Option<&'static str>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a MarginAccount

    §

    type Holder = Option<PyRef<'py, MarginAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a mut MarginAccount

    §

    type Holder = Option<PyRefMut<'py, MarginAccount>>

    source§

    fn extract(obj: &'py PyAny, holder: &'a mut Self::Holder) -> PyResult<Self>

    source§

    impl PyMethods<MarginAccount> for PyClassImplCollector<MarginAccount>

    source§

    fn py_methods(self) -> &'static PyClassItems

    source§

    impl PyTypeInfo for MarginAccount

    §

    type AsRefTarget = PyCell<MarginAccount>

    Utility type to make Py::as_ref work.
    source§

    const NAME: &'static str = "MarginAccount"

    Class name.
    source§

    const MODULE: Option<&'static str> = _

    Module name, if any.
    source§

    fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject

    Returns the PyTypeObject instance for this type.
    §

    fn type_object(py: Python<'_>) -> &PyType

    Returns the safe abstraction over the type object.
    §

    fn is_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type or a subclass of this type.
    §

    fn is_exact_type_of(object: &PyAny) -> bool

    Checks if object is an instance of this type.
    source§

    impl Eq for MarginAccount

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for MarginAccount

    §

    impl Send for MarginAccount

    §

    impl Sync for MarginAccount

    §

    impl Unpin for MarginAccount

    §

    impl UnwindSafe for MarginAccount

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    §

    impl<Q, K> Equivalent<K> for Q
    where @@ -97,6 +97,6 @@ T: IntoPy<Py<PyAny>> + Send + Sync,

    §

    fn arguments(self, py: Python<'_>) -> Py<PyAny>

    Arguments for exception
    source§

    impl<T> Separable for T
    where T: Display,

    source§

    fn separate_by_policy(&self, policy: SeparatorPolicy<'_>) -> String

    Adds separators according to the given SeparatorPolicy. Read more
    source§

    fn separate_with_commas(&self) -> String

    Inserts a comma every three digits from the right. Read more
    source§

    fn separate_with_spaces(&self) -> String

    Inserts a space every three digits from the right. Read more
    source§

    fn separate_with_dots(&self) -> String

    Inserts a period every three digits from the right. Read more
    source§

    fn separate_with_underscores(&self) -> String

    Inserts an underscore every three digits from the right. Read more
    source§

    impl<T> ToString for T
    where T: Display + ?Sized,

    source§

    default fn to_string(&self) -> String

    Converts the given value to a String. Read more
    source§

    impl<T, U> TryFrom<U> for T
    where - U: Into<T>,

    §

    type Error = Infallible

    The type returned in the event of a conversion error.
    source§

    fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

    Performs the conversion.
    source§

    impl<T, U> TryInto<U> for T
    where - U: TryFrom<T>,

    §

    type Error = <U as TryFrom<T>>::Error

    The type returned in the event of a conversion error.
    source§

    fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

    Performs the conversion.
    §

    impl<T> Ungil for T
    where + U: Into<T>,

    §

    type Error = Infallible

    The type returned in the event of a conversion error.
    source§

    fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

    Performs the conversion.
    source§

    impl<T, U> TryInto<U> for T
    where + U: TryFrom<T>,

    §

    type Error = <U as TryFrom<T>>::Error

    The type returned in the event of a conversion error.
    source§

    fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

    Performs the conversion.
    §

    impl<T> Ungil for T
    where T: Send,

    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/account/trait.Account.html b/nightly/core/nautilus_accounting/account/trait.Account.html index f5ba39edd892..f811f92b9019 100644 --- a/nightly/core/nautilus_accounting/account/trait.Account.html +++ b/nightly/core/nautilus_accounting/account/trait.Account.html @@ -1,58 +1,58 @@ -Account in nautilus_accounting::account - Rust +Account in nautilus_accounting::account - Rust
    pub trait Account {
     
    Show 16 methods // Required methods - fn balance_total(&self, currency: Option<Currency>) -> Option<Money>; - fn balances_total(&self) -> HashMap<Currency, Money>; - fn balance_free(&self, currency: Option<Currency>) -> Option<Money>; - fn balances_free(&self) -> HashMap<Currency, Money>; - fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>; - fn balances_locked(&self) -> HashMap<Currency, Money>; - fn last_event(&self) -> Option<AccountState>; - fn events(&self) -> Vec<AccountState>; + fn balance_total(&self, currency: Option<Currency>) -> Option<Money>; + fn balances_total(&self) -> HashMap<Currency, Money>; + fn balance_free(&self, currency: Option<Currency>) -> Option<Money>; + fn balances_free(&self) -> HashMap<Currency, Money>; + fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>; + fn balances_locked(&self) -> HashMap<Currency, Money>; + fn last_event(&self) -> Option<AccountState>; + fn events(&self) -> Vec<AccountState>; fn event_count(&self) -> usize; - fn currencies(&self) -> Vec<Currency>; - fn starting_balances(&self) -> HashMap<Currency, Money>; - fn balances(&self) -> HashMap<Currency, AccountBalance>; - fn apply(&mut self, event: AccountState); - fn calculate_balance_locked<T: Instrument>( + fn currencies(&self) -> Vec<Currency>; + fn starting_balances(&self) -> HashMap<Currency, Money>; + fn balances(&self) -> HashMap<Currency, AccountBalance>; + fn apply(&mut self, event: AccountState); + fn calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> - ) -> Result<Money>; - fn calculate_pnls<T: Instrument>( + ) -> Result<Money>; + fn calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> - ) -> Result<Vec<Money>>; - fn calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> + ) -> Result<Vec<Money>>; + fn calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> - ) -> Result<Money>; -
    }

    Required Methods§

    source

    fn balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_total(&self) -> HashMap<Currency, Money>

    source

    fn balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_free(&self) -> HashMap<Currency, Money>

    source

    fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_locked(&self) -> HashMap<Currency, Money>

    source

    fn last_event(&self) -> Option<AccountState>

    source

    fn events(&self) -> Vec<AccountState>

    source

    fn event_count(&self) -> usize

    source

    fn currencies(&self) -> Vec<Currency>

    source

    fn starting_balances(&self) -> HashMap<Currency, Money>

    source

    fn balances(&self) -> HashMap<Currency, AccountBalance>

    source

    fn apply(&mut self, event: AccountState)

    source

    fn calculate_balance_locked<T: Instrument>( + ) -> Result<Money>; +}

    Required Methods§

    source

    fn balance_total(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_total(&self) -> HashMap<Currency, Money>

    source

    fn balance_free(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_free(&self) -> HashMap<Currency, Money>

    source

    fn balance_locked(&self, currency: Option<Currency>) -> Option<Money>

    source

    fn balances_locked(&self) -> HashMap<Currency, Money>

    source

    fn last_event(&self) -> Option<AccountState>

    source

    fn events(&self) -> Vec<AccountState>

    source

    fn event_count(&self) -> usize

    source

    fn currencies(&self) -> Vec<Currency>

    source

    fn starting_balances(&self) -> HashMap<Currency, Money>

    source

    fn balances(&self) -> HashMap<Currency, AccountBalance>

    source

    fn apply(&mut self, event: AccountState)

    source

    fn calculate_balance_locked<T: Instrument>( &mut self, instrument: T, - side: OrderSide, - quantity: Quantity, - price: Price, + side: OrderSide, + quantity: Quantity, + price: Price, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    source

    fn calculate_pnls<T: Instrument>( +) -> Result<Money>

    source

    fn calculate_pnls<T: Instrument>( &self, instrument: T, - fill: OrderFilled, - position: Option<Position> -) -> Result<Vec<Money>>

    source

    fn calculate_commission<T: Instrument>( + fill: OrderFilled, + position: Option<Position> +) -> Result<Vec<Money>>

    source

    fn calculate_commission<T: Instrument>( &self, instrument: T, - last_qty: Quantity, - last_px: Price, - liquidity_side: LiquiditySide, + last_qty: Quantity, + last_px: Price, + liquidity_side: LiquiditySide, use_quote_for_inverse: Option<bool> -) -> Result<Money>

    Object Safety§

    This trait is not object safe.

    Implementors§

    \ No newline at end of file +) -> Result<Money>

    Object Safety§

    This trait is not object safe.

    Implementors§

    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/all.html b/nightly/core/nautilus_accounting/all.html index 1e453c827bd9..2900c5b52b21 100644 --- a/nightly/core/nautilus_accounting/all.html +++ b/nightly/core/nautilus_accounting/all.html @@ -1,2 +1,2 @@ -List of all items in this crate +List of all items in this crate
    \ No newline at end of file diff --git a/nightly/core/nautilus_accounting/index.html b/nightly/core/nautilus_accounting/index.html index 35b945070719..bfc721f5820c 100644 --- a/nightly/core/nautilus_accounting/index.html +++ b/nightly/core/nautilus_accounting/index.html @@ -1,3 +1,3 @@ -nautilus_accounting - Rust
    //////////////////////////////////////////////////////////////////////////////// #[cfg(test)] mod tests { - use crate::account::margin::MarginAccount; - use crate::account::stubs::*; - use crate::account::Account; - use nautilus_model::events::account::state::AccountState; - use nautilus_model::events::account::stubs::*; - use nautilus_model::identifiers::instrument_id::InstrumentId; - use nautilus_model::identifiers::stubs::*; - use nautilus_model::instruments::crypto_perpetual::CryptoPerpetual; - use nautilus_model::instruments::currency_pair::CurrencyPair; - use nautilus_model::instruments::stubs::*; - use nautilus_model::types::currency::Currency; - use nautilus_model::types::money::Money; - use nautilus_model::types::price::Price; - use nautilus_model::types::quantity::Quantity; - use rstest::rstest; use std::collections::HashMap; + use nautilus_model::{ + events::account::{state::AccountState, stubs::*}, + identifiers::{instrument_id::InstrumentId, stubs::*}, + instruments::{crypto_perpetual::CryptoPerpetual, currency_pair::CurrencyPair, stubs::*}, + types::{currency::Currency, money::Money, price::Price, quantity::Quantity}, + }; + use rstest::rstest; + + use crate::account::{margin::MarginAccount, stubs::*, Account}; + #[rstest] fn test_display(margin_account: MarginAccount) { assert_eq!( diff --git a/nightly/core/src/nautilus_accounting/account/mod.rs.html b/nightly/core/src/nautilus_accounting/account/mod.rs.html index 949a096ed982..974ae85fa887 100644 --- a/nightly/core/src/nautilus_accounting/account/mod.rs.html +++ b/nightly/core/src/nautilus_accounting/account/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source // limitations under the License. // ------------------------------------------------------------------------------------------------- -use anyhow::Result; -use nautilus_model::enums::{LiquiditySide, OrderSide}; -use nautilus_model::events::account::state::AccountState; -use nautilus_model::events::order::filled::OrderFilled; -use nautilus_model::instruments::Instrument; -use nautilus_model::position::Position; -use nautilus_model::types::balance::AccountBalance; -use nautilus_model::types::currency::Currency; -use nautilus_model::types::money::Money; -use nautilus_model::types::price::Price; -use nautilus_model::types::quantity::Quantity; -use std::collections::HashMap; +use std::collections::HashMap; + +use anyhow::Result; +use nautilus_model::{ + enums::{LiquiditySide, OrderSide}, + events::{account::state::AccountState, order::filled::OrderFilled}, + instruments::Instrument, + position::Position, + types::{ + balance::AccountBalance, currency::Currency, money::Money, price::Price, quantity::Quantity, + }, +}; pub trait Account { fn balance_total(&self, currency: Option<Currency>) -> Option<Money>; diff --git a/nightly/core/src/nautilus_accounting/lib.rs.html b/nightly/core/src/nautilus_accounting/lib.rs.html index 88e3b40e3e85..4bb9adc08efa 100644 --- a/nightly/core/src/nautilus_accounting/lib.rs.html +++ b/nightly/core/src/nautilus_accounting/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source use std::collections::HashMap; use nautilus_core::python::to_pyvalue_err; -use nautilus_model::enums::{LiquiditySide, OrderSide}; -use nautilus_model::events::account::state::AccountState; -use nautilus_model::events::order::filled::OrderFilled; -use nautilus_model::identifiers::account_id::AccountId; -use nautilus_model::instruments::crypto_future::CryptoFuture; -use nautilus_model::instruments::crypto_perpetual::CryptoPerpetual; -use nautilus_model::instruments::currency_pair::CurrencyPair; -use nautilus_model::instruments::equity::Equity; -use nautilus_model::instruments::futures_contract::FuturesContract; -use nautilus_model::instruments::options_contract::OptionsContract; -use nautilus_model::position::Position; -use nautilus_model::types::currency::Currency; -use nautilus_model::types::money::Money; -use nautilus_model::types::price::Price; -use nautilus_model::types::quantity::Quantity; -use pyo3::basic::CompareOp; -use pyo3::prelude::*; +use nautilus_model::{ + enums::{LiquiditySide, OrderSide}, + events::{account::state::AccountState, order::filled::OrderFilled}, + identifiers::account_id::AccountId, + instruments::{ + crypto_future::CryptoFuture, crypto_perpetual::CryptoPerpetual, + currency_pair::CurrencyPair, equity::Equity, futures_contract::FuturesContract, + options_contract::OptionsContract, + }, + position::Position, + types::{currency::Currency, money::Money, price::Price, quantity::Quantity}, +}; +use pyo3::{basic::CompareOp, prelude::*}; -use crate::account::cash::CashAccount; -use crate::account::Account; +use crate::account::{cash::CashAccount, Account}; #[pymethods] impl CashAccount { diff --git a/nightly/core/src/nautilus_accounting/python/margin.rs.html b/nightly/core/src/nautilus_accounting/python/margin.rs.html index ce17bdaf6b6f..2261204345ea 100644 --- a/nightly/core/src/nautilus_accounting/python/margin.rs.html +++ b/nightly/core/src/nautilus_accounting/python/margin.rs.html @@ -1,4 +1,4 @@ -margin.rs - source 296 297 298 -299 -300
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -316,18 +314,16 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    use nautilus_core::python::to_pyvalue_err; -use nautilus_model::events::account::state::AccountState; -use nautilus_model::identifiers::account_id::AccountId; -use nautilus_model::identifiers::instrument_id::InstrumentId; -use nautilus_model::instruments::crypto_future::CryptoFuture; -use nautilus_model::instruments::crypto_perpetual::CryptoPerpetual; -use nautilus_model::instruments::currency_pair::CurrencyPair; -use nautilus_model::instruments::equity::Equity; -use nautilus_model::instruments::futures_contract::FuturesContract; -use nautilus_model::instruments::options_contract::OptionsContract; -use nautilus_model::types::money::Money; -use nautilus_model::types::price::Price; -use nautilus_model::types::quantity::Quantity; +use nautilus_model::{ + events::account::state::AccountState, + identifiers::{account_id::AccountId, instrument_id::InstrumentId}, + instruments::{ + crypto_future::CryptoFuture, crypto_perpetual::CryptoPerpetual, + currency_pair::CurrencyPair, equity::Equity, futures_contract::FuturesContract, + options_contract::OptionsContract, + }, + types::{money::Money, price::Price, quantity::Quantity}, +}; use pyo3::{basic::CompareOp, prelude::*, types::PyDict}; use crate::account::margin::MarginAccount; diff --git a/nightly/core/src/nautilus_accounting/python/mod.rs.html b/nightly/core/src/nautilus_accounting/python/mod.rs.html index 4d31a5f2133a..fda9e3eb442b 100644 --- a/nightly/core/src/nautilus_accounting/python/mod.rs.html +++ b/nightly/core/src/nautilus_accounting/python/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source use std::{env, fs, path::PathBuf}; use anyhow::{bail, Result}; -use databento::dbn; use dbn::{ compat::InstrumentDefMsgV1, decode::{dbn::Decoder, DbnMetadata, DecodeStream}, @@ -322,7 +319,6 @@

    Files

    }; use pyo3::prelude::*; use streaming_iterator::StreamingIterator; -use time; use ustr::Ustr; use super::{ diff --git a/nightly/core/src/nautilus_adapters/databento/mod.rs.html b/nightly/core/src/nautilus_adapters/databento/mod.rs.html index 2f0bd88e7415..7980be2b6478 100644 --- a/nightly/core/src/nautilus_adapters/databento/mod.rs.html +++ b/nightly/core/src/nautilus_adapters/databento/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source // limitations under the License. // ------------------------------------------------------------------------------------------------- -use databento::dbn; -use nautilus_core::{python::to_pyvalue_err, time::UnixNanos}; +use nautilus_core::{python::to_pyvalue_err, time::UnixNanos}; use nautilus_model::{ data::{depth::OrderBookDepth10, trade::TradeTick}, identifiers::instrument_id::InstrumentId, diff --git a/nightly/core/src/nautilus_adapters/databento/python/historical.rs.html b/nightly/core/src/nautilus_adapters/databento/python/historical.rs.html index 144c5106f157..f7903cc28ad3 100644 --- a/nightly/core/src/nautilus_adapters/databento/python/historical.rs.html +++ b/nightly/core/src/nautilus_adapters/databento/python/historical.rs.html @@ -1,4 +1,4 @@ -historical.rs - source 359 360 361 -362 -363
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -380,8 +378,7 @@ 

    Files

    use std::{fs, num::NonZeroU64, sync::Arc}; -use databento::{self, historical::timeseries::GetRangeParams}; -use dbn::{self, VersionUpgradePolicy}; +use databento::historical::timeseries::GetRangeParams; use indexmap::IndexMap; use nautilus_core::{ python::to_pyvalue_err, @@ -399,6 +396,7 @@

    Files

    }; use tokio::sync::Mutex; +use super::loader::convert_instrument_to_pyobject; use crate::databento::{ common::get_date_time_range, decode::{decode_instrument_def_msg, decode_record, raw_ptr_to_ustr}, @@ -406,18 +404,16 @@

    Files

    types::{DatabentoPublisher, PublisherId}, }; -use super::loader::convert_instrument_to_pyobject; - #[cfg_attr( feature = "python", pyclass(module = "nautilus_trader.core.nautilus_pyo3.databento") )] pub struct DatabentoHistoricalClient { + #[pyo3(get)] + pub key: String, clock: &'static AtomicTime, inner: Arc<Mutex<databento::HistoricalClient>>, publisher_venue_map: Arc<IndexMap<PublisherId, Venue>>, - #[pyo3(get)] - pub key: String, } #[pymethods] @@ -500,7 +496,7 @@

    Files

    .await .map_err(to_pyvalue_err)?; - decoder.set_upgrade_policy(VersionUpgradePolicy::Upgrade); + decoder.set_upgrade_policy(dbn::VersionUpgradePolicy::Upgrade); let mut instruments = Vec::new(); diff --git a/nightly/core/src/nautilus_adapters/databento/python/live.rs.html b/nightly/core/src/nautilus_adapters/databento/python/live.rs.html index 78f4f01b9700..1ec5069894c3 100644 --- a/nightly/core/src/nautilus_adapters/databento/python/live.rs.html +++ b/nightly/core/src/nautilus_adapters/databento/python/live.rs.html @@ -1,4 +1,4 @@ -live.rs - source 353 354 355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -370,40 +425,36 @@ 

    Files

    // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use std::collections::HashMap; -use std::fs; -use std::str::FromStr; -use std::sync::Arc; +use std::{collections::HashMap, ffi::CStr, fs, str::FromStr, sync::Arc}; -use anyhow::{bail, Result}; +use anyhow::{anyhow, bail, Result}; +use databento::dbn::{PitSymbolMap, Record, SymbolIndex, VersionUpgradePolicy}; use databento::live::Subscription; -use dbn::{PitSymbolMap, Record, SymbolIndex, VersionUpgradePolicy}; use indexmap::IndexMap; use log::{error, info}; -use nautilus_core::python::to_pyruntime_err; -use nautilus_core::time::AtomicTime; use nautilus_core::{ - python::to_pyvalue_err, - time::{get_atomic_clock_realtime, UnixNanos}, + python::{to_pyruntime_err, to_pyvalue_err}, + time::{get_atomic_clock_realtime, AtomicTime, UnixNanos}, }; -use nautilus_model::data::delta::OrderBookDelta; -use nautilus_model::data::deltas::OrderBookDeltas; -use nautilus_model::data::Data; -use nautilus_model::ffi::data::deltas::OrderBookDeltas_API; -use nautilus_model::identifiers::instrument_id::InstrumentId; -use nautilus_model::identifiers::symbol::Symbol; -use nautilus_model::identifiers::venue::Venue; -use nautilus_model::python::data::data_to_pycapsule; -use pyo3::exceptions::PyRuntimeError; -use pyo3::prelude::*; +use nautilus_model::{ + data::{delta::OrderBookDelta, deltas::OrderBookDeltas, Data}, + ffi::data::deltas::OrderBookDeltas_API, + identifiers::{instrument_id::InstrumentId, symbol::Symbol, venue::Venue}, + python::data::data_to_pycapsule, +}; +use pyo3::{exceptions::PyRuntimeError, prelude::*}; use time::OffsetDateTime; -use tokio::sync::Mutex; -use tokio::time::{timeout, Duration}; - -use crate::databento::decode::{decode_instrument_def_msg, decode_record, raw_ptr_to_ustr}; -use crate::databento::types::{DatabentoPublisher, PublisherId}; +use tokio::{ + sync::Mutex, + time::{timeout, Duration}, +}; +use ustr::Ustr; use super::loader::convert_instrument_to_pyobject; +use crate::databento::{ + decode::{decode_instrument_def_msg, decode_record}, + types::{DatabentoPublisher, PublisherId}, +}; #[cfg_attr( feature = "python", @@ -515,7 +566,7 @@

    Files

    let publisher_venue_map = self.publisher_venue_map.clone(); let clock = get_atomic_clock_realtime(); - let buffering_start = match replay { + let mut buffering_start = match replay { true => Some(clock.get_time_ns()), false => None, }; @@ -523,6 +574,7 @@

    Files

    pyo3_asyncio::tokio::future_into_py(py, async move { let mut client = arc_client.lock().await; let mut symbol_map = PitSymbolMap::new(); + let mut instrument_id_map: HashMap<u32, InstrumentId> = HashMap::new(); let timeout_duration = Duration::from_millis(10); let relock_interval = timeout_duration.as_nanos() as u64; @@ -532,6 +584,8 @@

    Files

    client.start().await.map_err(to_pyruntime_err)?; + let mut deltas_count = 0_u64; + loop { // Check if need to drop then re-aquire lock let now_ns = clock.get_time_ns(); @@ -566,39 +620,64 @@

    Files

    } else if let Some(msg) = record.get::<dbn::SystemMsg>() { handle_system_msg(msg); } else if let Some(msg) = record.get::<dbn::SymbolMappingMsg>() { + // Remove instrument ID index as the raw symbol may have changed + instrument_id_map.remove(&msg.hd.instrument_id); handle_symbol_mapping_msg(msg, &mut symbol_map); } else if let Some(msg) = record.get::<dbn::InstrumentDefMsg>() { - handle_instrument_def_msg(msg, &publisher_venue_map, clock, &callback) - .map_err(to_pyvalue_err)?; + handle_instrument_def_msg( + msg, + &publisher_venue_map, + &mut instrument_id_map, + clock, + &callback, + ) + .map_err(to_pyvalue_err)?; } else { - let (mut data1, data2) = - handle_record(record, &symbol_map, &publisher_venue_map, clock) - .map_err(to_pyvalue_err)?; + let (mut data1, data2) = handle_record( + record, + &symbol_map, + &publisher_venue_map, + &mut instrument_id_map, + clock, + ) + .map_err(to_pyvalue_err)?; if let Some(msg) = record.get::<dbn::MboMsg>() { // SAFETY: An MBO message will always produce a delta if let Data::Delta(delta) = data1.clone().unwrap() { - buffered_deltas - .entry(delta.instrument_id) - .or_default() - .push(delta); - - // Check if this is the last message in the packet - if msg.flags & dbn::flags::LAST != 0 { - continue; // Not last message + let buffer = buffered_deltas.entry(delta.instrument_id).or_default(); + buffer.push(delta); + + // TODO: Temporary for debugging + deltas_count += 1; + println!( + "Buffering delta: {} {} {:?} flags={}", + deltas_count, delta.ts_event, buffering_start, msg.flags, + ); + + // Check if last message in the packet + if msg.flags & dbn::flags::LAST == 0 { + continue; // NOT last message } - // Check if we're currently buffering a replay + // Check if snapshot + if msg.flags & dbn::flags::SNAPSHOT != 0 { + continue; // Buffer snapshot + } + + // Check if buffering a replay if let Some(start_ns) = buffering_start { if delta.ts_event <= start_ns { - continue; // Continue buffering the replay + continue; // Continue buffering replay } + buffering_start = None; } // SAFETY: We can guarantee a deltas vec exists - let deltas = buffered_deltas.remove(&delta.instrument_id).unwrap(); - let book_deltas = OrderBookDeltas::new(delta.instrument_id, deltas); - data1 = Some(Data::Deltas(OrderBookDeltas_API::new(book_deltas))); + let buffer = buffered_deltas.remove(&delta.instrument_id).unwrap(); + let deltas = OrderBookDeltas::new(delta.instrument_id, buffer); + let deltas = OrderBookDeltas_API::new(deltas); + data1 = Some(Data::Deltas(deltas)); } }; @@ -651,16 +730,43 @@

    Files

    .unwrap_or_else(|_| panic!("Error updating `symbol_map` with {msg:?}")); } +fn update_instrument_id_map( + header: &dbn::RecordHeader, + raw_symbol: &str, + publisher_venue_map: &IndexMap<PublisherId, Venue>, + instrument_id_map: &mut HashMap<u32, InstrumentId>, +) -> InstrumentId { + // Check if instrument ID is already in the map + if let Some(&instrument_id) = instrument_id_map.get(&header.instrument_id) { + return instrument_id; + } + + let symbol = Symbol { + value: Ustr::from(raw_symbol), + }; + let venue = publisher_venue_map.get(&header.publisher_id).unwrap(); + let instrument_id = InstrumentId::new(symbol, *venue); + + instrument_id_map.insert(header.instrument_id, instrument_id); + instrument_id +} + fn handle_instrument_def_msg( msg: &dbn::InstrumentDefMsg, publisher_venue_map: &IndexMap<PublisherId, Venue>, + instrument_id_map: &mut HashMap<u32, InstrumentId>, clock: &AtomicTime, callback: &PyObject, ) -> Result<()> { - let raw_symbol = unsafe { raw_ptr_to_ustr(msg.raw_symbol.as_ptr()).unwrap() }; - let symbol = Symbol { value: raw_symbol }; - let venue = publisher_venue_map.get(&msg.hd.publisher_id).unwrap(); - let instrument_id = InstrumentId::new(symbol, *venue); + let c_str: &CStr = unsafe { CStr::from_ptr(msg.raw_symbol.as_ptr()) }; + let raw_symbol: &str = c_str.to_str().map_err(|e| anyhow!(e))?; + + let instrument_id = update_instrument_id_map( + msg.header(), + raw_symbol, + publisher_venue_map, + instrument_id_map, + ); let ts_init = clock.get_time_ns(); let result = decode_instrument_def_msg(msg, instrument_id, ts_init); @@ -681,15 +787,19 @@

    Files

    record: dbn::RecordRef, symbol_map: &PitSymbolMap, publisher_venue_map: &IndexMap<PublisherId, Venue>, + instrument_id_map: &mut HashMap<u32, InstrumentId>, clock: &AtomicTime, ) -> Result<(Option<Data>, Option<Data>)> { let raw_symbol = symbol_map .get_for_rec(&record) .expect("Cannot resolve `raw_symbol` from `symbol_map`"); - let publisher_id = record.publisher().unwrap() as PublisherId; - let symbol = Symbol::from_str_unchecked(raw_symbol); - let venue = publisher_venue_map.get(&publisher_id).unwrap(); - let instrument_id = InstrumentId::new(symbol, *venue); + + let instrument_id = update_instrument_id_map( + record.header(), + raw_symbol, + publisher_venue_map, + instrument_id_map, + ); let price_precision = 2; // Hard coded for now let ts_init = clock.get_time_ns(); diff --git a/nightly/core/src/nautilus_adapters/databento/python/loader.rs.html b/nightly/core/src/nautilus_adapters/databento/python/loader.rs.html index 65322dc52032..3fed0c966fe2 100644 --- a/nightly/core/src/nautilus_adapters/databento/python/loader.rs.html +++ b/nightly/core/src/nautilus_adapters/databento/python/loader.rs.html @@ -1,4 +1,4 @@ -loader.rs - source // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use databento::dbn; -use pyo3::prelude::*; +
    use pyo3::prelude::*; use serde::Deserialize; use ustr::Ustr; diff --git a/nightly/core/src/nautilus_adapters/lib.rs.html b/nightly/core/src/nautilus_adapters/lib.rs.html index aa66e2d95af4..87933ac6a216 100644 --- a/nightly/core/src/nautilus_adapters/lib.rs.html +++ b/nightly/core/src/nautilus_adapters/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source self.value = value; } - self._ma1.update_raw(value); - self._ma2.update_raw(value); - self._ma3 - .update_raw(2.0f64.mul_add(self._ma1.value, -self._ma2.value)); + self.ma1.update_raw(value); + self.ma2.update_raw(value); + self.ma3 + .update_raw(2.0f64.mul_add(self.ma1.value, -self.ma2.value)); - self.value = self._ma3.value; + self.value = self.ma3.value; self.count += 1; - if !self.is_initialized && self.count >= self.period { - self.is_initialized = true; + if !self.initialized && self.count >= self.period { + self.initialized = true; } } } @@ -427,7 +427,7 @@

    Files

    let display_str = format!("{indicator_hma_10}"); assert_eq!(display_str, "HullMovingAverage(10)"); assert_eq!(indicator_hma_10.period, 10); - assert!(!indicator_hma_10.is_initialized); + assert!(!indicator_hma_10.initialized); assert!(!indicator_hma_10.has_inputs); } @@ -436,9 +436,9 @@

    Files

    for i in 1..10 { indicator_hma_10.update_raw(f64::from(i)); } - assert!(!indicator_hma_10.is_initialized); + assert!(!indicator_hma_10.initialized); indicator_hma_10.update_raw(10.0); - assert!(indicator_hma_10.is_initialized); + assert!(indicator_hma_10.initialized); } #[rstest] @@ -491,7 +491,7 @@

    Files

    indicator_hma_10.handle_bar(&bar_ethusdt_binance_minute_bid); assert_eq!(indicator_hma_10.value, 1522.0); assert!(indicator_hma_10.has_inputs); - assert!(!indicator_hma_10.is_initialized); + assert!(!indicator_hma_10.initialized); } #[rstest] @@ -499,17 +499,17 @@

    Files

    indicator_hma_10.update_raw(1.0); assert_eq!(indicator_hma_10.count, 1); assert_eq!(indicator_hma_10.value, 1.0); - assert_eq!(indicator_hma_10._ma1.value, 1.0); - assert_eq!(indicator_hma_10._ma2.value, 1.0); - assert_eq!(indicator_hma_10._ma3.value, 1.0); + assert_eq!(indicator_hma_10.ma1.value, 1.0); + assert_eq!(indicator_hma_10.ma2.value, 1.0); + assert_eq!(indicator_hma_10.ma3.value, 1.0); indicator_hma_10.reset(); assert_eq!(indicator_hma_10.value, 0.0); assert_eq!(indicator_hma_10.count, 0); - assert_eq!(indicator_hma_10._ma1.value, 0.0); - assert_eq!(indicator_hma_10._ma2.value, 0.0); - assert_eq!(indicator_hma_10._ma3.value, 0.0); + assert_eq!(indicator_hma_10.ma1.value, 0.0); + assert_eq!(indicator_hma_10.ma2.value, 0.0); + assert_eq!(indicator_hma_10.ma3.value, 0.0); assert!(!indicator_hma_10.has_inputs); - assert!(!indicator_hma_10.is_initialized); + assert!(!indicator_hma_10.initialized); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/average/mod.rs.html b/nightly/core/src/nautilus_indicators/average/mod.rs.html index 528322b0924d..ebd742b6b298 100644 --- a/nightly/core/src/nautilus_indicators/average/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/average/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source self.has_inputs } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, tick: &QuoteTick) { - self.update_raw(tick.extract_price(self.price_type).into()); + fn handle_quote_tick(&mut self, quote: &QuoteTick) { + self.update_raw(quote.extract_price(self.price_type).into()); } - fn handle_trade_tick(&mut self, tick: &TradeTick) { - self.update_raw((&tick.price).into()); + fn handle_trade_tick(&mut self, trade: &TradeTick) { + self.update_raw((&trade.price).into()); } fn handle_bar(&mut self, bar: &Bar) { @@ -301,7 +301,7 @@

    Files

    self.value = 0.0; self.count = 0; self.has_inputs = false; - self.is_initialized = false; + self.initialized = false; } } @@ -319,7 +319,7 @@

    Files

    value: 0.0, count: 0, has_inputs: false, - is_initialized: false, + initialized: false, }) } } @@ -343,8 +343,8 @@

    Files

    self.count += 1; // Initialization logic - if !self.is_initialized && self.count >= self.period { - self.is_initialized = true; + if !self.initialized && self.count >= self.period { + self.initialized = true; } } } @@ -374,7 +374,7 @@

    Files

    assert_eq!(rma.period, 10); assert_eq!(rma.price_type, PriceType::Mid); assert_eq!(rma.alpha, 0.1); - assert!(!rma.is_initialized); + assert!(!rma.initialized); } #[rstest] @@ -400,7 +400,7 @@

    Files

    rma.update_raw(10.0); assert!(rma.has_inputs()); - assert!(rma.is_initialized()); + assert!(rma.initialized()); assert_eq!(rma.count, 10); assert_eq!(rma.value, 4.486_784_401); } @@ -413,7 +413,7 @@

    Files

    rma.reset(); assert_eq!(rma.count, 0); assert_eq!(rma.value, 0.0); - assert!(!rma.is_initialized); + assert!(!rma.initialized); } #[rstest] @@ -450,7 +450,7 @@

    Files

    ) { indicator_rma_10.handle_bar(&bar_ethusdt_binance_minute_bid); assert!(indicator_rma_10.has_inputs); - assert!(!indicator_rma_10.is_initialized); + assert!(!indicator_rma_10.initialized); assert_eq!(indicator_rma_10.value, 1522.0); } } diff --git a/nightly/core/src/nautilus_indicators/average/sma.rs.html b/nightly/core/src/nautilus_indicators/average/sma.rs.html index 6909bc65661d..4c06104943ee 100644 --- a/nightly/core/src/nautilus_indicators/average/sma.rs.html +++ b/nightly/core/src/nautilus_indicators/average/sma.rs.html @@ -1,4 +1,4 @@ -sma.rs - source pub value: f64, pub count: usize, pub inputs: Vec<f64>, - pub is_initialized: bool, + pub initialized: bool, } impl Display for SimpleMovingAverage { @@ -255,16 +255,16 @@

    Files

    !self.inputs.is_empty() } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, tick: &QuoteTick) { - self.update_raw(tick.extract_price(self.price_type).into()); + fn handle_quote_tick(&mut self, quote: &QuoteTick) { + self.update_raw(quote.extract_price(self.price_type).into()); } - fn handle_trade_tick(&mut self, tick: &TradeTick) { - self.update_raw((&tick.price).into()); + fn handle_trade_tick(&mut self, trade: &TradeTick) { + self.update_raw((&trade.price).into()); } fn handle_bar(&mut self, bar: &Bar) { @@ -275,7 +275,7 @@

    Files

    self.value = 0.0; self.count = 0; self.inputs.clear(); - self.is_initialized = false; + self.initialized = false; } } @@ -289,7 +289,7 @@

    Files

    value: 0.0, count: 0, inputs: Vec::with_capacity(period), - is_initialized: false, + initialized: false, }) } } @@ -312,8 +312,8 @@

    Files

    let sum = self.inputs.iter().sum::<f64>(); self.value = sum / self.count as f64; - if !self.is_initialized && self.count >= self.period { - self.is_initialized = true; + if !self.initialized && self.count >= self.period { + self.initialized = true; } } } @@ -360,7 +360,7 @@

    Files

    sma.update_raw(10.0); assert!(sma.has_inputs()); - assert!(sma.is_initialized()); + assert!(sma.initialized()); assert_eq!(sma.count, 10); assert_eq!(sma.value, 5.5); } @@ -373,7 +373,7 @@

    Files

    sma.reset(); assert_eq!(sma.count, 0); assert_eq!(sma.value, 0.0); - assert!(!sma.is_initialized); + assert!(!sma.initialized); } #[rstest] diff --git a/nightly/core/src/nautilus_indicators/average/wma.rs.html b/nightly/core/src/nautilus_indicators/average/wma.rs.html index 0dcc15106aa5..9e72e31cacd4 100644 --- a/nightly/core/src/nautilus_indicators/average/wma.rs.html +++ b/nightly/core/src/nautilus_indicators/average/wma.rs.html @@ -1,4 +1,4 @@ -wma.rs - source /// The last indicator value. pub value: f64, /// Whether the indicator is initialized. - pub is_initialized: bool, + pub initialized: bool, /// Inputs pub inputs: Vec<f64>, has_inputs: bool, @@ -301,7 +301,7 @@

    Files

    price_type: price_type.unwrap_or(PriceType::Last), value: 0.0, inputs: Vec::with_capacity(period), - is_initialized: false, + initialized: false, has_inputs: false, }) } @@ -327,16 +327,16 @@

    Files

    fn has_inputs(&self) -> bool { self.has_inputs } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, tick: &QuoteTick) { - self.update_raw(tick.extract_price(self.price_type).into()); + fn handle_quote_tick(&mut self, quote: &QuoteTick) { + self.update_raw(quote.extract_price(self.price_type).into()); } - fn handle_trade_tick(&mut self, tick: &TradeTick) { - self.update_raw((&tick.price).into()); + fn handle_trade_tick(&mut self, trade: &TradeTick) { + self.update_raw((&trade.price).into()); } fn handle_bar(&mut self, bar: &Bar) { @@ -346,7 +346,7 @@

    Files

    fn reset(&mut self) { self.value = 0.0; self.has_inputs = false; - self.is_initialized = false; + self.initialized = false; self.inputs.clear(); } } @@ -371,8 +371,8 @@

    Files

    } self.inputs.push(value); self.value = self.weighted_average(); - if !self.is_initialized && self.count() >= self.period { - self.is_initialized = true; + if !self.initialized && self.count() >= self.period { + self.initialized = true; } } } @@ -399,7 +399,7 @@

    Files

    ); assert_eq!(indicator_wma_10.name(), "WeightedMovingAverage"); assert!(!indicator_wma_10.has_inputs()); - assert!(!indicator_wma_10.is_initialized()); + assert!(!indicator_wma_10.initialized()); } #[rstest] @@ -473,7 +473,7 @@

    Files

    assert_eq!(indicator_wma_10.value, 0.0); assert_eq!(indicator_wma_10.count(), 0); assert!(!indicator_wma_10.has_inputs); - assert!(!indicator_wma_10.is_initialized); + assert!(!indicator_wma_10.initialized); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/book/imbalance.rs.html b/nightly/core/src/nautilus_indicators/book/imbalance.rs.html new file mode 100644 index 000000000000..d496766a0cbd --- /dev/null +++ b/nightly/core/src/nautilus_indicators/book/imbalance.rs.html @@ -0,0 +1,447 @@ +imbalance.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +183
    +184
    +185
    +186
    +187
    +188
    +189
    +190
    +191
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +199
    +200
    +201
    +202
    +203
    +204
    +205
    +206
    +207
    +208
    +209
    +210
    +211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +219
    +220
    +221
    +222
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +use std::fmt::Display;
    +
    +use anyhow::Result;
    +use nautilus_model::{
    +    orderbook::{book_mbo::OrderBookMbo, book_mbp::OrderBookMbp},
    +    types::quantity::Quantity,
    +};
    +use pyo3::prelude::*;
    +
    +use crate::indicator::Indicator;
    +
    +#[repr(C)]
    +#[derive(Debug)]
    +#[pyclass(module = "nautilus_trader.core.nautilus_pyo3.indicators")]
    +pub struct BookImbalanceRatio {
    +    pub value: f64,
    +    pub count: usize,
    +    pub initialized: bool,
    +    has_inputs: bool,
    +}
    +
    +impl Display for BookImbalanceRatio {
    +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    +        write!(f, "{}()", self.name())
    +    }
    +}
    +
    +impl Indicator for BookImbalanceRatio {
    +    fn name(&self) -> String {
    +        stringify!(BookImbalanceRatio).to_string()
    +    }
    +
    +    fn has_inputs(&self) -> bool {
    +        self.has_inputs
    +    }
    +
    +    fn initialized(&self) -> bool {
    +        self.initialized
    +    }
    +
    +    fn handle_book_mbo(&mut self, book: &OrderBookMbo) {
    +        self.update(book.best_bid_size(), book.best_ask_size());
    +    }
    +
    +    fn handle_book_mbp(&mut self, book: &OrderBookMbp) {
    +        self.update(book.best_bid_size(), book.best_ask_size());
    +    }
    +
    +    fn reset(&mut self) {
    +        self.value = 0.0;
    +        self.count = 0;
    +        self.has_inputs = false;
    +        self.initialized = false;
    +    }
    +}
    +
    +impl BookImbalanceRatio {
    +    pub fn new() -> Result<Self> {
    +        // Inputs don't require validation, however we return a `Result`
    +        // to standardize with other indicators which do need validation.
    +        Ok(Self {
    +            value: 0.0,
    +            count: 0,
    +            has_inputs: false,
    +            initialized: false,
    +        })
    +    }
    +
    +    pub fn update(&mut self, best_bid: Option<Quantity>, best_ask: Option<Quantity>) {
    +        self.has_inputs = true;
    +        self.count += 1;
    +
    +        if let (Some(best_bid), Some(best_ask)) = (best_bid, best_ask) {
    +            let smaller = std::cmp::min(best_bid, best_ask);
    +            let larger = std::cmp::max(best_bid, best_ask);
    +
    +            let ratio = smaller.as_f64() / larger.as_f64();
    +            self.value = ratio;
    +
    +            self.initialized = true;
    +        }
    +        // No market yet
    +    }
    +}
    +
    +////////////////////////////////////////////////////////////////////////////////
    +// Tests
    +////////////////////////////////////////////////////////////////////////////////
    +#[cfg(test)]
    +mod tests {
    +    use nautilus_model::{
    +        identifiers::instrument_id::InstrumentId,
    +        stubs::{stub_order_book_mbp, stub_order_book_mbp_appl_xnas},
    +    };
    +    use rstest::rstest;
    +
    +    use super::*;
    +
    +    // TODO: Test `OrderBookMbo`: needs a good stub function
    +
    +    #[rstest]
    +    fn test_initialized() {
    +        let imbalance = BookImbalanceRatio::new().unwrap();
    +        let display_str = format!("{imbalance}");
    +        assert_eq!(display_str, "BookImbalanceRatio()");
    +        assert_eq!(imbalance.value, 0.0);
    +        assert_eq!(imbalance.count, 0);
    +        assert!(!imbalance.has_inputs);
    +        assert!(!imbalance.initialized);
    +    }
    +
    +    #[rstest]
    +    fn test_one_value_input_balanced() {
    +        let mut imbalance = BookImbalanceRatio::new().unwrap();
    +        let book = stub_order_book_mbp_appl_xnas();
    +        imbalance.handle_book_mbp(&book);
    +
    +        assert_eq!(imbalance.count, 1);
    +        assert_eq!(imbalance.value, 1.0);
    +        assert!(imbalance.initialized);
    +        assert!(imbalance.has_inputs);
    +    }
    +
    +    #[rstest]
    +    fn test_reset() {
    +        let mut imbalance = BookImbalanceRatio::new().unwrap();
    +        let book = stub_order_book_mbp_appl_xnas();
    +        imbalance.handle_book_mbp(&book);
    +        imbalance.reset();
    +
    +        assert_eq!(imbalance.count, 0);
    +        assert_eq!(imbalance.value, 0.0);
    +        assert!(!imbalance.initialized);
    +        assert!(!imbalance.has_inputs);
    +    }
    +
    +    #[rstest]
    +    fn test_one_value_input_with_bid_imbalance() {
    +        let mut imbalance = BookImbalanceRatio::new().unwrap();
    +        let book = stub_order_book_mbp(
    +            InstrumentId::from("AAPL.XNAS"),
    +            101.0,
    +            100.0,
    +            200.0, // <-- Larger bid side
    +            100.0,
    +            2,
    +            0.01,
    +            0,
    +            100.0,
    +            10,
    +        );
    +        imbalance.handle_book_mbp(&book);
    +
    +        assert_eq!(imbalance.count, 1);
    +        assert_eq!(imbalance.value, 0.5);
    +        assert!(imbalance.initialized);
    +        assert!(imbalance.has_inputs);
    +    }
    +
    +    #[rstest]
    +    fn test_one_value_input_with_ask_imbalance() {
    +        let mut imbalance = BookImbalanceRatio::new().unwrap();
    +        let book = stub_order_book_mbp(
    +            InstrumentId::from("AAPL.XNAS"),
    +            101.0,
    +            100.0,
    +            100.0,
    +            200.0, // <-- Larger ask side
    +            2,
    +            0.01,
    +            0,
    +            100.0,
    +            10,
    +        );
    +        imbalance.handle_book_mbp(&book);
    +
    +        assert_eq!(imbalance.count, 1);
    +        assert_eq!(imbalance.value, 0.5);
    +        assert!(imbalance.initialized);
    +        assert!(imbalance.has_inputs);
    +    }
    +
    +    #[rstest]
    +    fn test_one_value_input_with_bid_imbalance_multiple_inputs() {
    +        let mut imbalance = BookImbalanceRatio::new().unwrap();
    +        let book = stub_order_book_mbp(
    +            InstrumentId::from("AAPL.XNAS"),
    +            101.0,
    +            100.0,
    +            200.0, // <-- Larger bid side
    +            100.0,
    +            2,
    +            0.01,
    +            0,
    +            100.0,
    +            10,
    +        );
    +        imbalance.handle_book_mbp(&book);
    +        imbalance.handle_book_mbp(&book);
    +        imbalance.handle_book_mbp(&book);
    +
    +        assert_eq!(imbalance.count, 3);
    +        assert_eq!(imbalance.value, 0.5);
    +        assert!(imbalance.initialized);
    +        assert!(imbalance.has_inputs);
    +    }
    +}
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/book/mod.rs.html b/nightly/core/src/nautilus_indicators/book/mod.rs.html new file mode 100644 index 000000000000..efba76d61571 --- /dev/null +++ b/nightly/core/src/nautilus_indicators/book/mod.rs.html @@ -0,0 +1,35 @@ +mod.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +pub mod imbalance;
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/indicator.rs.html b/nightly/core/src/nautilus_indicators/indicator.rs.html index 921c3de13751..d706218fe47f 100644 --- a/nightly/core/src/nautilus_indicators/indicator.rs.html +++ b/nightly/core/src/nautilus_indicators/indicator.rs.html @@ -1,4 +1,4 @@ -indicator.rs - source 46 47 48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -65,15 +103,53 @@ 

    Files

    use std::{fmt, fmt::Debug}; -use nautilus_model::data::{bar::Bar, quote::QuoteTick, trade::TradeTick}; +use nautilus_model::{ + data::{ + bar::Bar, delta::OrderBookDelta, deltas::OrderBookDeltas, depth::OrderBookDepth10, + quote::QuoteTick, trade::TradeTick, + }, + orderbook::{book_mbo::OrderBookMbo, book_mbp::OrderBookMbp}, +}; -pub trait Indicator { +const IMPL_ERR: &str = "is not implemented for"; + +#[allow(unused_variables)] +pub trait Indicator { fn name(&self) -> String; fn has_inputs(&self) -> bool; - fn is_initialized(&self) -> bool; - fn handle_quote_tick(&mut self, tick: &QuoteTick); - fn handle_trade_tick(&mut self, tick: &TradeTick); - fn handle_bar(&mut self, bar: &Bar); + fn initialized(&self) -> bool; + fn handle_delta(&mut self, delta: &OrderBookDelta) { + // Eventually change this to log an error + panic!("`handle_delta` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_deltas(&mut self, deltas: &OrderBookDeltas) { + // Eventually change this to log an error + panic!("`handle_deltas` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_depth(&mut self, depth: &OrderBookDepth10) { + // Eventually change this to log an error + panic!("`handle_depth` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_book_mbo(&mut self, book: &OrderBookMbo) { + // Eventually change this to log an error + panic!("`handle_book_mbo` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_book_mbp(&mut self, book: &OrderBookMbp) { + // Eventually change this to log an error + panic!("`handle_book_mbp` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_quote_tick(&mut self, quote: &QuoteTick) { + // Eventually change this to log an error + panic!("`handle_quote_tick` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_trade_tick(&mut self, trade: &TradeTick) { + // Eventually change this to log an error + panic!("`handle_trade_tick` {} `{}`", IMPL_ERR, self.name()); + } + fn handle_bar(&mut self, bar: &Bar) { + // Eventually change this to log an error + panic!("`handle_bar` {} `{}`", IMPL_ERR, self.name()); + } fn reset(&mut self); } diff --git a/nightly/core/src/nautilus_indicators/lib.rs.html b/nightly/core/src/nautilus_indicators/lib.rs.html index bd546d4fa5a6..ccc87776e2ef 100644 --- a/nightly/core/src/nautilus_indicators/lib.rs.html +++ b/nightly/core/src/nautilus_indicators/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source 24 25 26 +27
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -42,6 +43,7 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    pub mod average; +pub mod book; pub mod indicator; pub mod momentum; pub mod ratio; diff --git a/nightly/core/src/nautilus_indicators/momentum/aroon.rs.html b/nightly/core/src/nautilus_indicators/momentum/aroon.rs.html index be04b5ed1b8d..267306b796eb 100644 --- a/nightly/core/src/nautilus_indicators/momentum/aroon.rs.html +++ b/nightly/core/src/nautilus_indicators/momentum/aroon.rs.html @@ -1,4 +1,4 @@ -aroon.rs - source 158 159 160 +161 +162 +163 +164 +165 +166 +167
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -175,12 +182,17 @@ 

    Files

    // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use std::fmt::{Debug, Display}; +use std::{ + collections::VecDeque, + fmt::{Debug, Display}, +}; use anyhow::Result; -use nautilus_model::data::{bar::Bar, quote::QuoteTick, trade::TradeTick}; +use nautilus_model::{ + data::{bar::Bar, quote::QuoteTick, trade::TradeTick}, + enums::PriceType, +}; use pyo3::prelude::*; -use std::collections::VecDeque; use crate::indicator::Indicator; @@ -197,7 +209,7 @@

    Files

    pub aroon_down: f64, pub value: f64, pub count: usize, - pub is_initialized: bool, + pub initialized: bool, has_inputs: bool, } @@ -216,17 +228,19 @@

    Files

    self.has_inputs } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, _tick: &QuoteTick) { - // Function body intentionally left blank. - } + fn handle_quote_tick(&mut self, tick: &QuoteTick) { + let price = tick.extract_price(PriceType::Mid).into(); + self.update_raw(price, price); + } - fn handle_trade_tick(&mut self, _tick: &TradeTick) { - // Function body intentionally left blank. - } + fn handle_trade_tick(&mut self, tick: &TradeTick) { + let price = tick.price.into(); + self.update_raw(price, price); + } fn handle_bar(&mut self, bar: &Bar) { self.update_raw((&bar.close).into(), (&bar.close).into()); @@ -240,7 +254,7 @@

    Files

    self.value = 0.0; self.count = 0; self.has_inputs = false; - self.is_initialized = false; + self.initialized = false; } } @@ -255,7 +269,7 @@

    Files

    value: 0.0, count: 0, has_inputs: false, - is_initialized: false, + initialized: false, }) } @@ -271,7 +285,7 @@

    Files

    self.low_inputs.push_front(low); self.increment_count(); - if self.is_initialized { + if self.initialized { // Makes sure we calculate with stable period self.calculate_aroon(); } @@ -312,10 +326,10 @@

    Files

    fn increment_count(&mut self) { self.count += 1; - if !self.is_initialized { + if !self.initialized { self.has_inputs = true; if self.count >= self.period { - self.is_initialized = true; + self.initialized = true; } } } diff --git a/nightly/core/src/nautilus_indicators/momentum/cmo.rs.html b/nightly/core/src/nautilus_indicators/momentum/cmo.rs.html new file mode 100644 index 000000000000..8e4ce482d9bc --- /dev/null +++ b/nightly/core/src/nautilus_indicators/momentum/cmo.rs.html @@ -0,0 +1,417 @@ +cmo.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +183
    +184
    +185
    +186
    +187
    +188
    +189
    +190
    +191
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +199
    +200
    +201
    +202
    +203
    +204
    +205
    +206
    +207
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2023 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +use std::fmt::Display;
    +
    +use anyhow::Result;
    +use nautilus_model::data::{bar::Bar, quote::QuoteTick, trade::TradeTick};
    +use pyo3::prelude::*;
    +
    +use crate::{
    +    average::{MovingAverageFactory, MovingAverageType},
    +    indicator::{Indicator, MovingAverage},
    +};
    +
    +#[repr(C)]
    +#[derive(Debug)]
    +#[pyclass(module = "nautilus_trader.core.nautilus.pyo3.indicators")]
    +pub struct ChandeMomentumOscillator {
    +    pub period: usize,
    +    pub ma_type: MovingAverageType,
    +    pub value: f64,
    +    pub count: usize,
    +    pub initialized: bool,
    +    _previous_close: f64,
    +    _average_gain: Box<dyn MovingAverage + Send + 'static>,
    +    _average_loss: Box<dyn MovingAverage + Send + 'static>,
    +    _has_inputs: bool,
    +}
    +
    +impl Display for ChandeMomentumOscillator {
    +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    +        write!(f, "{}({})", self.name(), self.period)
    +    }
    +}
    +
    +impl Indicator for ChandeMomentumOscillator {
    +    fn name(&self) -> String {
    +        stringify!(ChandeMomentumOscillator).to_string()
    +    }
    +
    +    fn has_inputs(&self) -> bool {
    +        self._has_inputs
    +    }
    +
    +    fn initialized(&self) -> bool {
    +        self.initialized
    +    }
    +
    +    fn handle_quote_tick(&mut self, _tick: &QuoteTick) {
    +        // Function body intentionally left blank.
    +    }
    +
    +    fn handle_trade_tick(&mut self, _tick: &TradeTick) {
    +        // Function body intentionally left blank.
    +    }
    +
    +    fn handle_bar(&mut self, bar: &Bar) {
    +        self.update_raw((&bar.close).into());
    +    }
    +
    +    fn reset(&mut self) {
    +        self.value = 0.0;
    +        self.count = 0;
    +        self._has_inputs = false;
    +        self.initialized = false;
    +        self._previous_close = 0.0;
    +    }
    +}
    +
    +impl ChandeMomentumOscillator {
    +    pub fn new(period: usize, ma_type: Option<MovingAverageType>) -> Result<Self> {
    +        Ok(Self {
    +            period,
    +            ma_type: ma_type.unwrap_or(MovingAverageType::Wilder),
    +            _average_gain: MovingAverageFactory::create(MovingAverageType::Wilder, period),
    +            _average_loss: MovingAverageFactory::create(MovingAverageType::Wilder, period),
    +            _previous_close: 0.0,
    +            value: 0.0,
    +            count: 0,
    +            initialized: false,
    +            _has_inputs: false,
    +        })
    +    }
    +
    +    pub fn update_raw(&mut self, close: f64) {
    +        if !self._has_inputs {
    +            self._previous_close = close;
    +            self._has_inputs = true;
    +        }
    +
    +        let gain: f64 = close - self._previous_close;
    +        if gain > 0.0 {
    +            self._average_gain.update_raw(gain);
    +            self._average_loss.update_raw(0.0);
    +        } else if gain < 0.0 {
    +            self._average_gain.update_raw(0.0);
    +            self._average_loss.update_raw(-gain);
    +        } else {
    +            self._average_gain.update_raw(0.0);
    +            self._average_loss.update_raw(0.0);
    +        }
    +
    +        if !self.initialized && self._average_gain.initialized() && self._average_loss.initialized()
    +        {
    +            self.initialized = true;
    +        }
    +        if self.initialized {
    +            self.value = 100.0 * (self._average_gain.value() - self._average_loss.value())
    +                / (self._average_gain.value() + self._average_loss.value());
    +        }
    +        self._previous_close = close;
    +    }
    +}
    +
    +////////////////////////////////////////////////////////////////////////////////
    +// Tests
    +////////////////////////////////////////////////////////////////////////////////
    +#[cfg(test)]
    +mod tests {
    +    use nautilus_model::data::{bar::Bar, quote::QuoteTick};
    +    use rstest::rstest;
    +
    +    use crate::{indicator::Indicator, momentum::cmo::ChandeMomentumOscillator, stubs::*};
    +
    +    #[rstest]
    +    fn test_cmo_initialized(cmo_10: ChandeMomentumOscillator) {
    +        let display_str = format!("{cmo_10}");
    +        assert_eq!(display_str, "ChandeMomentumOscillator(10)");
    +        assert_eq!(cmo_10.period, 10);
    +        assert!(!cmo_10.initialized);
    +    }
    +
    +    #[rstest]
    +    fn test_initialized_with_required_inputs_returns_true(mut cmo_10: ChandeMomentumOscillator) {
    +        for i in 0..12 {
    +            cmo_10.update_raw(f64::from(i));
    +        }
    +        assert!(cmo_10.initialized);
    +    }
    +
    +    #[rstest]
    +    fn test_value_all_higher_inputs_returns_expected_value(mut cmo_10: ChandeMomentumOscillator) {
    +        cmo_10.update_raw(109.93);
    +        cmo_10.update_raw(110.0);
    +        cmo_10.update_raw(109.77);
    +        cmo_10.update_raw(109.96);
    +        cmo_10.update_raw(110.29);
    +        cmo_10.update_raw(110.53);
    +        cmo_10.update_raw(110.27);
    +        cmo_10.update_raw(110.21);
    +        cmo_10.update_raw(110.06);
    +        cmo_10.update_raw(110.19);
    +        cmo_10.update_raw(109.83);
    +        cmo_10.update_raw(109.9);
    +        cmo_10.update_raw(110.0);
    +        cmo_10.update_raw(110.03);
    +        cmo_10.update_raw(110.13);
    +        cmo_10.update_raw(109.95);
    +        cmo_10.update_raw(109.75);
    +        cmo_10.update_raw(110.15);
    +        cmo_10.update_raw(109.9);
    +        cmo_10.update_raw(110.04);
    +        assert_eq!(cmo_10.value, 2.089_629_456_238_705_4);
    +    }
    +
    +    #[rstest]
    +    fn test_value_with_one_input_returns_expected_value(mut cmo_10: ChandeMomentumOscillator) {
    +        cmo_10.update_raw(1.00000);
    +        assert_eq!(cmo_10.value, 0.0);
    +    }
    +
    +    #[rstest]
    +    fn test_reset(mut cmo_10: ChandeMomentumOscillator) {
    +        cmo_10.update_raw(1.00020);
    +        cmo_10.update_raw(1.00030);
    +        cmo_10.update_raw(1.00050);
    +        cmo_10.reset();
    +        assert!(!cmo_10.initialized());
    +        assert_eq!(cmo_10.count, 0);
    +    }
    +
    +    #[rstest]
    +    fn test_handle_quote_tick(mut cmo_10: ChandeMomentumOscillator, quote_tick: QuoteTick) {
    +        cmo_10.handle_quote_tick(&quote_tick);
    +        assert_eq!(cmo_10.count, 0);
    +        assert_eq!(cmo_10.value, 0.0);
    +    }
    +
    +    #[rstest]
    +    fn test_handle_bar(mut cmo_10: ChandeMomentumOscillator, bar_ethusdt_binance_minute_bid: Bar) {
    +        cmo_10.handle_bar(&bar_ethusdt_binance_minute_bid);
    +        assert_eq!(cmo_10.count, 0);
    +        assert_eq!(cmo_10.value, 0.0);
    +    }
    +}
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/momentum/mod.rs.html b/nightly/core/src/nautilus_indicators/momentum/mod.rs.html index b470f54a548c..98d08e4aa683 100644 --- a/nightly/core/src/nautilus_indicators/momentum/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/momentum/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 15 16 17 +18
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -33,5 +34,6 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    pub mod aroon; +pub mod cmo; pub mod rsi;
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/momentum/rsi.rs.html b/nightly/core/src/nautilus_indicators/momentum/rsi.rs.html index 651d3ab54839..5cb87ad5bcd4 100644 --- a/nightly/core/src/nautilus_indicators/momentum/rsi.rs.html +++ b/nightly/core/src/nautilus_indicators/momentum/rsi.rs.html @@ -1,4 +1,4 @@ -rsi.rs - source 242 243 244 -245 -246 -247
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -285,12 +282,12 @@ 

    Files

    pub ma_type: MovingAverageType, pub value: f64, pub count: usize, - pub is_initialized: bool, - _has_inputs: bool, - _last_value: f64, - _average_gain: Box<dyn MovingAverage + Send + 'static>, - _average_loss: Box<dyn MovingAverage + Send + 'static>, - _rsi_max: f64, + pub initialized: bool, + has_inputs: bool, + last_value: f64, + average_gain: Box<dyn MovingAverage + Send + 'static>, + average_loss: Box<dyn MovingAverage + Send + 'static>, + rsi_max: f64, } impl Display for RelativeStrengthIndex { @@ -305,19 +302,19 @@

    Files

    } fn has_inputs(&self) -> bool { - self._has_inputs + self.has_inputs } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, tick: &QuoteTick) { - self.update_raw(tick.extract_price(PriceType::Mid).into()); + fn handle_quote_tick(&mut self, quote: &QuoteTick) { + self.update_raw(quote.extract_price(PriceType::Mid).into()); } - fn handle_trade_tick(&mut self, tick: &TradeTick) { - self.update_raw((tick.price).into()); + fn handle_trade_tick(&mut self, trade: &TradeTick) { + self.update_raw((trade.price).into()); } fn handle_bar(&mut self, bar: &Bar) { @@ -326,10 +323,10 @@

    Files

    fn reset(&mut self) { self.value = 0.0; - self._last_value = 0.0; + self.last_value = 0.0; self.count = 0; - self._has_inputs = false; - self.is_initialized = false; + self.has_inputs = false; + self.initialized = false; } } @@ -339,53 +336,50 @@

    Files

    period, ma_type: ma_type.unwrap_or(MovingAverageType::Exponential), value: 0.0, - _last_value: 0.0, + last_value: 0.0, count: 0, // inputs: Vec::new(), - _has_inputs: false, - _average_gain: MovingAverageFactory::create(MovingAverageType::Exponential, period), - _average_loss: MovingAverageFactory::create(MovingAverageType::Exponential, period), - _rsi_max: 1.0, - is_initialized: false, +
    has_inputs: false, + average_gain: MovingAverageFactory::create(MovingAverageType::Exponential, period), + average_loss: MovingAverageFactory::create(MovingAverageType::Exponential, period), + rsi_max: 1.0, + initialized: false, }) } pub fn update_raw(&mut self, value: f64) { - if !self._has_inputs { - self._last_value = value; - self._has_inputs = true; + if !self.has_inputs { + self.last_value = value; + self.has_inputs = true; } - let gain = value - self._last_value; + let gain = value - self.last_value; if gain > 0.0 { - self._average_gain.update_raw(gain); - self._average_loss.update_raw(0.0); + self.average_gain.update_raw(gain); + self.average_loss.update_raw(0.0); } else if gain < 0.0 { - self._average_loss.update_raw(-gain); - self._average_gain.update_raw(0.0); + self.average_loss.update_raw(-gain); + self.average_gain.update_raw(0.0); } else { - self._average_loss.update_raw(0.0); - self._average_gain.update_raw(0.0); + self.average_loss.update_raw(0.0); + self.average_gain.update_raw(0.0); } // init count from average gain MA - self.count = self._average_gain.count(); - if !self.is_initialized - && self._average_loss.is_initialized() - && self._average_gain.is_initialized() - { - self.is_initialized = true; + self.count = self.average_gain.count(); + if !self.initialized && self.average_loss.initialized() && self.average_gain.initialized() { + self.initialized = true; } - if self._average_loss.value() == 0.0 { - self.value = self._rsi_max; + if self.average_loss.value() == 0.0 { + self.value = self.rsi_max; return; } - let rs = self._average_gain.value() / self._average_loss.value(); - self.value = self._rsi_max - (self._rsi_max / (1.0 + rs)); - self._last_value = value; + let rs = self.average_gain.value() / self.average_loss.value(); + self.value = self.rsi_max - (self.rsi_max / (1.0 + rs)); + self.last_value = value; - if !self.is_initialized && self.count >= self.period { - self.is_initialized = true; + if !self.initialized && self.count >= self.period { + self.initialized = true; } } } @@ -405,7 +399,7 @@

    Files

    let display_str = format!("{rsi_10}"); assert_eq!(display_str, "RelativeStrengthIndex(10,EXPONENTIAL)"); assert_eq!(rsi_10.period, 10); - assert!(!rsi_10.is_initialized); + assert!(!rsi_10.initialized); } #[rstest] @@ -413,7 +407,7 @@

    Files

    for i in 0..12 { rsi_10.update_raw(f64::from(i)); } - assert!(rsi_10.is_initialized); + assert!(rsi_10.initialized); } #[rstest] @@ -469,7 +463,7 @@

    Files

    rsi_10.update_raw(1.0); rsi_10.update_raw(2.0); rsi_10.reset(); - assert!(!rsi_10.is_initialized()); + assert!(!rsi_10.initialized()); assert_eq!(rsi_10.count, 0); } diff --git a/nightly/core/src/nautilus_indicators/python/average/ama.rs.html b/nightly/core/src/nautilus_indicators/python/average/ama.rs.html index 93917c1016c4..352648668fc2 100644 --- a/nightly/core/src/nautilus_indicators/python/average/ama.rs.html +++ b/nightly/core/src/nautilus_indicators/python/average/ama.rs.html @@ -1,4 +1,4 @@ -ama.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "handle_quote_tick")] diff --git a/nightly/core/src/nautilus_indicators/python/average/dema.rs.html b/nightly/core/src/nautilus_indicators/python/average/dema.rs.html index c9a35f1c14fa..501f5afd73e4 100644 --- a/nightly/core/src/nautilus_indicators/python/average/dema.rs.html +++ b/nightly/core/src/nautilus_indicators/python/average/dema.rs.html @@ -1,4 +1,4 @@ -dema.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "handle_quote_tick")] diff --git a/nightly/core/src/nautilus_indicators/python/average/ema.rs.html b/nightly/core/src/nautilus_indicators/python/average/ema.rs.html index a762f1ae15a2..1750762a44f8 100644 --- a/nightly/core/src/nautilus_indicators/python/average/ema.rs.html +++ b/nightly/core/src/nautilus_indicators/python/average/ema.rs.html @@ -1,4 +1,4 @@ -ema.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "handle_quote_tick")] diff --git a/nightly/core/src/nautilus_indicators/python/average/hma.rs.html b/nightly/core/src/nautilus_indicators/python/average/hma.rs.html index 073a865ebf1e..92766480a898 100644 --- a/nightly/core/src/nautilus_indicators/python/average/hma.rs.html +++ b/nightly/core/src/nautilus_indicators/python/average/hma.rs.html @@ -1,4 +1,4 @@ -hma.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "handle_quote_tick")] diff --git a/nightly/core/src/nautilus_indicators/python/average/mod.rs.html b/nightly/core/src/nautilus_indicators/python/average/mod.rs.html index 54f8a413fb77..c149f01db86a 100644 --- a/nightly/core/src/nautilus_indicators/python/average/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/python/average/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source use pyo3::{prelude::*, pymodule}; pub mod average; +pub mod book; pub mod momentum; pub mod ratio; pub mod volatility; @@ -71,11 +76,14 @@

    Files

    m.add_class::<crate::average::dema::DoubleExponentialMovingAverage>()?; m.add_class::<crate::average::hma::HullMovingAverage>()?; m.add_class::<crate::average::rma::WilderMovingAverage>()?; + // book + m.add_class::<crate::book::imbalance::BookImbalanceRatio>()?; // ratio m.add_class::<crate::ratio::efficiency_ratio::EfficiencyRatio>()?; // momentum m.add_class::<crate::momentum::rsi::RelativeStrengthIndex>()?; m.add_class::<crate::momentum::aroon::AroonOscillator>()?; + m.add_class::<crate::momentum::cmo::ChandeMomentumOscillator>()?; // volatility m.add_class::<crate::volatility::atr::AverageTrueRange>()?; Ok(()) diff --git a/nightly/core/src/nautilus_indicators/python/momentum/aroon.rs.html b/nightly/core/src/nautilus_indicators/python/momentum/aroon.rs.html index e295a6b7451b..f5aa87bed27a 100644 --- a/nightly/core/src/nautilus_indicators/python/momentum/aroon.rs.html +++ b/nightly/core/src/nautilus_indicators/python/momentum/aroon.rs.html @@ -1,4 +1,4 @@ -aroon.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "update_raw")] diff --git a/nightly/core/src/nautilus_indicators/python/momentum/cmo.rs.html b/nightly/core/src/nautilus_indicators/python/momentum/cmo.rs.html new file mode 100644 index 000000000000..2fb90e756bdc --- /dev/null +++ b/nightly/core/src/nautilus_indicators/python/momentum/cmo.rs.html @@ -0,0 +1,193 @@ +cmo.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +use nautilus_core::python::to_pyvalue_err;
    +use nautilus_model::data::{bar::Bar, quote::QuoteTick, trade::TradeTick};
    +use pyo3::prelude::*;
    +
    +use crate::{
    +    average::MovingAverageType, indicator::Indicator, momentum::cmo::ChandeMomentumOscillator,
    +};
    +
    +#[pymethods]
    +impl ChandeMomentumOscillator {
    +    #[new]
    +    pub fn py_new(period: usize, ma_type: Option<MovingAverageType>) -> PyResult<Self> {
    +        Self::new(period, ma_type).map_err(to_pyvalue_err)
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "name")]
    +    fn py_name(&self) -> String {
    +        self.name()
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "period")]
    +    fn py_period(&self) -> usize {
    +        self.period
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "has_inputs")]
    +    fn py_has_inputs(&self) -> bool {
    +        self.has_inputs()
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "count")]
    +    fn py_count(&self) -> usize {
    +        self.count
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "value")]
    +    fn py_value(&self) -> f64 {
    +        self.value
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "initialized")]
    +    fn py_initialized(&self) -> bool {
    +        self.initialized
    +    }
    +
    +    #[pyo3(name = "update_raw")]
    +    fn py_update_raw(&mut self, close: f64) {
    +        self.update_raw(close);
    +    }
    +
    +    #[pyo3(name = "handle_quote_tick")]
    +    fn py_handle_quote_tick(&mut self, _tick: &QuoteTick) {
    +        // Function body intentionally left blank.
    +    }
    +
    +    #[pyo3(name = "handle_trade_tick")]
    +    fn py_handle_trade_tick(&mut self, _tick: &TradeTick) {
    +        // Function body intentionally left blank.
    +    }
    +
    +    #[pyo3(name = "handle_bar")]
    +    fn py_handle_bar(&mut self, bar: &Bar) {
    +        self.update_raw((&bar.close).into());
    +    }
    +
    +    #[pyo3(name = "reset")]
    +    fn py_reset(&mut self) {
    +        self.reset();
    +    }
    +
    +    fn __repr__(&self) -> String {
    +        format!("ChandeMomentumOscillator({})", self.period)
    +    }
    +}
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/python/momentum/mod.rs.html b/nightly/core/src/nautilus_indicators/python/momentum/mod.rs.html index e7c7ff36c849..58f0a05ab6f8 100644 --- a/nightly/core/src/nautilus_indicators/python/momentum/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/python/momentum/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 15 16 17 +18
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -33,5 +34,6 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    pub mod aroon; +pub mod cmo; pub mod rsi;
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_indicators/python/momentum/rsi.rs.html b/nightly/core/src/nautilus_indicators/python/momentum/rsi.rs.html index c6a822c4f34f..04fb98c27ed9 100644 --- a/nightly/core/src/nautilus_indicators/python/momentum/rsi.rs.html +++ b/nightly/core/src/nautilus_indicators/python/momentum/rsi.rs.html @@ -1,4 +1,4 @@ -rsi.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "update_raw")] diff --git a/nightly/core/src/nautilus_indicators/python/ratio/efficiency_ratio.rs.html b/nightly/core/src/nautilus_indicators/python/ratio/efficiency_ratio.rs.html index 04c261e4baf3..5b402ae2fc0a 100644 --- a/nightly/core/src/nautilus_indicators/python/ratio/efficiency_ratio.rs.html +++ b/nightly/core/src/nautilus_indicators/python/ratio/efficiency_ratio.rs.html @@ -1,4 +1,4 @@ -efficiency_ratio.rs - source #[getter] #[pyo3(name = "initialized")] fn py_initialized(&self) -> bool { - self.is_initialized + self.initialized } #[pyo3(name = "has_inputs")] diff --git a/nightly/core/src/nautilus_indicators/python/ratio/mod.rs.html b/nightly/core/src/nautilus_indicators/python/ratio/mod.rs.html index a55a5a120fc5..4a5dbb42d2f5 100644 --- a/nightly/core/src/nautilus_indicators/python/ratio/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/python/ratio/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source fn reset(&mut self) { self.value = 0.0; self.inputs.clear(); - self.is_initialized = false; + self.initialized = false; } } @@ -317,8 +317,8 @@

    Files

    price_type: price_type.unwrap_or(PriceType::Last), value: 0.0, inputs: Vec::with_capacity(period), - _deltas: Vec::with_capacity(period), - is_initialized: false, + deltas: Vec::with_capacity(period), + initialized: false, }) } @@ -327,13 +327,13 @@

    Files

    if self.inputs.len() < 2 { self.value = 0.0; return; - } else if !self.is_initialized && self.inputs.len() >= self.period { - self.is_initialized = true; + } else if !self.initialized && self.inputs.len() >= self.period { + self.initialized = true; } let last_diff = (self.inputs[self.inputs.len() - 1] - self.inputs[self.inputs.len() - 2]).abs(); - self._deltas.push(last_diff); - let sum_deltas = self._deltas.iter().sum::<f64>().abs(); + self.deltas.push(last_diff); + let sum_deltas = self.deltas.iter().sum::<f64>().abs(); let net_diff = (self.inputs[self.inputs.len() - 1] - self.inputs[0]).abs(); self.value = if sum_deltas == 0.0 { 0.0 @@ -358,7 +358,7 @@

    Files

    let display_str = format!("{efficiency_ratio_10}"); assert_eq!(display_str, "EfficiencyRatio(10)"); assert_eq!(efficiency_ratio_10.period, 10); - assert!(!efficiency_ratio_10.is_initialized); + assert!(!efficiency_ratio_10.initialized); } #[rstest] @@ -367,10 +367,10 @@

    Files

    efficiency_ratio_10.update_raw(f64::from(i)); } assert_eq!(efficiency_ratio_10.inputs.len(), 9); - assert!(!efficiency_ratio_10.is_initialized); + assert!(!efficiency_ratio_10.initialized); efficiency_ratio_10.update_raw(1.0); assert_eq!(efficiency_ratio_10.inputs.len(), 10); - assert!(efficiency_ratio_10.is_initialized); + assert!(efficiency_ratio_10.initialized); } #[rstest] @@ -436,9 +436,9 @@

    Files

    for i in 1..=10 { efficiency_ratio_10.update_raw(f64::from(i)); } - assert!(efficiency_ratio_10.is_initialized); + assert!(efficiency_ratio_10.initialized); efficiency_ratio_10.reset(); - assert!(!efficiency_ratio_10.is_initialized); + assert!(!efficiency_ratio_10.initialized); assert_eq!(efficiency_ratio_10.value, 0.0); } diff --git a/nightly/core/src/nautilus_indicators/ratio/mod.rs.html b/nightly/core/src/nautilus_indicators/ratio/mod.rs.html index 241637d91d53..9e099a388257 100644 --- a/nightly/core/src/nautilus_indicators/ratio/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/ratio/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source
    use std::fmt::{Debug, Display}; use anyhow::Result; -use nautilus_model::data::{bar::Bar, quote::QuoteTick, trade::TradeTick}; +use nautilus_model::data::bar::Bar; use pyo3::prelude::*; use crate::{ @@ -186,10 +178,10 @@

    Files

    pub value_floor: f64, pub value: f64, pub count: usize, - pub is_initialized: bool, + pub initialized: bool, + ma: Box<dyn MovingAverage + Send + 'static>, has_inputs: bool, - _previous_close: f64, - _ma: Box<dyn MovingAverage + Send + 'static>, + previous_close: f64, } impl Display for AverageTrueRange { @@ -215,28 +207,20 @@

    Files

    self.has_inputs } - fn is_initialized(&self) -> bool { - self.is_initialized + fn initialized(&self) -> bool { + self.initialized } - fn handle_quote_tick(&mut self, _tick: &QuoteTick) { - // Function body intentionally left blank. - } - - fn handle_trade_tick(&mut self, _tick: &TradeTick) { - // Function body intentionally left blank. - } - fn handle_bar(&mut self, bar: &Bar) { self.update_raw((&bar.high).into(), (&bar.low).into(), (&bar.close).into()); } fn reset(&mut self) { - self._previous_close = 0.0; + self.previous_close = 0.0; self.value = 0.0; self.count = 0; self.has_inputs = false; - self.is_initialized = false; + self.initialized = false; } } @@ -254,24 +238,24 @@

    Files

    value_floor: value_floor.unwrap_or(0.0), value: 0.0, count: 0, - _previous_close: 0.0, - _ma: MovingAverageFactory::create(MovingAverageType::Simple, period), + previous_close: 0.0, + ma: MovingAverageFactory::create(MovingAverageType::Simple, period), has_inputs: false, - is_initialized: false, + initialized: false, }) } pub fn update_raw(&mut self, high: f64, low: f64, close: f64) { if self.use_previous { if !self.has_inputs { - self._previous_close = close; + self.previous_close = close; } - self._ma.update_raw( - f64::max(self._previous_close, high) - f64::min(low, self._previous_close), + self.ma.update_raw( + f64::max(self.previous_close, high) - f64::min(low, self.previous_close), ); - self._previous_close = close; + self.previous_close = close; } else { - self._ma.update_raw(high - low); + self.ma.update_raw(high - low); } self._floor_value(); @@ -279,8 +263,8 @@

    Files

    } fn _floor_value(&mut self) { - if self.value_floor == 0.0 || self.value_floor < self._ma.value() { - self.value = self._ma.value(); + if self.value_floor == 0.0 || self.value_floor < self.ma.value() { + self.value = self.ma.value(); } else { // Floor the value self.value = self.value_floor; @@ -290,10 +274,10 @@

    Files

    fn increment_count(&mut self) { self.count += 1; - if !self.is_initialized { + if !self.initialized { self.has_inputs = true; if self.count >= self.period { - self.is_initialized = true; + self.initialized = true; } } } diff --git a/nightly/core/src/nautilus_indicators/volatility/mod.rs.html b/nightly/core/src/nautilus_indicators/volatility/mod.rs.html index e4d0278e14ca..8bd86bf17857 100644 --- a/nightly/core/src/nautilus_indicators/volatility/mod.rs.html +++ b/nightly/core/src/nautilus_indicators/volatility/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source use anyhow::Result; use nautilus_core::uuid::UUID4; use nautilus_model::identifiers::trader_id::TraderId; -use serde_json; /// A type of database operation. #[derive(Clone, Debug)] diff --git a/nightly/core/src/nautilus_infrastructure/lib.rs.html b/nightly/core/src/nautilus_infrastructure/lib.rs.html index 40de2c044238..eccccc442d2c 100644 --- a/nightly/core/src/nautilus_infrastructure/lib.rs.html +++ b/nightly/core/src/nautilus_infrastructure/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source uuid::UUID4, }; use nautilus_model::identifiers::trader_id::TraderId; -use pyo3::{prelude::*, types::PyBytes, PyResult}; -use serde_json; +use pyo3::{prelude::*, types::PyBytes}; use crate::{cache::CacheDatabase, redis::RedisCacheDatabase}; diff --git a/nightly/core/src/nautilus_infrastructure/python/mod.rs.html b/nightly/core/src/nautilus_infrastructure/python/mod.rs.html index 06d3173f52d1..7666eec554ba 100644 --- a/nightly/core/src/nautilus_infrastructure/python/mod.rs.html +++ b/nightly/core/src/nautilus_infrastructure/python/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source #[allow(non_snake_case)] #[must_use] - pub fn CAD() -> Currency { - *CAD_LOCK.get_or_init(|| Currency { + pub fn CAD() -> Self { + *CAD_LOCK.get_or_init(|| Self { code: Ustr::from("CAD"), precision: 2, iso4217: 124, @@ -1198,8 +1198,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn CHF() -> Currency { - *CHF_LOCK.get_or_init(|| Currency { +
    pub fn CHF() -> Self { + *CHF_LOCK.get_or_init(|| Self { code: Ustr::from("CHF"), precision: 2, iso4217: 756, @@ -1210,8 +1210,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn CNY() -> Currency { - *CNY_LOCK.get_or_init(|| Currency { +
    pub fn CNY() -> Self { + *CNY_LOCK.get_or_init(|| Self { code: Ustr::from("CNY"), precision: 2, iso4217: 156, @@ -1222,8 +1222,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn CNH() -> Currency { - *CNH_LOCK.get_or_init(|| Currency { +
    pub fn CNH() -> Self { + *CNH_LOCK.get_or_init(|| Self { code: Ustr::from("CNH"), precision: 2, iso4217: 0, @@ -1234,8 +1234,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn CZK() -> Currency { - *CZK_LOCK.get_or_init(|| Currency { +
    pub fn CZK() -> Self { + *CZK_LOCK.get_or_init(|| Self { code: Ustr::from("CZK"), precision: 2, iso4217: 203, @@ -1246,8 +1246,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn DKK() -> Currency { - *DKK_LOCK.get_or_init(|| Currency { + pub fn DKK() -> Self { + *DKK_LOCK.get_or_init(|| Self { code: Ustr::from("DKK"), precision: 2, iso4217: 208, @@ -1258,8 +1258,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn EUR() -> Currency { - *EUR_LOCK.get_or_init(|| Currency { + pub fn EUR() -> Self { + *EUR_LOCK.get_or_init(|| Self { code: Ustr::from("EUR"), precision: 2, iso4217: 978, @@ -1270,8 +1270,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn GBP() -> Currency { - *GBP_LOCK.get_or_init(|| Currency { + pub fn GBP() -> Self { + *GBP_LOCK.get_or_init(|| Self { code: Ustr::from("GBP"), precision: 2, iso4217: 826, @@ -1282,8 +1282,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn HKD() -> Currency { - *HKD_LOCK.get_or_init(|| Currency { + pub fn HKD() -> Self { + *HKD_LOCK.get_or_init(|| Self { code: Ustr::from("HKD"), precision: 2, iso4217: 344, @@ -1294,8 +1294,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn HUF() -> Currency { - *HUF_LOCK.get_or_init(|| Currency { + pub fn HUF() -> Self { + *HUF_LOCK.get_or_init(|| Self { code: Ustr::from("HUF"), precision: 2, iso4217: 348, @@ -1306,8 +1306,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ILS() -> Currency { - *ILS_LOCK.get_or_init(|| Currency { + pub fn ILS() -> Self { + *ILS_LOCK.get_or_init(|| Self { code: Ustr::from("ILS"), precision: 2, iso4217: 376, @@ -1318,8 +1318,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn INR() -> Currency { - *INR_LOCK.get_or_init(|| Currency { + pub fn INR() -> Self { + *INR_LOCK.get_or_init(|| Self { code: Ustr::from("INR"), precision: 2, iso4217: 356, @@ -1330,8 +1330,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn JPY() -> Currency { - *JPY_LOCK.get_or_init(|| Currency { + pub fn JPY() -> Self { + *JPY_LOCK.get_or_init(|| Self { code: Ustr::from("JPY"), precision: 0, iso4217: 392, @@ -1341,8 +1341,8 @@

    Files

    } #[allow(non_snake_case)] #[must_use] - pub fn KRW() -> Currency { - *KRW_LOCK.get_or_init(|| Currency { + pub fn KRW() -> Self { + *KRW_LOCK.get_or_init(|| Self { code: Ustr::from("KRW"), precision: 0, iso4217: 410, @@ -1353,8 +1353,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn MXN() -> Currency { - *MXN_LOCK.get_or_init(|| Currency { + pub fn MXN() -> Self { + *MXN_LOCK.get_or_init(|| Self { code: Ustr::from("MXN"), precision: 2, iso4217: 484, @@ -1365,8 +1365,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn NOK() -> Currency { - *NOK_LOCK.get_or_init(|| Currency { + pub fn NOK() -> Self { + *NOK_LOCK.get_or_init(|| Self { code: Ustr::from("NOK"), precision: 2, iso4217: 578, @@ -1377,8 +1377,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn NZD() -> Currency { - *NZD_LOCK.get_or_init(|| Currency { + pub fn NZD() -> Self { + *NZD_LOCK.get_or_init(|| Self { code: Ustr::from("NZD"), precision: 2, iso4217: 554, @@ -1389,8 +1389,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn PLN() -> Currency { - *PLN_LOCK.get_or_init(|| Currency { + pub fn PLN() -> Self { + *PLN_LOCK.get_or_init(|| Self { code: Ustr::from("PLN"), precision: 2, iso4217: 985, @@ -1401,8 +1401,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn RUB() -> Currency { - *RUB_LOCK.get_or_init(|| Currency { + pub fn RUB() -> Self { + *RUB_LOCK.get_or_init(|| Self { code: Ustr::from("RUB"), precision: 2, iso4217: 643, @@ -1413,8 +1413,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn SAR() -> Currency { - *SAR_LOCK.get_or_init(|| Currency { + pub fn SAR() -> Self { + *SAR_LOCK.get_or_init(|| Self { code: Ustr::from("SAR"), precision: 2, iso4217: 682, @@ -1425,8 +1425,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn SEK() -> Currency { - *SEK_LOCK.get_or_init(|| Currency { + pub fn SEK() -> Self { + *SEK_LOCK.get_or_init(|| Self { code: Ustr::from("SEK"), precision: 2, iso4217: 752, @@ -1437,8 +1437,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn SGD() -> Currency { - *SGD_LOCK.get_or_init(|| Currency { + pub fn SGD() -> Self { + *SGD_LOCK.get_or_init(|| Self { code: Ustr::from("SGD"), precision: 2, iso4217: 702, @@ -1449,8 +1449,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn THB() -> Currency { - *THB_LOCK.get_or_init(|| Currency { + pub fn THB() -> Self { + *THB_LOCK.get_or_init(|| Self { code: Ustr::from("THB"), precision: 2, iso4217: 764, @@ -1461,8 +1461,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn TRY() -> Currency { - *TRY_LOCK.get_or_init(|| Currency { + pub fn TRY() -> Self { + *TRY_LOCK.get_or_init(|| Self { code: Ustr::from("TRY"), precision: 2, iso4217: 949, @@ -1473,8 +1473,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn TWD() -> Currency { - *TWD_LOCK.get_or_init(|| Currency { + pub fn TWD() -> Self { + *TWD_LOCK.get_or_init(|| Self { code: Ustr::from("TWD"), precision: 2, iso4217: 901, @@ -1485,8 +1485,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn USD() -> Currency { - *USD_LOCK.get_or_init(|| Currency { + pub fn USD() -> Self { + *USD_LOCK.get_or_init(|| Self { code: Ustr::from("USD"), precision: 2, iso4217: 840, @@ -1496,8 +1496,8 @@

    Files

    } #[allow(non_snake_case)] #[must_use] - pub fn ZAR() -> Currency { - *ZAR_LOCK.get_or_init(|| Currency { + pub fn ZAR() -> Self { + *ZAR_LOCK.get_or_init(|| Self { code: Ustr::from("ZAR"), precision: 2, iso4217: 710, @@ -1508,8 +1508,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XAG() -> Currency { - *XAG_LOCK.get_or_init(|| Currency { + pub fn XAG() -> Self { + *XAG_LOCK.get_or_init(|| Self { code: Ustr::from("XAG"), precision: 2, iso4217: 961, @@ -1520,8 +1520,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XAU() -> Currency { - *XAU_LOCK.get_or_init(|| Currency { + pub fn XAU() -> Self { + *XAU_LOCK.get_or_init(|| Self { code: Ustr::from("XAU"), precision: 2, iso4217: 959, @@ -1532,8 +1532,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XPT() -> Currency { - *XPT_LOCK.get_or_init(|| Currency { + pub fn XPT() -> Self { + *XPT_LOCK.get_or_init(|| Self { code: Ustr::from("XPT"), precision: 2, iso4217: 962, @@ -1544,8 +1544,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ONEINCH() -> Currency { - *ONEINCH_LOCK.get_or_init(|| Currency { + pub fn ONEINCH() -> Self { + *ONEINCH_LOCK.get_or_init(|| Self { code: Ustr::from("1INCH"), precision: 8, iso4217: 0, @@ -1556,8 +1556,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn AAVE() -> Currency { - *AAVE_LOCK.get_or_init(|| Currency { + pub fn AAVE() -> Self { + *AAVE_LOCK.get_or_init(|| Self { code: Ustr::from("AAVE"), precision: 8, iso4217: 0, @@ -1568,8 +1568,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ACA() -> Currency { - *ACA_LOCK.get_or_init(|| Currency { + pub fn ACA() -> Self { + *ACA_LOCK.get_or_init(|| Self { code: Ustr::from("ACA"), precision: 8, iso4217: 0, @@ -1580,8 +1580,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ADA() -> Currency { - *ADA_LOCK.get_or_init(|| Currency { + pub fn ADA() -> Self { + *ADA_LOCK.get_or_init(|| Self { code: Ustr::from("ADA"), precision: 6, iso4217: 0, @@ -1592,8 +1592,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn AVAX() -> Currency { - *AVAX_LOCK.get_or_init(|| Currency { + pub fn AVAX() -> Self { + *AVAX_LOCK.get_or_init(|| Self { code: Ustr::from("AVAX"), precision: 8, iso4217: 0, @@ -1604,8 +1604,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BCH() -> Currency { - *BCH_LOCK.get_or_init(|| Currency { + pub fn BCH() -> Self { + *BCH_LOCK.get_or_init(|| Self { code: Ustr::from("BCH"), precision: 8, iso4217: 0, @@ -1616,8 +1616,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BTC() -> Currency { - *BTC_LOCK.get_or_init(|| Currency { + pub fn BTC() -> Self { + *BTC_LOCK.get_or_init(|| Self { code: Ustr::from("BTC"), precision: 8, iso4217: 0, @@ -1628,8 +1628,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BTTC() -> Currency { - *BTTC_LOCK.get_or_init(|| Currency { + pub fn BTTC() -> Self { + *BTTC_LOCK.get_or_init(|| Self { code: Ustr::from("BTTC"), precision: 8, iso4217: 0, @@ -1640,8 +1640,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BNB() -> Currency { - *BNB_LOCK.get_or_init(|| Currency { + pub fn BNB() -> Self { + *BNB_LOCK.get_or_init(|| Self { code: Ustr::from("BNB"), precision: 8, iso4217: 0, @@ -1652,8 +1652,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BRZ() -> Currency { - *BRZ_LOCK.get_or_init(|| Currency { + pub fn BRZ() -> Self { + *BRZ_LOCK.get_or_init(|| Self { code: Ustr::from("BRZ"), precision: 6, iso4217: 0, @@ -1664,8 +1664,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BSV() -> Currency { - *BSV_LOCK.get_or_init(|| Currency { + pub fn BSV() -> Self { + *BSV_LOCK.get_or_init(|| Self { code: Ustr::from("BSV"), precision: 8, iso4217: 0, @@ -1676,8 +1676,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn BUSD() -> Currency { - *BUSD_LOCK.get_or_init(|| Currency { + pub fn BUSD() -> Self { + *BUSD_LOCK.get_or_init(|| Self { code: Ustr::from("BUSD"), precision: 8, iso4217: 0, @@ -1688,8 +1688,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn CAKE() -> Currency { - *CAKE_LOCK.get_or_init(|| Currency { + pub fn CAKE() -> Self { + *CAKE_LOCK.get_or_init(|| Self { code: Ustr::from("CAKE"), precision: 8, iso4217: 0, @@ -1700,8 +1700,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn DASH() -> Currency { - *DASH_LOCK.get_or_init(|| Currency { + pub fn DASH() -> Self { + *DASH_LOCK.get_or_init(|| Self { code: Ustr::from("DASH"), precision: 8, iso4217: 0, @@ -1712,8 +1712,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn DOT() -> Currency { - *DOT_LOCK.get_or_init(|| Currency { + pub fn DOT() -> Self { + *DOT_LOCK.get_or_init(|| Self { code: Ustr::from("DOT"), precision: 8, iso4217: 0, @@ -1724,8 +1724,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn DOGE() -> Currency { - *DOGE_LOCK.get_or_init(|| Currency { + pub fn DOGE() -> Self { + *DOGE_LOCK.get_or_init(|| Self { code: Ustr::from("DOGE"), precision: 8, iso4217: 0, @@ -1736,8 +1736,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn EOS() -> Currency { - *EOS_LOCK.get_or_init(|| Currency { + pub fn EOS() -> Self { + *EOS_LOCK.get_or_init(|| Self { code: Ustr::from("EOS"), precision: 8, iso4217: 0, @@ -1748,8 +1748,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ETH() -> Currency { - *ETH_LOCK.get_or_init(|| Currency { + pub fn ETH() -> Self { + *ETH_LOCK.get_or_init(|| Self { code: Ustr::from("ETH"), precision: 8, iso4217: 0, @@ -1760,8 +1760,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ETHW() -> Currency { - *ETHW_LOCK.get_or_init(|| Currency { + pub fn ETHW() -> Self { + *ETHW_LOCK.get_or_init(|| Self { code: Ustr::from("ETHW"), precision: 8, iso4217: 0, @@ -1772,8 +1772,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn JOE() -> Currency { - *JOE_LOCK.get_or_init(|| Currency { + pub fn JOE() -> Self { + *JOE_LOCK.get_or_init(|| Self { code: Ustr::from("JOE"), precision: 8, iso4217: 0, @@ -1784,8 +1784,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn LINK() -> Currency { - *LINK_LOCK.get_or_init(|| Currency { + pub fn LINK() -> Self { + *LINK_LOCK.get_or_init(|| Self { code: Ustr::from("LINK"), precision: 8, iso4217: 0, @@ -1796,8 +1796,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn LTC() -> Currency { - *LTC_LOCK.get_or_init(|| Currency { + pub fn LTC() -> Self { + *LTC_LOCK.get_or_init(|| Self { code: Ustr::from("LTC"), precision: 8, iso4217: 0, @@ -1808,8 +1808,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn LUNA() -> Currency { - *LUNA_LOCK.get_or_init(|| Currency { + pub fn LUNA() -> Self { + *LUNA_LOCK.get_or_init(|| Self { code: Ustr::from("LUNA"), precision: 8, iso4217: 0, @@ -1820,8 +1820,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn NBT() -> Currency { - *NBT_LOCK.get_or_init(|| Currency { + pub fn NBT() -> Self { + *NBT_LOCK.get_or_init(|| Self { code: Ustr::from("NBT"), precision: 8, iso4217: 0, @@ -1832,8 +1832,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn SOL() -> Currency { - *SOL_LOCK.get_or_init(|| Currency { + pub fn SOL() -> Self { + *SOL_LOCK.get_or_init(|| Self { code: Ustr::from("SOL"), precision: 8, iso4217: 0, @@ -1844,8 +1844,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn SHIB() -> Currency { - *SHIB_LOCK.get_or_init(|| Currency { + pub fn SHIB() -> Self { + *SHIB_LOCK.get_or_init(|| Self { code: Ustr::from("SHIB"), precision: 8, iso4217: 0, @@ -1856,8 +1856,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn TRX() -> Currency { - *TRX_LOCK.get_or_init(|| Currency { + pub fn TRX() -> Self { + *TRX_LOCK.get_or_init(|| Self { code: Ustr::from("TRX"), precision: 8, iso4217: 0, @@ -1868,8 +1868,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn TRYB() -> Currency { - *TRYB_LOCK.get_or_init(|| Currency { + pub fn TRYB() -> Self { + *TRYB_LOCK.get_or_init(|| Self { code: Ustr::from("TRYB"), precision: 8, iso4217: 0, @@ -1880,8 +1880,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn TUSD() -> Currency { - *TUSD_LOCK.get_or_init(|| Currency { + pub fn TUSD() -> Self { + *TUSD_LOCK.get_or_init(|| Self { code: Ustr::from("TUSD"), precision: 8, iso4217: 0, @@ -1892,8 +1892,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn VTC() -> Currency { - *VTC_LOCK.get_or_init(|| Currency { + pub fn VTC() -> Self { + *VTC_LOCK.get_or_init(|| Self { code: Ustr::from("VTC"), precision: 8, iso4217: 0, @@ -1904,8 +1904,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn WSB() -> Currency { - *WSB_LOCK.get_or_init(|| Currency { + pub fn WSB() -> Self { + *WSB_LOCK.get_or_init(|| Self { code: Ustr::from("WSB"), precision: 8, iso4217: 0, @@ -1916,8 +1916,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XBT() -> Currency { - *XBT_LOCK.get_or_init(|| Currency { + pub fn XBT() -> Self { + *XBT_LOCK.get_or_init(|| Self { code: Ustr::from("XBT"), precision: 8, iso4217: 0, @@ -1928,8 +1928,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XEC() -> Currency { - *XEC_LOCK.get_or_init(|| Currency { + pub fn XEC() -> Self { + *XEC_LOCK.get_or_init(|| Self { code: Ustr::from("XEC"), precision: 8, iso4217: 0, @@ -1940,8 +1940,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XLM() -> Currency { - *XLM_LOCK.get_or_init(|| Currency { + pub fn XLM() -> Self { + *XLM_LOCK.get_or_init(|| Self { code: Ustr::from("XLM"), precision: 8, iso4217: 0, @@ -1952,8 +1952,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XMR() -> Currency { - *XMR_LOCK.get_or_init(|| Currency { + pub fn XMR() -> Self { + *XMR_LOCK.get_or_init(|| Self { code: Ustr::from("XMR"), precision: 8, iso4217: 0, @@ -1964,8 +1964,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn USDT() -> Currency { - *USDT_LOCK.get_or_init(|| Currency { + pub fn USDT() -> Self { + *USDT_LOCK.get_or_init(|| Self { code: Ustr::from("USDT"), precision: 8, iso4217: 0, @@ -1976,8 +1976,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XRP() -> Currency { - *XRP_LOCK.get_or_init(|| Currency { + pub fn XRP() -> Self { + *XRP_LOCK.get_or_init(|| Self { code: Ustr::from("XRP"), precision: 6, iso4217: 0, @@ -1988,8 +1988,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn XTZ() -> Currency { - *XTZ_LOCK.get_or_init(|| Currency { + pub fn XTZ() -> Self { + *XTZ_LOCK.get_or_init(|| Self { code: Ustr::from("XTZ"), precision: 6, iso4217: 0, @@ -2000,8 +2000,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn USDC() -> Currency { - *USDC_LOCK.get_or_init(|| Currency { + pub fn USDC() -> Self { + *USDC_LOCK.get_or_init(|| Self { code: Ustr::from("USDC"), precision: 8, iso4217: 0, @@ -2012,8 +2012,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn USDP() -> Currency { - *USDP_LOCK.get_or_init(|| Currency { + pub fn USDP() -> Self { + *USDP_LOCK.get_or_init(|| Self { code: Ustr::from("USDP"), precision: 4, iso4217: 0, @@ -2024,8 +2024,8 @@

    Files

    #[allow(non_snake_case)] #[must_use] - pub fn ZEC() -> Currency { - *ZEC_LOCK.get_or_init(|| Currency { + pub fn ZEC() -> Self { + *ZEC_LOCK.get_or_init(|| Self { code: Ustr::from("ZEC"), precision: 8, iso4217: 0, diff --git a/nightly/core/src/nautilus_model/data/bar.rs.html b/nightly/core/src/nautilus_model/data/bar.rs.html index 4fcf592f5de5..31efe65f5245 100644 --- a/nightly/core/src/nautilus_model/data/bar.rs.html +++ b/nightly/core/src/nautilus_model/data/bar.rs.html @@ -1,4 +1,4 @@ -bar.rs - source 616 617 618 +619
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -644,7 +645,6 @@ 

    Files

    use nautilus_core::{serialization::Serializable, time::UnixNanos}; use pyo3::prelude::*; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use thiserror; use crate::{ enums::{AggregationSource, BarAggregation, PriceType}, @@ -738,7 +738,7 @@

    Files

    if rev_pieces.len() != 5 { return Err(BarTypeParseError { input: s.to_string(), - token: "".to_string(), + token: String::new(), position: 0, }); } @@ -773,7 +773,7 @@

    Files

    position: 4, })?; - Ok(BarType { + Ok(Self { instrument_id, spec: BarSpecification { step, @@ -816,7 +816,7 @@

    Files

    D: Deserializer<'de>, { let s: String = Deserialize::deserialize(deserializer)?; - BarType::from_str(&s).map_err(serde::de::Error::custom) + Self::from_str(&s).map_err(serde::de::Error::custom) } } @@ -873,6 +873,7 @@

    Files

    } /// Returns the metadata for the type, for use with serialization formats. + #[must_use] pub fn get_metadata( bar_type: &BarType, price_precision: u8, @@ -888,6 +889,7 @@

    Files

    } /// Returns the field map for the type, for use with Arrow schemas. + #[must_use] pub fn get_fields() -> IndexMap<String, String> { let mut metadata = IndexMap::new(); metadata.insert("open".to_string(), "Int64".to_string()); diff --git a/nightly/core/src/nautilus_model/data/delta.rs.html b/nightly/core/src/nautilus_model/data/delta.rs.html index 6dd95c45172e..2165b6a4ebf8 100644 --- a/nightly/core/src/nautilus_model/data/delta.rs.html +++ b/nightly/core/src/nautilus_model/data/delta.rs.html @@ -1,4 +1,4 @@ -delta.rs - source 336 337 338 +339 +340
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -440,6 +442,7 @@ 

    Files

    } /// Returns the metadata for the type, for use with serialization formats. + #[must_use] pub fn get_metadata( instrument_id: &InstrumentId, price_precision: u8, @@ -453,6 +456,7 @@

    Files

    } /// Returns the field map for the type, for use with Arrow schemas. + #[must_use] pub fn get_fields() -> IndexMap<String, String> { let mut metadata = IndexMap::new(); metadata.insert("action".to_string(), "UInt8".to_string()); @@ -548,7 +552,7 @@

    Files

    pub mod stubs { use rstest::fixture; - use super::*; + use super::{BookAction, BookOrder, OrderBookDelta, OrderSide}; use crate::{ identifiers::instrument_id::InstrumentId, types::{price::Price, quantity::Quantity}, @@ -561,7 +565,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let flags = 0; let sequence = 1; let ts_event = 1; @@ -600,7 +604,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let flags = 0; let sequence = 1; let ts_event = 1; @@ -655,7 +659,7 @@

    Files

    fn test_display(stub_delta: OrderBookDelta) { let delta = stub_delta; assert_eq!( - format!("{}", delta), + format!("{delta}"), "AAPL.XNAS,ADD,100.00,10,BUY,123456,0,1,1,2".to_string() ); } diff --git a/nightly/core/src/nautilus_model/data/deltas.rs.html b/nightly/core/src/nautilus_model/data/deltas.rs.html index b58e3f2bf9b7..b3c1bac1bac4 100644 --- a/nightly/core/src/nautilus_model/data/deltas.rs.html +++ b/nightly/core/src/nautilus_model/data/deltas.rs.html @@ -1,4 +1,4 @@ -deltas.rs - source pub mod stubs { use rstest::fixture; - use super::*; + use super::OrderBookDeltas; use crate::{ data::{delta::OrderBookDelta, order::BookOrder}, enums::{BookAction, OrderSide}, @@ -695,7 +695,7 @@

    Files

    fn test_display(stub_deltas: OrderBookDeltas) { let deltas = stub_deltas; assert_eq!( - format!("{}", deltas), + format!("{deltas}"), "AAPL.XNAS,len=7,flags=32,sequence=0,ts_event=1,ts_init=2".to_string() ); } diff --git a/nightly/core/src/nautilus_model/data/depth.rs.html b/nightly/core/src/nautilus_model/data/depth.rs.html index 43e8d1006740..37944353fd36 100644 --- a/nightly/core/src/nautilus_model/data/depth.rs.html +++ b/nightly/core/src/nautilus_model/data/depth.rs.html @@ -1,4 +1,4 @@ -depth.rs - source 317 318 319 +320 +321
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -413,6 +415,7 @@ 

    Files

    } /// Returns the metadata for the type, for use with serialization formats. + #[must_use] pub fn get_metadata( instrument_id: &InstrumentId, price_precision: u8, @@ -426,6 +429,7 @@

    Files

    } /// Returns the field map for the type, for use with Arrow schemas. + #[must_use] pub fn get_fields() -> IndexMap<String, String> { let mut metadata = IndexMap::new(); metadata.insert("bid_price_0".to_string(), "Int64".to_string()); @@ -517,7 +521,7 @@

    Files

    pub mod stubs { use rstest::fixture; - use super::*; + use super::{OrderBookDepth10, DEPTH10_LEN}; use crate::{ data::order::BookOrder, enums::OrderSide, @@ -633,7 +637,7 @@

    Files

    fn test_display(stub_depth10: OrderBookDepth10) { let depth = stub_depth10; assert_eq!( - format!("{}", depth), + format!("{depth}"), "AAPL.XNAS,flags=0,sequence=0,ts_event=1,ts_init=2".to_string() ); } diff --git a/nightly/core/src/nautilus_model/data/mod.rs.html b/nightly/core/src/nautilus_model/data/mod.rs.html index d078ba0a4d9c..ad99e560c51a 100644 --- a/nightly/core/src/nautilus_model/data/mod.rs.html +++ b/nightly/core/src/nautilus_model/data/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 139 140 141 -142
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -167,12 +166,11 @@ 

    Files

    use nautilus_core::time::UnixNanos; -use crate::ffi::data::deltas::OrderBookDeltas_API; - use self::{ bar::Bar, delta::OrderBookDelta, deltas::OrderBookDeltas, depth::OrderBookDepth10, quote::QuoteTick, trade::TradeTick, }; +use crate::ffi::data::deltas::OrderBookDeltas_API; #[repr(C)] #[derive(Clone, Debug)] @@ -193,12 +191,12 @@

    Files

    impl HasTsInit for Data { fn get_ts_init(&self) -> UnixNanos { match self { - Data::Delta(d) => d.ts_init, - Data::Deltas(d) => d.ts_init, - Data::Depth10(d) => d.ts_init, - Data::Quote(q) => q.ts_init, - Data::Trade(t) => t.ts_init, - Data::Bar(b) => b.ts_init, + Self::Delta(d) => d.ts_init, + Self::Deltas(d) => d.ts_init, + Self::Depth10(d) => d.ts_init, + Self::Quote(q) => q.ts_init, + Self::Trade(t) => t.ts_init, + Self::Bar(b) => b.ts_init, } } } diff --git a/nightly/core/src/nautilus_model/data/order.rs.html b/nightly/core/src/nautilus_model/data/order.rs.html index 83145242f93b..7ee0833ee034 100644 --- a/nightly/core/src/nautilus_model/data/order.rs.html +++ b/nightly/core/src/nautilus_model/data/order.rs.html @@ -1,4 +1,4 @@ -order.rs - source
    pub mod stubs { use rstest::fixture; - use super::*; + use super::{BookOrder, OrderSide}; use crate::types::{price::Price, quantity::Quantity}; #[fixture] @@ -522,7 +522,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; BookOrder::new(side, price, size, order_id) } @@ -546,7 +546,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let order = BookOrder::new(side, price, size, order_id); @@ -561,7 +561,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let order = BookOrder::new(side, price, size, order_id); let book_price = order.to_book_price(); @@ -575,7 +575,7 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from("10"); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let order = BookOrder::new(side, price, size, order_id); let exposure = order.exposure(); @@ -587,7 +587,7 @@

    Files

    fn test_signed_size() { let price = Price::from("100.00"); let size = Quantity::from("10"); - let order_id = 123456; + let order_id = 123_456; let order_buy = BookOrder::new(OrderSide::Buy, price, size, order_id); let signed_size_buy = order_buy.signed_size(); @@ -603,12 +603,12 @@

    Files

    let price = Price::from("100.00"); let size = Quantity::from(10); let side = OrderSide::Buy; - let order_id = 123456; + let order_id = 123_456; let order = BookOrder::new(side, price, size, order_id); - let display = format!("{}", order); + let display = format!("{order}"); - let expected = format!("{},{},{},{}", price, size, side, order_id); + let expected = format!("{price},{size},{side},{order_id}"); assert_eq!(display, expected); } diff --git a/nightly/core/src/nautilus_model/data/quote.rs.html b/nightly/core/src/nautilus_model/data/quote.rs.html index f63ccb391346..ebedf3c6f91c 100644 --- a/nightly/core/src/nautilus_model/data/quote.rs.html +++ b/nightly/core/src/nautilus_model/data/quote.rs.html @@ -1,4 +1,4 @@ -quote.rs - source 297 298 299 +300 +301
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -397,6 +399,7 @@ 

    Files

    } /// Returns the metadata for the type, for use with serialization formats. + #[must_use] pub fn get_metadata( instrument_id: &InstrumentId, price_precision: u8, @@ -410,6 +413,7 @@

    Files

    } /// Returns the field map for the type, for use with Arrow schemas. + #[must_use] pub fn get_fields() -> IndexMap<String, String> { let mut metadata = IndexMap::new(); metadata.insert("bid_price".to_string(), "Int64".to_string()); diff --git a/nightly/core/src/nautilus_model/data/trade.rs.html b/nightly/core/src/nautilus_model/data/trade.rs.html index fd2ed121ad07..95e6bb67aba0 100644 --- a/nightly/core/src/nautilus_model/data/trade.rs.html +++ b/nightly/core/src/nautilus_model/data/trade.rs.html @@ -1,4 +1,4 @@ -trade.rs - source 255 256 257 +258 +259
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -339,6 +341,7 @@ 

    Files

    } /// Returns the metadata for the type, for use with serialization formats. + #[must_use] pub fn get_metadata( instrument_id: &InstrumentId, price_precision: u8, @@ -352,6 +355,7 @@

    Files

    } /// Returns the field map for the type, for use with Arrow schemas. + #[must_use] pub fn get_fields() -> IndexMap<String, String> { let mut metadata = IndexMap::new(); metadata.insert("price".to_string(), "Int64".to_string()); @@ -461,9 +465,9 @@

    Files

    #[rstest] fn test_to_string(stub_trade_tick_ethusdt_buyer: TradeTick) { - let tick = stub_trade_tick_ethusdt_buyer; + let trade = stub_trade_tick_ethusdt_buyer; assert_eq!( - tick.to_string(), + trade.to_string(), "ETHUSDT-PERP.BINANCE,10000.0000,1.00000000,BUYER,123456789,0" ); } @@ -481,37 +485,37 @@

    Files

    "ts_init": 1 }"#
    ; - let tick: TradeTick = serde_json::from_str(raw_string).unwrap(); + let trade: TradeTick = serde_json::from_str(raw_string).unwrap(); - assert_eq!(tick.aggressor_side, AggressorSide::Buyer); + assert_eq!(trade.aggressor_side, AggressorSide::Buyer); } #[rstest] fn test_from_pyobject(stub_trade_tick_ethusdt_buyer: TradeTick) { pyo3::prepare_freethreaded_python(); - let tick = stub_trade_tick_ethusdt_buyer; + let trade = stub_trade_tick_ethusdt_buyer; Python::with_gil(|py| { - let tick_pyobject = tick.into_py(py); + let tick_pyobject = trade.into_py(py); let parsed_tick = TradeTick::from_pyobject(tick_pyobject.as_ref(py)).unwrap(); - assert_eq!(parsed_tick, tick); + assert_eq!(parsed_tick, trade); }); } #[rstest] fn test_json_serialization(stub_trade_tick_ethusdt_buyer: TradeTick) { - let tick = stub_trade_tick_ethusdt_buyer; - let serialized = tick.as_json_bytes().unwrap(); + let trade = stub_trade_tick_ethusdt_buyer; + let serialized = trade.as_json_bytes().unwrap(); let deserialized = TradeTick::from_json_bytes(serialized).unwrap(); - assert_eq!(deserialized, tick); + assert_eq!(deserialized, trade); } #[rstest] fn test_msgpack_serialization(stub_trade_tick_ethusdt_buyer: TradeTick) { - let tick = stub_trade_tick_ethusdt_buyer; - let serialized = tick.as_msgpack_bytes().unwrap(); + let trade = stub_trade_tick_ethusdt_buyer; + let serialized = trade.as_msgpack_bytes().unwrap(); let deserialized = TradeTick::from_msgpack_bytes(serialized).unwrap(); - assert_eq!(deserialized, tick); + assert_eq!(deserialized, trade); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/enums.rs.html b/nightly/core/src/nautilus_model/enums.rs.html index e2de5f99df16..57f9b79c51ca 100644 --- a/nightly/core/src/nautilus_model/enums.rs.html +++ b/nightly/core/src/nautilus_model/enums.rs.html @@ -1,4 +1,4 @@ -enums.rs - source impl FromU8 for AggressorSide { fn from_u8(value: u8) -> Option<Self> { match value { - 0 => Some(AggressorSide::NoAggressor), - 1 => Some(AggressorSide::Buyer), - 2 => Some(AggressorSide::Seller), + 0 => Some(Self::NoAggressor), + 1 => Some(Self::Buyer), + 2 => Some(Self::Seller), _ => None, } } @@ -1551,10 +1551,10 @@

    Files

    impl FromU8 for BookAction { fn from_u8(value: u8) -> Option<Self> { match value { - 1 => Some(BookAction::Add), - 2 => Some(BookAction::Update), - 3 => Some(BookAction::Delete), - 4 => Some(BookAction::Clear), + 1 => Some(Self::Add), + 2 => Some(Self::Update), + 3 => Some(Self::Delete), + 4 => Some(Self::Clear), _ => None, } } @@ -1596,9 +1596,9 @@

    Files

    impl FromU8 for BookType { fn from_u8(value: u8) -> Option<Self> { match value { - 1 => Some(BookType::L1_MBP), - 2 => Some(BookType::L2_MBP), - 3 => Some(BookType::L3_MBO), + 1 => Some(Self::L1_MBP), + 2 => Some(Self::L2_MBP), + 3 => Some(Self::L3_MBO), _ => None, } } @@ -1935,9 +1935,9 @@

    Files

    impl FromU8 for OrderSide { fn from_u8(value: u8) -> Option<Self> { match value { - 0 => Some(OrderSide::NoOrderSide), - 1 => Some(OrderSide::Buy), - 2 => Some(OrderSide::Sell), + 0 => Some(Self::NoOrderSide), + 1 => Some(Self::Buy), + 2 => Some(Self::Sell), _ => None, } } diff --git a/nightly/core/src/nautilus_model/events/account/mod.rs.html b/nightly/core/src/nautilus_model/events/account/mod.rs.html index 2ed6644eb27d..87debd667646 100644 --- a/nightly/core/src/nautilus_model/events/account/mod.rs.html +++ b/nightly/core/src/nautilus_model/events/account/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source ts_event: UnixNanos, ts_init: UnixNanos, base_currency: Option<Currency>, - ) -> Result<AccountState> { - Ok(AccountState { + ) -> Result<Self> { + Ok(Self { account_id, account_type, base_currency, @@ -227,12 +225,10 @@

    Files

    "AccountState(account_id={}, account_type={}, base_currency={}, is_reported={}, balances=[{}], margins=[{}], event_id={})", self.account_id, self.account_type, - self.base_currency - .map(|base_currency | format!("{}", base_currency.code)) - .unwrap_or_else(|| "None".to_string()), + self.base_currency.map_or_else(|| "None".to_string(), |base_currency | format!("{}", base_currency.code)), self.is_reported, - self.balances.iter().map(|b| format!("{}", b)).collect::<Vec<String>>().join(","), - self.margins.iter().map(|m| format!("{}", m)).collect::<Vec<String>>().join(","), + self.balances.iter().map(|b| format!("{b}")).collect::<Vec<String>>().join(","), + self.margins.iter().map(|m| format!("{m}")).collect::<Vec<String>>().join(","), self.event_id ) } @@ -267,7 +263,7 @@

    Files

    #[rstest] fn test_display_cash_account_state(cash_account_state: AccountState) { - let display = format!("{}", cash_account_state); + let display = format!("{cash_account_state}"); assert_eq!( display, "AccountState(account_id=SIM-001, account_type=CASH, base_currency=USD, is_reported=true, \ @@ -278,7 +274,7 @@

    Files

    #[rstest] fn test_display_margin_account_state(margin_account_state: AccountState) { - let display = format!("{}", margin_account_state); + let display = format!("{margin_account_state}"); assert_eq!( display, "AccountState(account_id=SIM-001, account_type=MARGIN, base_currency=USD, is_reported=true, \ diff --git a/nightly/core/src/nautilus_model/events/account/stubs.rs.html b/nightly/core/src/nautilus_model/events/account/stubs.rs.html index a2aacde6a4f6..799c534a7a4f 100644 --- a/nightly/core/src/nautilus_model/events/account/stubs.rs.html +++ b/nightly/core/src/nautilus_model/events/account/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source use rstest::fixture; -use crate::types::balance::AccountBalance; -use crate::types::money::Money; use crate::{ enums::AccountType, events::account::state::AccountState, identifiers::stubs::{account_id, uuid4}, types::{ + balance::AccountBalance, currency::Currency, + money::Money, stubs::{account_balance_test, margin_balance_test}, }, }; diff --git a/nightly/core/src/nautilus_model/events/mod.rs.html b/nightly/core/src/nautilus_model/events/mod.rs.html index 619358d77a61..ed9cfdd0c08e 100644 --- a/nightly/core/src/nautilus_model/events/mod.rs.html +++ b/nightly/core/src/nautilus_model/events/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source ts_event: UnixNanos, ts_init: UnixNanos, reconciliation: bool, - ) -> Result<OrderAccepted> { - Ok(OrderAccepted { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -184,7 +184,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), }) } } @@ -215,7 +215,7 @@

    Files

    #[rstest] fn test_order_accepted_display(order_accepted: OrderAccepted) { - let display = format!("{}", order_accepted); + let display = format!("{order_accepted}"); assert_eq!( display, "OrderAccepted(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/cancel_rejected.rs.html b/nightly/core/src/nautilus_model/events/order/cancel_rejected.rs.html index 4308a34de0ba..87014984e19b 100644 --- a/nightly/core/src/nautilus_model/events/order/cancel_rejected.rs.html +++ b/nightly/core/src/nautilus_model/events/order/cancel_rejected.rs.html @@ -1,4 +1,4 @@ -cancel_rejected.rs - source 114 115 116 -117 -118 -119 -120
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -138,7 +134,7 @@ 

    Files

    use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -185,8 +181,8 @@

    Files

    reconciliation: bool, venue_order_id: Option<VenueOrderId>, account_id: Option<AccountId>, - ) -> Result<OrderCancelRejected> { - Ok(OrderCancelRejected { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -195,7 +191,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, }) @@ -209,12 +205,8 @@

    Files

    "OrderCancelRejected(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={}, reason={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.reason, self.ts_event ) @@ -233,7 +225,7 @@

    Files

    #[rstest] fn test_order_cancel_rejected(order_cancel_rejected: OrderCancelRejected) { - let display = format!("{}", order_cancel_rejected); + let display = format!("{order_cancel_rejected}"); assert_eq!( display, "OrderCancelRejected(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001, reason=ORDER_DOES_NOT_EXISTS, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/canceled.rs.html b/nightly/core/src/nautilus_model/events/order/canceled.rs.html index a5b389296b81..e1b279b4e9b6 100644 --- a/nightly/core/src/nautilus_model/events/order/canceled.rs.html +++ b/nightly/core/src/nautilus_model/events/order/canceled.rs.html @@ -1,4 +1,4 @@ -canceled.rs - source 95 96 97 -98 -99 -100 -101
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -119,7 +115,7 @@ 

    Files

    use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -172,7 +168,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, }) @@ -186,12 +182,8 @@

    Files

    "OrderCanceled(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.ts_event ) } diff --git a/nightly/core/src/nautilus_model/events/order/denied.rs.html b/nightly/core/src/nautilus_model/events/order/denied.rs.html index 647f19d052bb..5973c142e5ea 100644 --- a/nightly/core/src/nautilus_model/events/order/denied.rs.html +++ b/nightly/core/src/nautilus_model/events/order/denied.rs.html @@ -1,4 +1,4 @@ -denied.rs - source use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -158,8 +158,8 @@

    Files

    event_id: UUID4, ts_event: UnixNanos, ts_init: UnixNanos, - ) -> Result<OrderDenied> { - Ok(OrderDenied { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -194,7 +194,7 @@

    Files

    #[rstest] fn test_order_denied_display(order_denied_max_submitted_rate: OrderDenied) { - let display = format!("{}", order_denied_max_submitted_rate); + let display = format!("{order_denied_max_submitted_rate}"); assert_eq!(display, "OrderDenied(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1,reason=Exceeded MAX_ORDER_SUBMIT_RATE)"); } } diff --git a/nightly/core/src/nautilus_model/events/order/emulated.rs.html b/nightly/core/src/nautilus_model/events/order/emulated.rs.html index 7fa13112e52d..1ea7e086de25 100644 --- a/nightly/core/src/nautilus_model/events/order/emulated.rs.html +++ b/nightly/core/src/nautilus_model/events/order/emulated.rs.html @@ -1,4 +1,4 @@ -emulated.rs - source use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -153,8 +153,8 @@

    Files

    event_id: UUID4, ts_event: UnixNanos, ts_init: UnixNanos, - ) -> Result<OrderEmulated> { - Ok(OrderEmulated { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -187,7 +187,7 @@

    Files

    #[rstest] fn test_order_emulated(order_emulated: OrderEmulated) { - let display = format!("{}", order_emulated); + let display = format!("{order_emulated}"); assert_eq!( display, "OrderEmulated(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1)" diff --git a/nightly/core/src/nautilus_model/events/order/event.rs.html b/nightly/core/src/nautilus_model/events/order/event.rs.html index 140606193fb0..5223ade789e8 100644 --- a/nightly/core/src/nautilus_model/events/order/event.rs.html +++ b/nightly/core/src/nautilus_model/events/order/event.rs.html @@ -1,4 +1,4 @@ -event.rs - source use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -186,7 +182,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, }) @@ -200,12 +196,8 @@

    Files

    "OrderExpired(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.ts_event ) } @@ -223,7 +215,7 @@

    Files

    #[rstest] fn test_order_cancel_rejected(order_expired: OrderExpired) { - let display = format!("{}", order_expired); + let display = format!("{order_expired}"); assert_eq!( display, "OrderExpired(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/filled.rs.html b/nightly/core/src/nautilus_model/events/order/filled.rs.html index 3bf69a7f9c4f..c985e63a8164 100644 --- a/nightly/core/src/nautilus_model/events/order/filled.rs.html +++ b/nightly/core/src/nautilus_model/events/order/filled.rs.html @@ -1,4 +1,4 @@ -filled.rs - source 222 223 224 +225 +226
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -242,7 +244,7 @@ 

    Files

    use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -328,8 +330,8 @@

    Files

    reconciliation: bool, position_id: Option<PositionId>, commission: Option<Money>, - ) -> Result<OrderFilled> { - Ok(OrderFilled { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -352,11 +354,13 @@

    Files

    }) } - pub fn is_buy(&self) -> bool { + #[must_use] + pub fn is_buy(&self) -> bool { self.order_side == OrderSide::Buy } - pub fn is_sell(&self) -> bool { + #[must_use] + pub fn is_sell(&self) -> bool { self.order_side == OrderSide::Sell } } @@ -433,13 +437,13 @@

    Files

    #[rstest] fn test_order_filled_display(order_filled: OrderFilled) { - let display = format!("{}", order_filled); + let display = format!("{order_filled}"); assert_eq!( display, "OrderFilled(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, \ venue_order_id=123456, account_id=SIM-001, trade_id=1, position_id=P-001, \ order_side=BUY, order_type=LIMIT, last_qty=0.561, last_px=22000, \ - commission=12.20000000 USDT ,liquidity_side=TAKER, ts_event=0)") + commission=12.20000000 USDT ,liquidity_side=TAKER, ts_event=0)"); } #[rstest] diff --git a/nightly/core/src/nautilus_model/events/order/initialized.rs.html b/nightly/core/src/nautilus_model/events/order/initialized.rs.html index 80752c31a4cc..73a355d00b8c 100644 --- a/nightly/core/src/nautilus_model/events/order/initialized.rs.html +++ b/nightly/core/src/nautilus_model/events/order/initialized.rs.html @@ -1,4 +1,4 @@ -initialized.rs - source 292 293 294 +295 +296 +297
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -315,7 +318,7 @@ 

    Files

    }; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -451,8 +454,8 @@

    Files

    exec_algorithm_params: Option<HashMap<Ustr, Ustr>>, exec_spawn_id: Option<ClientOrderId>, tags: Option<Ustr>, - ) -> Result<OrderInitialized> { - Ok(OrderInitialized { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -525,45 +528,48 @@

    Files

    self.reduce_only, self.quote_quantity, self.price - .map(|price| format!("{}", price)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |price| format!("{price}")), self.emulation_trigger - .map(|trigger| format!("{}", trigger)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |trigger| format!("{trigger}")), self.trigger_instrument_id - .map(|instrument_id| format!("{}", instrument_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |instrument_id| format!( + "{instrument_id}" + )), self.contingency_type - .map(|contingency_type| format!("{}", contingency_type)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |contingency_type| format!( + "{contingency_type}" + )), self.order_list_id - .map(|order_list_id| format!("{}", order_list_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |order_list_id| format!( + "{order_list_id}" + )), self.linked_order_ids .as_ref() - .map(|linked_order_ids| linked_order_ids + .map_or("None".to_string(), |linked_order_ids| linked_order_ids .iter() .map(ToString::to_string) .collect::<Vec<_>>() - .join(", ")) - .unwrap_or("None".to_string()), + .join(", ")), self.parent_order_id - .map(|parent_order_id| format!("{}", parent_order_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |parent_order_id| format!( + "{parent_order_id}" + )), self.exec_algorithm_id - .map(|exec_algorithm_id| format!("{}", exec_algorithm_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_algorithm_id| format!( + "{exec_algorithm_id}" + )), self.exec_algorithm_params .as_ref() - .map(|exec_algorithm_params| format!("{:?}", exec_algorithm_params)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_algorithm_params| format!( + "{exec_algorithm_params:?}" + )), self.exec_spawn_id - .map(|exec_spawn_id| format!("{}", exec_spawn_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_spawn_id| format!( + "{exec_spawn_id}" + )), self.tags .as_ref() - .map(|tags| format!("{}", tags)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |tags| format!("{tags}")), ) } } @@ -578,7 +584,7 @@

    Files

    use crate::events::order::{initialized::OrderInitialized, stubs::*}; #[rstest] fn test_order_initialized(order_initialized_buy_limit: OrderInitialized) { - let display = format!("{}", order_initialized_buy_limit); + let display = format!("{order_initialized_buy_limit}"); assert_eq!( display, "OrderInitialized(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, \ diff --git a/nightly/core/src/nautilus_model/events/order/mod.rs.html b/nightly/core/src/nautilus_model/events/order/mod.rs.html index 6d642c6b36aa..6c758ced8f22 100644 --- a/nightly/core/src/nautilus_model/events/order/mod.rs.html +++ b/nightly/core/src/nautilus_model/events/order/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -195,7 +191,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, }) @@ -209,12 +205,8 @@

    Files

    "OrderModifyRejected(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={},reason={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.reason, self.ts_event ) @@ -232,7 +224,7 @@

    Files

    #[rstest] fn test_order_modified_rejected(order_modify_rejected: OrderModifyRejected) { - let display = format!("{}", order_modify_rejected); + let display = format!("{order_modify_rejected}"); assert_eq!( display, "OrderModifyRejected(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, \ diff --git a/nightly/core/src/nautilus_model/events/order/pending_cancel.rs.html b/nightly/core/src/nautilus_model/events/order/pending_cancel.rs.html index 13a9f603f0bd..2b485d0d3de9 100644 --- a/nightly/core/src/nautilus_model/events/order/pending_cancel.rs.html +++ b/nightly/core/src/nautilus_model/events/order/pending_cancel.rs.html @@ -1,4 +1,4 @@ -pending_cancel.rs - source 108 109 110 -111 -112
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -130,7 +128,7 @@ 

    Files

    use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -184,7 +182,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, }) } @@ -197,9 +195,7 @@

    Files

    "OrderPendingCancel(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.ts_event ) @@ -217,7 +213,7 @@

    Files

    #[rstest] fn test_order_pending_cancel_display(order_pending_cancel: OrderPendingCancel) { - let display = format!("{}", order_pending_cancel); + let display = format!("{order_pending_cancel}"); assert_eq!( display, "OrderPendingCancel(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/pending_update.rs.html b/nightly/core/src/nautilus_model/events/order/pending_update.rs.html index 686fb2c61e5d..25c81046b812 100644 --- a/nightly/core/src/nautilus_model/events/order/pending_update.rs.html +++ b/nightly/core/src/nautilus_model/events/order/pending_update.rs.html @@ -1,4 +1,4 @@ -pending_update.rs - source 108 109 110 -111 -112
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -130,7 +128,7 @@ 

    Files

    use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -184,7 +182,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, }) } @@ -197,9 +195,7 @@

    Files

    "OrderPendingUpdate(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.ts_event ) @@ -217,7 +213,7 @@

    Files

    #[rstest] fn test_order_pending_update_display(order_pending_update: OrderPendingUpdate) { - let display = format!("{}", order_pending_update); + let display = format!("{order_pending_update}"); assert_eq!( display, "OrderPendingUpdate(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/rejected.rs.html b/nightly/core/src/nautilus_model/events/order/rejected.rs.html index f2d6a6f13449..91c1ac3b997d 100644 --- a/nightly/core/src/nautilus_model/events/order/rejected.rs.html +++ b/nightly/core/src/nautilus_model/events/order/rejected.rs.html @@ -1,4 +1,4 @@ -rejected.rs - source use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -169,8 +169,8 @@

    Files

    ts_event: UnixNanos, ts_init: UnixNanos, reconciliation: bool, - ) -> Result<OrderRejected> { - Ok(OrderRejected { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -180,7 +180,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), }) } } @@ -207,7 +207,7 @@

    Files

    #[rstest] fn test_order_rejected_display(order_rejected_insufficient_margin: OrderRejected) { - let display = format!("{}", order_rejected_insufficient_margin); + let display = format!("{order_rejected_insufficient_margin}"); assert_eq!(display, "OrderRejected(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, \ reason=INSUFFICIENT_MARGIN, ts_event=0)"); } diff --git a/nightly/core/src/nautilus_model/events/order/released.rs.html b/nightly/core/src/nautilus_model/events/order/released.rs.html index 69ea3d3d0463..a6669459cf08 100644 --- a/nightly/core/src/nautilus_model/events/order/released.rs.html +++ b/nightly/core/src/nautilus_model/events/order/released.rs.html @@ -1,4 +1,4 @@ -released.rs - source use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -197,7 +197,7 @@

    Files

    use crate::events::order::{released::OrderReleased, stubs::*}; #[rstest] fn test_order_released_display(order_released: OrderReleased) { - let display = format!("{}", order_released); + let display = format!("{order_released}"); assert_eq!( display, "OrderReleased(BTCUSDT.COINBASE, O-20200814-102234-001-001-1, 22000)" diff --git a/nightly/core/src/nautilus_model/events/order/stubs.rs.html b/nightly/core/src/nautilus_model/events/order/stubs.rs.html index b526a0165882..d1aee6228425 100644 --- a/nightly/core/src/nautilus_model/events/order/stubs.rs.html +++ b/nightly/core/src/nautilus_model/events/order/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source 429 430 431 +432 +433 +434 +435 +436 +437 +438 +439 +440
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -463,9 +472,18 @@ 

    Files

    triggered::OrderTriggered, updated::OrderUpdated, }, identifiers::{ - account_id::AccountId, client_order_id::ClientOrderId, instrument_id::InstrumentId, - order_list_id::OrderListId, strategy_id::StrategyId, stubs::*, trade_id::TradeId, - trader_id::TraderId, venue_order_id::VenueOrderId, + account_id::AccountId, + client_order_id::ClientOrderId, + instrument_id::InstrumentId, + order_list_id::OrderListId, + strategy_id::StrategyId, + stubs::{ + account_id, client_order_id, instrument_id_btc_usdt, strategy_id_ema_cross, trader_id, + uuid4, venue_order_id, + }, + trade_id::TradeId, + trader_id::TraderId, + venue_order_id::VenueOrderId, }, types::{currency::Currency, money::Money, price::Price, quantity::Quantity}, }; diff --git a/nightly/core/src/nautilus_model/events/order/submitted.rs.html b/nightly/core/src/nautilus_model/events/order/submitted.rs.html index df942c7e9a02..b430d0f7f2fc 100644 --- a/nightly/core/src/nautilus_model/events/order/submitted.rs.html +++ b/nightly/core/src/nautilus_model/events/order/submitted.rs.html @@ -1,4 +1,4 @@ -submitted.rs - source
    use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -160,8 +160,8 @@

    Files

    event_id: UUID4, ts_event: UnixNanos, ts_init: UnixNanos, - ) -> Result<OrderSubmitted> { - Ok(OrderSubmitted { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -197,7 +197,7 @@

    Files

    #[rstest] fn test_order_rejected_display(order_submitted: OrderSubmitted) { - let display = format!("{}", order_submitted); + let display = format!("{order_submitted}"); assert_eq!( display, "OrderSubmitted(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, account_id=SIM-001, ts_event=0)" diff --git a/nightly/core/src/nautilus_model/events/order/triggered.rs.html b/nightly/core/src/nautilus_model/events/order/triggered.rs.html index 604da4d2a15f..bac4bbcde752 100644 --- a/nightly/core/src/nautilus_model/events/order/triggered.rs.html +++ b/nightly/core/src/nautilus_model/events/order/triggered.rs.html @@ -1,4 +1,4 @@ -triggered.rs - source use std::fmt::Display; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -174,8 +174,8 @@

    Files

    reconciliation: bool, venue_order_id: Option<VenueOrderId>, account_id: Option<AccountId>, - ) -> Result<OrderTriggered> { - Ok(OrderTriggered { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -183,7 +183,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, }) @@ -198,12 +198,12 @@

    Files

    stringify!(OrderTriggered), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else( + || "None".to_string(), + |venue_order_id| format!("{venue_order_id}") + ), self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()) + .map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")) ) } } @@ -219,9 +219,9 @@

    Files

    #[rstest] fn test_order_triggered_display(order_triggered: OrderTriggered) { - let display = format!("{}", order_triggered); + let display = format!("{order_triggered}"); assert_eq!(display, "OrderTriggered(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, \ - venue_order_id=001, account_id=SIM-001)") + venue_order_id=001, account_id=SIM-001)"); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/events/order/updated.rs.html b/nightly/core/src/nautilus_model/events/order/updated.rs.html index a72ef972a964..337b74e7289a 100644 --- a/nightly/core/src/nautilus_model/events/order/updated.rs.html +++ b/nightly/core/src/nautilus_model/events/order/updated.rs.html @@ -1,4 +1,4 @@ -updated.rs - source 123 124 125 -126 -127 -128 -129 -130 -131 -132 -133
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -151,7 +143,7 @@ 

    Files

    use std::fmt::{Display, Formatter}; use anyhow::Result; -use derive_builder::{self, Builder}; +use derive_builder::Builder; use nautilus_core::{time::UnixNanos, uuid::UUID4}; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; @@ -204,8 +196,8 @@

    Files

    account_id: Option<AccountId>, price: Option<Price>, trigger_price: Option<Price>, - ) -> Result<OrderUpdated> { - Ok(OrderUpdated { + ) -> Result<Self> { + Ok(Self { trader_id, strategy_id, instrument_id, @@ -214,7 +206,7 @@

    Files

    event_id, ts_event, ts_init, - reconciliation: reconciliation as u8, + reconciliation: u8::from(reconciliation), venue_order_id, account_id, price, @@ -230,19 +222,11 @@

    Files

    "OrderUpdated(instrument_id={}, client_order_id={}, venue_order_id={}, account_id={},quantity={}, price={}, trigger_price={}, ts_event={})", self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.quantity, - self.price - .map(|price| format!("{}", price)) - .unwrap_or_else(|| "None".to_string()), - self.trigger_price - .map(|trigger_price| format!("{}", trigger_price)) - .unwrap_or_else(|| "None".to_string()), + self.price.map_or_else(|| "None".to_string(), |price| format!("{price}")), + self.trigger_price.map_or_else(|| "None".to_string(), |trigger_price| format!("{trigger_price}")), self.ts_event ) } @@ -259,11 +243,11 @@

    Files

    #[rstest] fn test_order_updated_display(order_updated: OrderUpdated) { - let display = format!("{}", order_updated); + let display = format!("{order_updated}"); assert_eq!( display, "OrderUpdated(instrument_id=BTCUSDT.COINBASE, client_order_id=O-20200814-102234-001-001-1, venue_order_id=001, account_id=SIM-001,quantity=100, price=22000, trigger_price=None, ts_event=0)" - ) + ); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/events/position/changed.rs.html b/nightly/core/src/nautilus_model/events/position/changed.rs.html index 4c0cf470195b..078f57a8a6e9 100644 --- a/nightly/core/src/nautilus_model/events/position/changed.rs.html +++ b/nightly/core/src/nautilus_model/events/position/changed.rs.html @@ -1,4 +1,4 @@ -changed.rs - source
    } } - pub fn pprint(&self, num_levels: usize) -> String { + #[must_use] + pub fn pprint(&self, num_levels: usize) -> String { match self.book_type { BookType::L3_MBO => self.get_mbo().pprint(num_levels), BookType::L2_MBP => self.get_mbp().pprint(num_levels), diff --git a/nightly/core/src/nautilus_model/ffi/orderbook/level.rs.html b/nightly/core/src/nautilus_model/ffi/orderbook/level.rs.html index a4f37fe1e676..2e112ef7c44f 100644 --- a/nightly/core/src/nautilus_model/ffi/orderbook/level.rs.html +++ b/nightly/core/src/nautilus_model/ffi/orderbook/level.rs.html @@ -1,4 +1,4 @@ -level.rs - source 116 117 118 +119
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -158,7 +159,8 @@ 

    Files

    pub struct Level_API(Box<Level>); impl Level_API { - pub fn new(level: Level) -> Self { + #[must_use] + pub fn new(level: Level) -> Self { Self(Box::new(level)) } } @@ -180,7 +182,7 @@

    Files

    #[no_mangle] pub extern "C" fn level_new(order_side: OrderSide, price: Price, orders: CVec) -> Level_API { let CVec { ptr, len, cap } = orders; - let orders: Vec<BookOrder> = unsafe { Vec::from_raw_parts(ptr as *mut BookOrder, len, cap) }; + let orders: Vec<BookOrder> = unsafe { Vec::from_raw_parts(ptr.cast::<BookOrder>(), len, cap) }; let price = BookPrice { value: price, side: order_side, @@ -207,7 +209,7 @@

    Files

    #[no_mangle] pub extern "C" fn level_orders(level: &Level_API) -> CVec { - let orders_vec: Vec<BookOrder> = level.orders.values().cloned().collect(); + let orders_vec: Vec<BookOrder> = level.orders.values().copied().collect(); orders_vec.into() } @@ -225,7 +227,7 @@

    Files

    #[no_mangle] pub extern "C" fn vec_levels_drop(v: CVec) { let CVec { ptr, len, cap } = v; - let data: Vec<Level_API> = unsafe { Vec::from_raw_parts(ptr as *mut Level_API, len, cap) }; + let data: Vec<Level_API> = unsafe { Vec::from_raw_parts(ptr.cast::<Level_API>(), len, cap) }; drop(data); // Memory freed here } @@ -233,7 +235,7 @@

    Files

    #[no_mangle] pub extern "C" fn vec_orders_drop(v: CVec) { let CVec { ptr, len, cap } = v; - let orders: Vec<BookOrder> = unsafe { Vec::from_raw_parts(ptr as *mut BookOrder, len, cap) }; + let orders: Vec<BookOrder> = unsafe { Vec::from_raw_parts(ptr.cast::<BookOrder>(), len, cap) }; drop(orders); // Memory freed here }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/ffi/orderbook/mod.rs.html b/nightly/core/src/nautilus_model/ffi/orderbook/mod.rs.html index 4c14f7ef0cfa..8005f1937c57 100644 --- a/nightly/core/src/nautilus_model/ffi/orderbook/mod.rs.html +++ b/nightly/core/src/nautilus_model/ffi/orderbook/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source }) } - pub fn get_tag(&self) -> &str { + #[must_use] + pub fn get_tag(&self) -> &str { // SAFETY: Unwrap safe as value previously validated self.value.split('-').last().unwrap() } diff --git a/nightly/core/src/nautilus_model/identifiers/venue.rs.html b/nightly/core/src/nautilus_model/identifiers/venue.rs.html index 7b42441f64af..d964ecb85dfc 100644 --- a/nightly/core/src/nautilus_model/identifiers/venue.rs.html +++ b/nightly/core/src/nautilus_model/identifiers/venue.rs.html @@ -1,4 +1,4 @@ -venue.rs - source 103 104 105 +106 +107
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -152,7 +154,8 @@ 

    Files

    }) } - pub fn from_str_unchecked(s: &str) -> Self { + #[must_use] + pub fn from_str_unchecked(s: &str) -> Self { Self { value: Ustr::from(s), } @@ -164,7 +167,8 @@

    Files

    Self::new(SYNTHETIC_VENUE).unwrap() } - pub fn is_synthetic(&self) -> bool { + #[must_use] + pub fn is_synthetic(&self) -> bool { self.value.as_str() == SYNTHETIC_VENUE } } diff --git a/nightly/core/src/nautilus_model/identifiers/venue_order_id.rs.html b/nightly/core/src/nautilus_model/identifiers/venue_order_id.rs.html index 5194ffd5f7ff..4a374ecf0456 100644 --- a/nightly/core/src/nautilus_model/identifiers/venue_order_id.rs.html +++ b/nightly/core/src/nautilus_model/identifiers/venue_order_id.rs.html @@ -1,4 +1,4 @@ -venue_order_id.rs - source
    #[rstest] fn test_equality(currency_pair_btcusdt: CurrencyPair) { - let cloned = currency_pair_btcusdt.clone(); - assert_eq!(currency_pair_btcusdt, cloned) + let cloned = currency_pair_btcusdt; + assert_eq!(currency_pair_btcusdt, cloned); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/instruments/equity.rs.html b/nightly/core/src/nautilus_model/instruments/equity.rs.html index 4f54049a391a..92d2d364f6bc 100644 --- a/nightly/core/src/nautilus_model/instruments/equity.rs.html +++ b/nightly/core/src/nautilus_model/instruments/equity.rs.html @@ -1,4 +1,4 @@ -equity.rs - source #[rstest] fn test_equality(equity_aapl: Equity) { - let cloned = equity_aapl.clone(); - assert_eq!(equity_aapl, cloned) + let cloned = equity_aapl; + assert_eq!(equity_aapl, cloned); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/instruments/futures_contract.rs.html b/nightly/core/src/nautilus_model/instruments/futures_contract.rs.html index 7575d882cacf..57be555cc10a 100644 --- a/nightly/core/src/nautilus_model/instruments/futures_contract.rs.html +++ b/nightly/core/src/nautilus_model/instruments/futures_contract.rs.html @@ -1,4 +1,4 @@ -futures_contract.rs - source #[rstest] fn test_equality(futures_contract_es: FuturesContract) { - let cloned = futures_contract_es.clone(); + let cloned = futures_contract_es; assert_eq!(futures_contract_es, cloned); } } diff --git a/nightly/core/src/nautilus_model/instruments/mod.rs.html b/nightly/core/src/nautilus_model/instruments/mod.rs.html index 1197b5abd365..1afd7ad717d8 100644 --- a/nightly/core/src/nautilus_model/instruments/mod.rs.html +++ b/nightly/core/src/nautilus_model/instruments/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 130 131 132 -133
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -239,19 +238,18 @@ 

    Files

    let use_quote_for_inverse = use_quote_for_inverse.unwrap_or(false); let (amount, currency) = if self.is_inverse() { if use_quote_for_inverse { - (quantity.as_f64(), self.quote_currency().to_owned()) + (quantity.as_f64(), self.quote_currency()) } else { let amount = quantity.as_f64() * self.multiplier().as_f64() * (1.0 / price.as_f64()); let currency = self .base_currency() - .expect("Error: no base currency for notional calculation") - .to_owned(); + .expect("Error: no base currency for notional calculation"); (amount, currency) } } else { let amount = quantity.as_f64() * self.multiplier().as_f64() * price.as_f64(); - let currency = self.quote_currency().to_owned(); + let currency = self.quote_currency(); (amount, currency) }; diff --git a/nightly/core/src/nautilus_model/instruments/options_contract.rs.html b/nightly/core/src/nautilus_model/instruments/options_contract.rs.html index 3d0a6d21f809..26668d985c1e 100644 --- a/nightly/core/src/nautilus_model/instruments/options_contract.rs.html +++ b/nightly/core/src/nautilus_model/instruments/options_contract.rs.html @@ -1,4 +1,4 @@ -options_contract.rs - source #[rstest] fn test_equality(options_contract_appl: OptionsContract) { - let options_contract_appl2 = options_contract_appl.clone(); + let options_contract_appl2 = options_contract_appl; assert_eq!(options_contract_appl, options_contract_appl2); } } diff --git a/nightly/core/src/nautilus_model/instruments/stubs.rs.html b/nightly/core/src/nautilus_model/instruments/stubs.rs.html index 38c38de8e6c0..3f41076748aa 100644 --- a/nightly/core/src/nautilus_model/instruments/stubs.rs.html +++ b/nightly/core/src/nautilus_model/instruments/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source 344 345 346 +347
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -565,7 +566,8 @@ 

    Files

    .unwrap() } -pub fn default_fx_ccy(symbol: Symbol, venue: Option<Venue>) -> CurrencyPair { +#[must_use] +pub fn default_fx_ccy(symbol: Symbol, venue: Option<Venue>) -> CurrencyPair { let target_venue = venue.unwrap_or(Venue::from("SIM")); let instrument_id = InstrumentId::new(symbol, target_venue); let base_currency = symbol.value.split('/').next().unwrap(); diff --git a/nightly/core/src/nautilus_model/instruments/synthetic.rs.html b/nightly/core/src/nautilus_model/instruments/synthetic.rs.html index 3c1e0d434318..5f096c1cddf9 100644 --- a/nightly/core/src/nautilus_model/instruments/synthetic.rs.html +++ b/nightly/core/src/nautilus_model/instruments/synthetic.rs.html @@ -1,4 +1,4 @@ -synthetic.rs - source 237 238 239 +240
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -310,12 +311,12 @@ 

    Files

    // Extract variables from the component instruments let variables: Vec<String> = components .iter() - .map(|component| component.to_string()) + .map(std::string::ToString::to_string) .collect(); let operator_tree = evalexpr::build_operator_tree(&formula)?; - Ok(SyntheticInstrument { + Ok(Self { id: InstrumentId::new(symbol, Venue::synthetic()), price_precision, price_increment, @@ -329,7 +330,8 @@

    Files

    }) } - pub fn is_valid_formula(&self, formula: &str) -> bool { + #[must_use] + pub fn is_valid_formula(&self, formula: &str) -> bool { evalexpr::build_operator_tree(formula).is_ok() } @@ -352,7 +354,7 @@

    Files

    self.context .set_value(variable.clone(), Value::from(value))?; } else { - panic!("Missing price for component: {}", variable); + panic!("Missing price for component: {variable}"); } } @@ -459,7 +461,7 @@

    Files

    Symbol::new("BTC-LTC").unwrap(), 2, vec![btc_binance, ltc_binance], - formula.clone(), + formula, 0, 0, ) diff --git a/nightly/core/src/nautilus_model/lib.rs.html b/nightly/core/src/nautilus_model/lib.rs.html index 7b7211b3b834..eeb9f68b0940 100644 --- a/nightly/core/src/nautilus_model/lib.rs.html +++ b/nightly/core/src/nautilus_model/lib.rs.html @@ -1,4 +1,4 @@ -lib.rs - source } } -pub fn get_quantity_for_price( +/// Calculates the estimated fill quantity for a specified price from a set of +/// order book levels and order side. +#[must_use] +pub fn get_quantity_for_price( price: Price, order_side: OrderSide, levels: &BTreeMap<BookPrice, Level>, @@ -587,7 +524,7 @@

    Files

    break; } } - _ => panic!("Invalid `OrderSide` {}", order_side), + _ => panic!("Invalid `OrderSide` {order_side}"), } matched_size += level.size(); } @@ -606,41 +543,13 @@

    Files

    data::{ depth::{stubs::stub_depth10, OrderBookDepth10}, order::BookOrder, - quote::QuoteTick, - trade::TradeTick, }, - enums::{AggressorSide, OrderSide}, - identifiers::{instrument_id::InstrumentId, trade_id::TradeId}, + enums::OrderSide, + identifiers::instrument_id::InstrumentId, orderbook::{book_mbo::OrderBookMbo, book_mbp::OrderBookMbp}, types::{price::Price, quantity::Quantity}, }; - #[rstest] - fn test_orderbook_creation() { - let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); - let book = OrderBookMbp::new(instrument_id, false); - - assert_eq!(book.instrument_id, instrument_id); - assert_eq!(book.sequence, 0); - assert_eq!(book.ts_last, 0); - assert_eq!(book.count, 0); - } - - #[rstest] - fn test_orderbook_reset() { - let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); - let mut book = OrderBookMbp::new(instrument_id, false); - book.sequence = 10; - book.ts_last = 100; - book.count = 3; - - book.reset(); - - assert_eq!(book.sequence, 0); - assert_eq!(book.ts_last, 0); - assert_eq!(book.count, 0); - } - #[rstest] fn test_best_bid_and_ask_when_nothing_in_book() { let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); @@ -687,6 +596,7 @@

    Files

    assert_eq!(book.best_ask_size(), Some(Quantity::from("2.0"))); assert!(book.has_ask()); } + #[rstest] fn test_spread_with_no_bids_or_asks() { let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); @@ -806,11 +716,11 @@

    Files

    assert_eq!( book.get_avg_px_for_quantity(qty, OrderSide::Buy), - 2.0033333333333334 + 2.003_333_333_333_333_4 ); assert_eq!( book.get_avg_px_for_quantity(qty, OrderSide::Sell), - 0.9966666666666667 + 0.996_666_666_666_666_7 ); } @@ -886,54 +796,6 @@

    Files

    assert_eq!(book.best_ask_size().unwrap().as_f64(), 100.0); } - #[rstest] - fn test_update_quote_tick_l1() { - let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); - let mut book = OrderBookMbp::new(instrument_id, true); - let quote = QuoteTick::new( - InstrumentId::from("ETHUSDT-PERP.BINANCE"), - Price::from("5000.000"), - Price::from("5100.000"), - Quantity::from("100.00000000"), - Quantity::from("99.00000000"), - 0, - 0, - ) - .unwrap(); - - book.update_quote_tick(&quote); - - assert_eq!(book.best_bid_price().unwrap(), quote.bid_price); - assert_eq!(book.best_ask_price().unwrap(), quote.ask_price); - assert_eq!(book.best_bid_size().unwrap(), quote.bid_size); - assert_eq!(book.best_ask_size().unwrap(), quote.ask_size); - } - - #[rstest] - fn test_update_trade_tick_l1() { - let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); - let mut book = OrderBookMbp::new(instrument_id, true); - - let price = Price::from("15000.000"); - let size = Quantity::from("10.00000000"); - let trade = TradeTick::new( - instrument_id, - price, - size, - AggressorSide::Buyer, - TradeId::new("123456789").unwrap(), - 0, - 0, - ); - - book.update_trade_tick(&trade); - - assert_eq!(book.best_bid_price().unwrap(), price); - assert_eq!(book.best_ask_price().unwrap(), price); - assert_eq!(book.best_bid_size().unwrap(), size); - assert_eq!(book.best_ask_size().unwrap(), size); - } - #[rstest] fn test_pprint() { let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); @@ -996,7 +858,7 @@

    Files

    │ [1.0] │ 1.000 │ │\n\ ╰───────┴───────┴───────╯"
    ; - println!("{}", pprint_output); + println!("{pprint_output}"); assert_eq!(pprint_output, expected_output); } } diff --git a/nightly/core/src/nautilus_model/orderbook/book_mbo.rs.html b/nightly/core/src/nautilus_model/orderbook/book_mbo.rs.html index e7a44b289e02..adb25236eab5 100644 --- a/nightly/core/src/nautilus_model/orderbook/book_mbo.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/book_mbo.rs.html @@ -1,4 +1,4 @@ -book_mbo.rs - source 257 258 259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -275,7 +328,6 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    use nautilus_core::time::UnixNanos; -use pyo3; use super::{ book::{get_avg_px_for_quantity, get_quantity_for_price}, @@ -292,17 +344,22 @@

    Files

    types::{price::Price, quantity::Quantity}, }; -/// Provides an order book which can handle MBO/L3 granularity data. +/// Provides an order book which can handle MBO (market by order, a.k.a L3) +/// granularity data. #[derive(Clone, Debug)] #[cfg_attr( feature = "python", pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") )] pub struct OrderBookMbo { - pub instrument_id: InstrumentId, - pub sequence: u64, - pub ts_last: UnixNanos, - pub count: u64, + /// The instrument ID for the order book. + pub instrument_id: InstrumentId, + /// The last event sequence number for the order book. + pub sequence: u64, + /// The timestamp of the last event applied to the order book. + pub ts_last: UnixNanos, + /// The current count of events applied to the order book. + pub count: u64, bids: Ladder, asks: Ladder, } @@ -385,7 +442,7 @@

    Files

    pub fn apply_deltas(&mut self, deltas: OrderBookDeltas) { for delta in deltas.deltas { - self.apply_delta(delta) + self.apply_delta(delta); } } @@ -402,85 +459,96 @@

    Files

    } } - pub fn bids(&self) -> Vec<&Level> { - self.bids.levels.values().collect() + pub fn bids(&self) -> impl Iterator<Item = &Level> { + self.bids.levels.values() } - pub fn asks(&self) -> Vec<&Level> { - self.asks.levels.values().collect() + pub fn asks(&self) -> impl Iterator<Item = &Level> { + self.asks.levels.values() } - pub fn has_bid(&self) -> bool { + #[must_use] + pub fn has_bid(&self) -> bool { match self.bids.top() { Some(top) => !top.orders.is_empty(), None => false, } } - pub fn has_ask(&self) -> bool { + #[must_use] + pub fn has_ask(&self) -> bool { match self.asks.top() { Some(top) => !top.orders.is_empty(), None => false, } } - pub fn best_bid_price(&self) -> Option<Price> { + #[must_use] + pub fn best_bid_price(&self) -> Option<Price> { self.bids.top().map(|top| top.price.value) } - pub fn best_ask_price(&self) -> Option<Price> { + #[must_use] + pub fn best_ask_price(&self) -> Option<Price> { self.asks.top().map(|top| top.price.value) } - pub fn best_bid_size(&self) -> Option<Quantity> { + #[must_use] + pub fn best_bid_size(&self) -> Option<Quantity> { match self.bids.top() { Some(top) => top.first().map(|order| order.size), None => None, } } - pub fn best_ask_size(&self) -> Option<Quantity> { + #[must_use] + pub fn best_ask_size(&self) -> Option<Quantity> { match self.asks.top() { Some(top) => top.first().map(|order| order.size), None => None, } } - pub fn spread(&self) -> Option<f64> { + #[must_use] + pub fn spread(&self) -> Option<f64> { match (self.best_ask_price(), self.best_bid_price()) { (Some(ask), Some(bid)) => Some(ask.as_f64() - bid.as_f64()), _ => None, } } - pub fn midpoint(&self) -> Option<f64> { + #[must_use] + pub fn midpoint(&self) -> Option<f64> { match (self.best_ask_price(), self.best_bid_price()) { (Some(ask), Some(bid)) => Some((ask.as_f64() + bid.as_f64()) / 2.0), _ => None, } } - pub fn get_avg_px_for_quantity(&self, qty: Quantity, order_side: OrderSide) -> f64 { + #[must_use] + pub fn get_avg_px_for_quantity(&self, qty: Quantity, order_side: OrderSide) -> f64 { let levels = match order_side { OrderSide::Buy => &self.asks.levels, OrderSide::Sell => &self.bids.levels, - _ => panic!("Invalid `OrderSide` {}", order_side), + _ => panic!("Invalid `OrderSide` {order_side}"), }; get_avg_px_for_quantity(qty, levels) } - pub fn get_quantity_for_price(&self, price: Price, order_side: OrderSide) -> f64 { + #[must_use] + pub fn get_quantity_for_price(&self, price: Price, order_side: OrderSide) -> f64 { let levels = match order_side { OrderSide::Buy => &self.asks.levels, OrderSide::Sell => &self.bids.levels, - _ => panic!("Invalid `OrderSide` {}", order_side), + _ => panic!("Invalid `OrderSide` {order_side}"), }; get_quantity_for_price(price, order_side, levels) } - pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { + #[must_use] + pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { match order.side { OrderSide::Buy => self.asks.simulate_fills(order), OrderSide::Sell => self.bids.simulate_fills(order), @@ -489,6 +557,7 @@

    Files

    } /// Return a [`String`] representation of the order book in a human-readable table format. + #[must_use] pub fn pprint(&self, num_levels: usize) -> String { pprint_book(&self.bids, &self.asks, num_levels) } @@ -518,4 +587,41 @@

    Files

    self.count += 1; } } + +//////////////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////////////// +#[cfg(test)] +mod tests { + use rstest::rstest; + + use super::*; + use crate::identifiers::instrument_id::InstrumentId; + + #[rstest] + fn test_orderbook_creation() { + let instrument_id = InstrumentId::from("AAPL.XNAS"); + let book = OrderBookMbo::new(instrument_id); + + assert_eq!(book.instrument_id, instrument_id); + assert_eq!(book.sequence, 0); + assert_eq!(book.ts_last, 0); + assert_eq!(book.count, 0); + } + + #[rstest] + fn test_orderbook_reset() { + let instrument_id = InstrumentId::from("AAPL.XNAS"); + let mut book = OrderBookMbo::new(instrument_id); + book.sequence = 10; + book.ts_last = 100; + book.count = 3; + + book.reset(); + + assert_eq!(book.sequence, 0); + assert_eq!(book.ts_last, 0); + assert_eq!(book.count, 0); + } +}
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/orderbook/book_mbp.rs.html b/nightly/core/src/nautilus_model/orderbook/book_mbp.rs.html index 8035b43bdc4e..ab6088a017d9 100644 --- a/nightly/core/src/nautilus_model/orderbook/book_mbp.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/book_mbp.rs.html @@ -1,4 +1,4 @@ -book_mbp.rs - source 386 387 388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -421,18 +530,25 @@ 

    Files

    types::{price::Price, quantity::Quantity}, }; -/// Provides an order book which can handle MBP/L2 or L1 (top only) granularity data. +/// Provides an order book which can handle MBP (market by price, a.k.a. L2) +/// granularity data. The book can also be specified as being 'top only', meaning +/// it will only maintain the state of the top most level of the bid and ask side. #[derive(Clone, Debug)] #[cfg_attr( feature = "python", pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") )] pub struct OrderBookMbp { - pub instrument_id: InstrumentId, - pub top_only: bool, - pub sequence: u64, - pub ts_last: UnixNanos, - pub count: u64, + /// The instrument ID for the order book. + pub instrument_id: InstrumentId, + /// If the order book will only maintain state for the top bid and ask levels. + pub top_only: bool, + /// The last event sequence number for the order book. + pub sequence: u64, + /// The timestamp of the last event applied to the order book. + pub ts_last: UnixNanos, + /// The current count of events applied to the order book. + pub count: u64, bids: Ladder, asks: Ladder, } @@ -551,7 +667,7 @@

    Files

    pub fn apply_deltas(&mut self, deltas: OrderBookDeltas) { for delta in deltas.deltas { - self.apply_delta(delta) + self.apply_delta(delta); } } @@ -568,85 +684,96 @@

    Files

    } } - pub fn bids(&self) -> Vec<&Level> { - self.bids.levels.values().collect() + pub fn bids(&self) -> impl Iterator<Item = &Level> { + self.bids.levels.values() } - pub fn asks(&self) -> Vec<&Level> { - self.asks.levels.values().collect() + pub fn asks(&self) -> impl Iterator<Item = &Level> { + self.asks.levels.values() } - pub fn has_bid(&self) -> bool { + #[must_use] + pub fn has_bid(&self) -> bool { match self.bids.top() { Some(top) => !top.orders.is_empty(), None => false, } } - pub fn has_ask(&self) -> bool { + #[must_use] + pub fn has_ask(&self) -> bool { match self.asks.top() { Some(top) => !top.orders.is_empty(), None => false, } } - pub fn best_bid_price(&self) -> Option<Price> { + #[must_use] + pub fn best_bid_price(&self) -> Option<Price> { self.bids.top().map(|top| top.price.value) } - pub fn best_ask_price(&self) -> Option<Price> { + #[must_use] + pub fn best_ask_price(&self) -> Option<Price> { self.asks.top().map(|top| top.price.value) } - pub fn best_bid_size(&self) -> Option<Quantity> { + #[must_use] + pub fn best_bid_size(&self) -> Option<Quantity> { match self.bids.top() { Some(top) => top.first().map(|order| order.size), None => None, } } - pub fn best_ask_size(&self) -> Option<Quantity> { + #[must_use] + pub fn best_ask_size(&self) -> Option<Quantity> { match self.asks.top() { Some(top) => top.first().map(|order| order.size), None => None, } } - pub fn spread(&self) -> Option<f64> { + #[must_use] + pub fn spread(&self) -> Option<f64> { match (self.best_ask_price(), self.best_bid_price()) { (Some(ask), Some(bid)) => Some(ask.as_f64() - bid.as_f64()), _ => None, } } - pub fn midpoint(&self) -> Option<f64> { + #[must_use] + pub fn midpoint(&self) -> Option<f64> { match (self.best_ask_price(), self.best_bid_price()) { (Some(ask), Some(bid)) => Some((ask.as_f64() + bid.as_f64()) / 2.0), _ => None, } } - pub fn get_avg_px_for_quantity(&self, qty: Quantity, order_side: OrderSide) -> f64 { + #[must_use] + pub fn get_avg_px_for_quantity(&self, qty: Quantity, order_side: OrderSide) -> f64 { let levels = match order_side { OrderSide::Buy => &self.asks.levels, OrderSide::Sell => &self.bids.levels, - _ => panic!("Invalid `OrderSide` {}", order_side), + _ => panic!("Invalid `OrderSide` {order_side}"), }; get_avg_px_for_quantity(qty, levels) } - pub fn get_quantity_for_price(&self, price: Price, order_side: OrderSide) -> f64 { + #[must_use] + pub fn get_quantity_for_price(&self, price: Price, order_side: OrderSide) -> f64 { let levels = match order_side { OrderSide::Buy => &self.asks.levels, OrderSide::Sell => &self.bids.levels, - _ => panic!("Invalid `OrderSide` {}", order_side), + _ => panic!("Invalid `OrderSide` {order_side}"), }; get_quantity_for_price(price, order_side, levels) } - pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { + #[must_use] + pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { match order.side { OrderSide::Buy => self.asks.simulate_fills(order), OrderSide::Sell => self.bids.simulate_fills(order), @@ -655,6 +782,7 @@

    Files

    } /// Return a [`String`] representation of the order book in a human-readable table format. + #[must_use] pub fn pprint(&self, num_levels: usize) -> String { pprint_book(&self.bids, &self.asks, num_levels) } @@ -676,7 +804,7 @@

    Files

    } } false => { - for (_, bid_level) in self.bids.levels.iter() { + for bid_level in self.bids.levels.values() { let num_orders = bid_level.orders.len(); if num_orders > 1 { return Err(BookIntegrityError::TooManyOrders( @@ -686,7 +814,7 @@

    Files

    } } - for (_, ask_level) in self.asks.levels.iter() { + for ask_level in self.asks.levels.values() { let num_orders = ask_level.orders.len(); if num_orders > 1 { return Err(BookIntegrityError::TooManyOrders( @@ -776,4 +904,94 @@

    Files

    order } } + +//////////////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////////////// +#[cfg(test)] +mod tests { + use rstest::rstest; + + use super::*; + use crate::{ + enums::AggressorSide, + identifiers::{instrument_id::InstrumentId, trade_id::TradeId}, + }; + + #[rstest] + fn test_orderbook_creation() { + let instrument_id = InstrumentId::from("AAPL.XNAS"); + let book = OrderBookMbp::new(instrument_id, false); + + assert_eq!(book.instrument_id, instrument_id); + assert!(!book.top_only); + assert_eq!(book.sequence, 0); + assert_eq!(book.ts_last, 0); + assert_eq!(book.count, 0); + } + + #[rstest] + fn test_orderbook_reset() { + let instrument_id = InstrumentId::from("AAPL.XNAS"); + let mut book = OrderBookMbp::new(instrument_id, true); + book.sequence = 10; + book.ts_last = 100; + book.count = 3; + + book.reset(); + + assert!(book.top_only); + assert_eq!(book.sequence, 0); + assert_eq!(book.ts_last, 0); + assert_eq!(book.count, 0); + } + + #[rstest] + fn test_update_quote_tick_l1() { + let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); + let mut book = OrderBookMbp::new(instrument_id, true); + let quote = QuoteTick::new( + InstrumentId::from("ETHUSDT-PERP.BINANCE"), + Price::from("5000.000"), + Price::from("5100.000"), + Quantity::from("100.00000000"), + Quantity::from("99.00000000"), + 0, + 0, + ) + .unwrap(); + + book.update_quote_tick(&quote); + + assert_eq!(book.best_bid_price().unwrap(), quote.bid_price); + assert_eq!(book.best_ask_price().unwrap(), quote.ask_price); + assert_eq!(book.best_bid_size().unwrap(), quote.bid_size); + assert_eq!(book.best_ask_size().unwrap(), quote.ask_size); + } + + #[rstest] + fn test_update_trade_tick_l1() { + let instrument_id = InstrumentId::from("ETHUSDT-PERP.BINANCE"); + let mut book = OrderBookMbp::new(instrument_id, true); + + let price = Price::from("15000.000"); + let size = Quantity::from("10.00000000"); + let trade = TradeTick::new( + instrument_id, + price, + size, + AggressorSide::Buyer, + TradeId::new("123456789").unwrap(), + 0, + 0, + ); + + book.update_trade_tick(&trade); + + assert_eq!(book.best_bid_price().unwrap(), price); + assert_eq!(book.best_ask_price().unwrap(), price); + assert_eq!(book.best_bid_size().unwrap(), size); + assert_eq!(book.best_ask_size().unwrap(), size); + } +}
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/orderbook/display.rs.html b/nightly/core/src/nautilus_model/orderbook/display.rs.html index 37c5130f9dba..fee527c948aa 100644 --- a/nightly/core/src/nautilus_model/orderbook/display.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/display.rs.html @@ -1,4 +1,4 @@ -display.rs - source 69 70 71 +72
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -99,6 +100,7 @@ 

    Files

    } /// Return a [`String`] representation of the order book in a human-readable table format. +#[must_use] pub fn pprint_book(bids: &Ladder, asks: &Ladder, num_levels: usize) -> String { let ask_levels: Vec<(&BookPrice, &Level)> = asks.levels.iter().take(num_levels).rev().collect(); let bid_levels: Vec<(&BookPrice, &Level)> = bids.levels.iter().take(num_levels).collect(); @@ -126,13 +128,13 @@

    Files

    OrderLevelDisplay { bids: if bid_sizes.is_empty() { - String::from("") + String::new() } else { format!("[{}]", bid_sizes.join(", ")) }, price: format!("{}", level.price), asks: if ask_sizes.is_empty() { - String::from("") + String::new() } else { format!("[{}]", ask_sizes.join(", ")) }, diff --git a/nightly/core/src/nautilus_model/orderbook/ladder.rs.html b/nightly/core/src/nautilus_model/orderbook/ladder.rs.html index 60340cc1c24b..4bd28afc9da6 100644 --- a/nightly/core/src/nautilus_model/orderbook/ladder.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/ladder.rs.html @@ -1,4 +1,4 @@ -ladder.rs - source 697 698 699 +700 +701 +702 +703
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -804,7 +808,7 @@ 

    Files

    pub fn add_bulk(&mut self, orders: Vec<BookOrder>) { for order in orders { - self.add(order) + self.add(order); } } @@ -870,12 +874,15 @@

    Files

    #[must_use] pub fn sizes(&self) -> f64 { - self.levels.values().map(|l| l.size()).sum() + self.levels.values().map(super::level::Level::size).sum() } #[must_use] pub fn exposures(&self) -> f64 { - self.levels.values().map(|l| l.exposure()).sum() + self.levels + .values() + .map(super::level::Level::exposure) + .sum() } #[must_use] @@ -886,7 +893,8 @@

    Files

    } } - pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { + #[must_use] + pub fn simulate_fills(&self, order: &BookOrder) -> Vec<(Price, Quantity)> { let is_reversed = self.side == OrderSide::Buy; let mut fills = Vec::new(); @@ -969,7 +977,7 @@

    Files

    assert_eq!(ladder.len(), 1); assert_eq!(ladder.sizes(), 20.0); assert_eq!(ladder.exposures(), 200.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 10.0) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 10.0); } #[rstest] @@ -984,7 +992,7 @@

    Files

    assert_eq!(ladder.len(), 3); assert_eq!(ladder.sizes(), 300.0); assert_eq!(ladder.exposures(), 2520.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 10.0) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 10.0); } #[rstest] @@ -1004,7 +1012,7 @@

    Files

    assert_eq!(ladder.len(), 3); assert_eq!(ladder.sizes(), 300.0); assert_eq!(ladder.exposures(), 3780.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0); } #[rstest] @@ -1057,7 +1065,7 @@

    Files

    assert_eq!(ladder.len(), 1); assert_eq!(ladder.sizes(), 20.0); assert_eq!(ladder.exposures(), 222.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.1) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.1); } #[rstest] @@ -1073,7 +1081,7 @@

    Files

    assert_eq!(ladder.len(), 1); assert_eq!(ladder.sizes(), 20.0); assert_eq!(ladder.exposures(), 222.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.1) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.1); } #[rstest] @@ -1089,7 +1097,7 @@

    Files

    assert_eq!(ladder.len(), 1); assert_eq!(ladder.sizes(), 10.0); assert_eq!(ladder.exposures(), 110.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0); } #[rstest] @@ -1105,7 +1113,7 @@

    Files

    assert_eq!(ladder.len(), 1); assert_eq!(ladder.sizes(), 10.0); assert_eq!(ladder.exposures(), 110.0); - assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0) + assert_eq!(ladder.top().unwrap().price.value.as_f64(), 11.0); } #[rstest] @@ -1131,7 +1139,7 @@

    Files

    assert_eq!(ladder.len(), 0); assert_eq!(ladder.sizes(), 0.0); assert_eq!(ladder.exposures(), 0.0); - assert_eq!(ladder.top(), None) + assert_eq!(ladder.top(), None); } #[rstest] @@ -1147,7 +1155,7 @@

    Files

    assert_eq!(ladder.len(), 0); assert_eq!(ladder.sizes(), 0.0); assert_eq!(ladder.exposures(), 0.0); - assert_eq!(ladder.top(), None) + assert_eq!(ladder.top(), None); } #[rstest] diff --git a/nightly/core/src/nautilus_model/orderbook/level.rs.html b/nightly/core/src/nautilus_model/orderbook/level.rs.html index d0ecf8bb5d7e..d3d19cf16287 100644 --- a/nightly/core/src/nautilus_model/orderbook/level.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/level.rs.html @@ -1,4 +1,4 @@ -level.rs - source 403 404 405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -428,7 +441,11 @@ 

    Files

    types::fixed::FIXED_SCALAR, }; -#[derive(Clone, Debug, Eq)] +/// Represents a discrete price level in an order book. +/// +/// The level maintains a collection of orders as well as tracking insertion order +/// to preserve FIFO queue dynamics. +#[derive(Clone, Debug, Eq)] #[cfg_attr( feature = "python", pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") @@ -477,6 +494,42 @@

    Files

    .and_then(|&id| self.orders.get(&id)) } + /// Returns the orders in the insertion order. + #[must_use] + pub fn get_orders(&self) -> Vec<BookOrder> { + self.insertion_order + .iter() + .filter_map(|id| self.orders.get(id)) + .copied() + .collect() + } + + #[must_use] + pub fn size(&self) -> f64 { + self.orders.values().map(|o| o.size.as_f64()).sum() + } + + #[must_use] + pub fn size_raw(&self) -> u64 { + self.orders.values().map(|o| o.size.raw).sum() + } + + #[must_use] + pub fn exposure(&self) -> f64 { + self.orders + .values() + .map(|o| o.price.as_f64() * o.size.as_f64()) + .sum() + } + + #[must_use] + pub fn exposure_raw(&self) -> u64 { + self.orders + .values() + .map(|o| ((o.price.as_f64() * o.size.as_f64()) * FIXED_SCALAR) as u64) + .sum() + } + pub fn add_bulk(&mut self, orders: Vec<BookOrder>) { self.insertion_order .extend(orders.iter().map(|o| o.order_id)); @@ -511,41 +564,14 @@

    Files

    } pub fn remove_by_id(&mut self, order_id: OrderId, ts_event: u64, sequence: u64) { - if self.orders.remove(&order_id).is_none() { - panic!( - "{}", - &BookIntegrityError::OrderNotFound(order_id, ts_event, sequence) - ); - } + assert!( + self.orders.remove(&order_id).is_some(), + "{}", + &BookIntegrityError::OrderNotFound(order_id, ts_event, sequence) + ); self.update_insertion_order(); } - #[must_use] - pub fn size(&self) -> f64 { - self.orders.values().map(|o| o.size.as_f64()).sum() - } - - #[must_use] - pub fn size_raw(&self) -> u64 { - self.orders.values().map(|o| o.size.raw).sum() - } - - #[must_use] - pub fn exposure(&self) -> f64 { - self.orders - .values() - .map(|o| o.price.as_f64() * o.size.as_f64()) - .sum() - } - - #[must_use] - pub fn exposure_raw(&self) -> u64 { - self.orders - .values() - .map(|o| ((o.price.as_f64() * o.size.as_f64()) * FIXED_SCALAR) as u64) - .sum() - } - fn check_order_for_this_level(&self, order: &BookOrder) { assert_eq!(order.price, self.price.value); } diff --git a/nightly/core/src/nautilus_model/orderbook/mod.rs.html b/nightly/core/src/nautilus_model/orderbook/mod.rs.html index 6463259152b8..47a1f8a191c2 100644 --- a/nightly/core/src/nautilus_model/orderbook/mod.rs.html +++ b/nightly/core/src/nautilus_model/orderbook/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source use nautilus_core::{time::UnixNanos, uuid::UUID4}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; -use thiserror; use ustr::Ustr; use crate::{ @@ -845,13 +851,15 @@

    Files

    OrderType::MarketIfTouched, ]; -pub fn ustr_hashmap_to_str(h: HashMap<Ustr, Ustr>) -> HashMap<String, String> { +#[must_use] +pub fn ustr_hashmap_to_str(h: HashMap<Ustr, Ustr>) -> HashMap<String, String> { h.into_iter() .map(|(k, v)| (k.to_string(), v.to_string())) .collect() } -pub fn str_hashmap_to_ustr(h: HashMap<String, String>) -> HashMap<Ustr, Ustr> { +#[must_use] +pub fn str_hashmap_to_ustr(h: HashMap<String, String>) -> HashMap<Ustr, Ustr> { h.into_iter() .map(|(k, v)| (Ustr::from(&k), Ustr::from(&v))) .collect() @@ -859,69 +867,69 @@

    Files

    impl OrderStatus { #[rustfmt::skip] - pub fn transition(&mut self, event: &OrderEvent) -> Result<OrderStatus, OrderError> { +
    pub fn transition(&mut self, event: &OrderEvent) -> Result<Self, OrderError> { let new_state = match (self, event) { - (OrderStatus::Initialized, OrderEvent::OrderDenied(_)) => OrderStatus::Denied, - (OrderStatus::Initialized, OrderEvent::OrderEmulated(_)) => OrderStatus::Emulated, // Emulated orders - (OrderStatus::Initialized, OrderEvent::OrderReleased(_)) => OrderStatus::Released, // Emulated orders - (OrderStatus::Initialized, OrderEvent::OrderSubmitted(_)) => OrderStatus::Submitted, - (OrderStatus::Initialized, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, // External orders - (OrderStatus::Initialized, OrderEvent::OrderAccepted(_)) => OrderStatus::Accepted, // External orders - (OrderStatus::Initialized, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, // External orders - (OrderStatus::Initialized, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, // External orders - (OrderStatus::Initialized, OrderEvent::OrderTriggered(_)) => OrderStatus::Triggered, // External orders - (OrderStatus::Emulated, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, // Emulated orders - (OrderStatus::Emulated, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, // Emulated orders - (OrderStatus::Emulated, OrderEvent::OrderReleased(_)) => OrderStatus::Released, // Emulated orders - (OrderStatus::Released, OrderEvent::OrderSubmitted(_)) => OrderStatus::Submitted, // Emulated orders - (OrderStatus::Released, OrderEvent::OrderDenied(_)) => OrderStatus::Denied, // Emulated orders - (OrderStatus::Released, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, // Execution algo - (OrderStatus::Submitted, OrderEvent::OrderPendingUpdate(_)) => OrderStatus::PendingUpdate, - (OrderStatus::Submitted, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, - (OrderStatus::Submitted, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, - (OrderStatus::Submitted, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, // FOK and IOC cases - (OrderStatus::Submitted, OrderEvent::OrderAccepted(_)) => OrderStatus::Accepted, - (OrderStatus::Submitted, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::Submitted, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, - (OrderStatus::Accepted, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, // StopLimit order - (OrderStatus::Accepted, OrderEvent::OrderPendingUpdate(_)) => OrderStatus::PendingUpdate, - (OrderStatus::Accepted, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, - (OrderStatus::Accepted, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, - (OrderStatus::Accepted, OrderEvent::OrderTriggered(_)) => OrderStatus::Triggered, - (OrderStatus::Accepted, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, - (OrderStatus::Accepted, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::Accepted, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, - (OrderStatus::Canceled, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, // Real world possibility - (OrderStatus::Canceled, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, // Real world possibility - (OrderStatus::PendingUpdate, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, - (OrderStatus::PendingUpdate, OrderEvent::OrderAccepted(_)) => OrderStatus::Accepted, - (OrderStatus::PendingUpdate, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, - (OrderStatus::PendingUpdate, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, - (OrderStatus::PendingUpdate, OrderEvent::OrderTriggered(_)) => OrderStatus::Triggered, - (OrderStatus::PendingUpdate, OrderEvent::OrderPendingUpdate(_)) => OrderStatus::PendingUpdate, // Allow multiple requests - (OrderStatus::PendingUpdate, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, - (OrderStatus::PendingUpdate, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::PendingUpdate, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, - (OrderStatus::PendingCancel, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, - (OrderStatus::PendingCancel, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, // Allow multiple requests - (OrderStatus::PendingCancel, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, - (OrderStatus::PendingCancel, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, - (OrderStatus::PendingCancel, OrderEvent::OrderAccepted(_)) => OrderStatus::Accepted, // Allow failed cancel requests - (OrderStatus::PendingCancel, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::PendingCancel, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, - (OrderStatus::Triggered, OrderEvent::OrderRejected(_)) => OrderStatus::Rejected, - (OrderStatus::Triggered, OrderEvent::OrderPendingUpdate(_)) => OrderStatus::PendingUpdate, - (OrderStatus::Triggered, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, - (OrderStatus::Triggered, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, - (OrderStatus::Triggered, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, - (OrderStatus::Triggered, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::Triggered, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, - (OrderStatus::PartiallyFilled, OrderEvent::OrderPendingUpdate(_)) => OrderStatus::PendingUpdate, - (OrderStatus::PartiallyFilled, OrderEvent::OrderPendingCancel(_)) => OrderStatus::PendingCancel, - (OrderStatus::PartiallyFilled, OrderEvent::OrderCanceled(_)) => OrderStatus::Canceled, - (OrderStatus::PartiallyFilled, OrderEvent::OrderExpired(_)) => OrderStatus::Expired, - (OrderStatus::PartiallyFilled, OrderEvent::OrderPartiallyFilled(_)) => OrderStatus::PartiallyFilled, - (OrderStatus::PartiallyFilled, OrderEvent::OrderFilled(_)) => OrderStatus::Filled, + (Self::Initialized, OrderEvent::OrderDenied(_)) => Self::Denied, + (Self::Initialized, OrderEvent::OrderEmulated(_)) => Self::Emulated, // Emulated orders + (Self::Initialized, OrderEvent::OrderReleased(_)) => Self::Released, // Emulated orders + (Self::Initialized, OrderEvent::OrderSubmitted(_)) => Self::Submitted, + (Self::Initialized, OrderEvent::OrderRejected(_)) => Self::Rejected, // External orders + (Self::Initialized, OrderEvent::OrderAccepted(_)) => Self::Accepted, // External orders + (Self::Initialized, OrderEvent::OrderCanceled(_)) => Self::Canceled, // External orders + (Self::Initialized, OrderEvent::OrderExpired(_)) => Self::Expired, // External orders + (Self::Initialized, OrderEvent::OrderTriggered(_)) => Self::Triggered, // External orders + (Self::Emulated, OrderEvent::OrderCanceled(_)) => Self::Canceled, // Emulated orders + (Self::Emulated, OrderEvent::OrderExpired(_)) => Self::Expired, // Emulated orders + (Self::Emulated, OrderEvent::OrderReleased(_)) => Self::Released, // Emulated orders + (Self::Released, OrderEvent::OrderSubmitted(_)) => Self::Submitted, // Emulated orders + (Self::Released, OrderEvent::OrderDenied(_)) => Self::Denied, // Emulated orders + (Self::Released, OrderEvent::OrderCanceled(_)) => Self::Canceled, // Execution algo + (Self::Submitted, OrderEvent::OrderPendingUpdate(_)) => Self::PendingUpdate, + (Self::Submitted, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, + (Self::Submitted, OrderEvent::OrderRejected(_)) => Self::Rejected, + (Self::Submitted, OrderEvent::OrderCanceled(_)) => Self::Canceled, // FOK and IOC cases + (Self::Submitted, OrderEvent::OrderAccepted(_)) => Self::Accepted, + (Self::Submitted, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::Submitted, OrderEvent::OrderFilled(_)) => Self::Filled, + (Self::Accepted, OrderEvent::OrderRejected(_)) => Self::Rejected, // StopLimit order + (Self::Accepted, OrderEvent::OrderPendingUpdate(_)) => Self::PendingUpdate, + (Self::Accepted, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, + (Self::Accepted, OrderEvent::OrderCanceled(_)) => Self::Canceled, + (Self::Accepted, OrderEvent::OrderTriggered(_)) => Self::Triggered, + (Self::Accepted, OrderEvent::OrderExpired(_)) => Self::Expired, + (Self::Accepted, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::Accepted, OrderEvent::OrderFilled(_)) => Self::Filled, + (Self::Canceled, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, // Real world possibility + (Self::Canceled, OrderEvent::OrderFilled(_)) => Self::Filled, // Real world possibility + (Self::PendingUpdate, OrderEvent::OrderRejected(_)) => Self::Rejected, + (Self::PendingUpdate, OrderEvent::OrderAccepted(_)) => Self::Accepted, + (Self::PendingUpdate, OrderEvent::OrderCanceled(_)) => Self::Canceled, + (Self::PendingUpdate, OrderEvent::OrderExpired(_)) => Self::Expired, + (Self::PendingUpdate, OrderEvent::OrderTriggered(_)) => Self::Triggered, + (Self::PendingUpdate, OrderEvent::OrderPendingUpdate(_)) => Self::PendingUpdate, // Allow multiple requests + (Self::PendingUpdate, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, + (Self::PendingUpdate, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::PendingUpdate, OrderEvent::OrderFilled(_)) => Self::Filled, + (Self::PendingCancel, OrderEvent::OrderRejected(_)) => Self::Rejected, + (Self::PendingCancel, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, // Allow multiple requests + (Self::PendingCancel, OrderEvent::OrderCanceled(_)) => Self::Canceled, + (Self::PendingCancel, OrderEvent::OrderExpired(_)) => Self::Expired, + (Self::PendingCancel, OrderEvent::OrderAccepted(_)) => Self::Accepted, // Allow failed cancel requests + (Self::PendingCancel, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::PendingCancel, OrderEvent::OrderFilled(_)) => Self::Filled, + (Self::Triggered, OrderEvent::OrderRejected(_)) => Self::Rejected, + (Self::Triggered, OrderEvent::OrderPendingUpdate(_)) => Self::PendingUpdate, + (Self::Triggered, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, + (Self::Triggered, OrderEvent::OrderCanceled(_)) => Self::Canceled, + (Self::Triggered, OrderEvent::OrderExpired(_)) => Self::Expired, + (Self::Triggered, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::Triggered, OrderEvent::OrderFilled(_)) => Self::Filled, + (Self::PartiallyFilled, OrderEvent::OrderPendingUpdate(_)) => Self::PendingUpdate, + (Self::PartiallyFilled, OrderEvent::OrderPendingCancel(_)) => Self::PendingCancel, + (Self::PartiallyFilled, OrderEvent::OrderCanceled(_)) => Self::Canceled, + (Self::PartiallyFilled, OrderEvent::OrderExpired(_)) => Self::Expired, + (Self::PartiallyFilled, OrderEvent::OrderPartiallyFilled(_)) => Self::PartiallyFilled, + (Self::PartiallyFilled, OrderEvent::OrderFilled(_)) => Self::Filled, _ => return Err(OrderError::InvalidStateTransition), }; Ok(new_state) @@ -1285,7 +1293,7 @@

    Files

    } fn submitted(&mut self, event: &OrderSubmitted) { - self.account_id = Some(event.account_id) + self.account_id = Some(event.account_id); } fn accepted(&mut self, event: &OrderAccepted) { @@ -1369,10 +1377,11 @@

    Files

    OrderSide::Sell if avg_px < current_price => Some(current_price - avg_px), _ => None, } - }) + }); } - pub fn opposite_side(side: OrderSide) -> OrderSide { + #[must_use] + pub fn opposite_side(side: OrderSide) -> OrderSide { match side { OrderSide::Buy => OrderSide::Sell, OrderSide::Sell => OrderSide::Buy, @@ -1380,7 +1389,8 @@

    Files

    } } - pub fn closing_side(side: PositionSide) -> OrderSide { + #[must_use] + pub fn closing_side(side: PositionSide) -> OrderSide { match side { PositionSide::Long => OrderSide::Sell, PositionSide::Short => OrderSide::Buy, @@ -1389,7 +1399,8 @@

    Files

    } } - pub fn signed_decimal_qty(&self) -> Decimal { + #[must_use] + pub fn signed_decimal_qty(&self) -> Decimal { match self.side { OrderSide::Buy => self.quantity.as_decimal(), OrderSide::Sell => -self.quantity.as_decimal(), @@ -1397,7 +1408,8 @@

    Files

    } } - pub fn would_reduce_only(&self, side: PositionSide, position_qty: Quantity) -> bool { + #[must_use] + pub fn would_reduce_only(&self, side: PositionSide, position_qty: Quantity) -> bool { if side == PositionSide::Flat { return false; } @@ -1411,11 +1423,13 @@

    Files

    } } - pub fn commission(&self, currency: &Currency) -> Option<Money> { + #[must_use] + pub fn commission(&self, currency: &Currency) -> Option<Money> { self.commissions.get(currency).copied() } - pub fn commissions(&self) -> HashMap<Currency, Money> { + #[must_use] + pub fn commissions(&self) -> HashMap<Currency, Money> { self.commissions.clone() } } @@ -1453,7 +1467,7 @@

    Files

    #[case(OrderSide::NoOrderSide, OrderSide::NoOrderSide)]
    fn test_order_opposite_side(#[case] order_side: OrderSide, #[case] expected_side: OrderSide) { let result = OrderCore::opposite_side(order_side); - assert_eq!(result, expected_side) + assert_eq!(result, expected_side); } #[rstest] @@ -1462,7 +1476,7 @@

    Files

    #[case(PositionSide::NoPositionSide, OrderSide::NoOrderSide)]
    fn test_closing_side(#[case] position_side: PositionSide, #[case] expected_side: OrderSide) { let result = OrderCore::closing_side(position_side); - assert_eq!(result, expected_side) + assert_eq!(result, expected_side); } #[rstest] @@ -1477,7 +1491,7 @@

    Files

    .into(); let result = order.signed_decimal_qty(); - assert_eq!(result, expected) + assert_eq!(result, expected); } #[rustfmt::skip] @@ -1539,7 +1553,7 @@

    Files

    assert_eq!(order.client_order_id, init.client_order_id); assert_eq!(order.status(), OrderStatus::Filled); - assert_eq!(order.filled_qty(), Quantity::from(100000)); + assert_eq!(order.filled_qty(), Quantity::from(100_000)); assert_eq!(order.leaves_qty(), Quantity::from(0)); assert_eq!(order.avg_px(), Some(1.0)); assert!(!order.is_open()); diff --git a/nightly/core/src/nautilus_model/orders/default.rs.html b/nightly/core/src/nautilus_model/orders/default.rs.html index c6cb7adfe775..ef56a4de8fb6 100644 --- a/nightly/core/src/nautilus_model/orders/default.rs.html +++ b/nightly/core/src/nautilus_model/orders/default.rs.html @@ -1,4 +1,4 @@ -default.rs - source /// Provides a default [`LimitOrder`] used for testing. impl Default for LimitOrder { fn default() -> Self { - LimitOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -399,7 +399,7 @@

    Files

    /// Provides a default [`LimitIfTouchedOrder`] used for testing. impl Default for LimitIfTouchedOrder { fn default() -> Self { - LimitIfTouchedOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -434,7 +434,7 @@

    Files

    /// Provides a default [`MarketOrder`] used for testing. impl Default for MarketOrder { fn default() -> Self { - MarketOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -462,7 +462,7 @@

    Files

    /// Provides a default [`MarketIfTouchedOrder`] used for testing. impl Default for MarketIfTouchedOrder { fn default() -> Self { - MarketIfTouchedOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -495,7 +495,7 @@

    Files

    /// Provides a default [`MarketToLimitOrder`] used for testing. impl Default for MarketToLimitOrder { fn default() -> Self { - MarketToLimitOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -525,7 +525,7 @@

    Files

    /// Provides a default [`StopLimitOrder`] used for testing. impl Default for StopLimitOrder { fn default() -> Self { - StopLimitOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -560,7 +560,7 @@

    Files

    /// Provides a default [`StopMarketOrder`] used for testing. impl Default for StopMarketOrder { fn default() -> Self { - StopMarketOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -593,7 +593,7 @@

    Files

    /// Provides a default [`TrailingStopLimitOrder`] used for testing. impl Default for TrailingStopLimitOrder { fn default() -> Self { - TrailingStopLimitOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), @@ -631,7 +631,7 @@

    Files

    /// Provides a default [`TrailingStopMarketOrder`] used for testing. impl Default for TrailingStopMarketOrder { fn default() -> Self { - TrailingStopMarketOrder::new( + Self::new( TraderId::default(), StrategyId::default(), InstrumentId::default(), diff --git a/nightly/core/src/nautilus_model/orders/limit.rs.html b/nightly/core/src/nautilus_model/orders/limit.rs.html index 1270f05157fb..d7ca88209b66 100644 --- a/nightly/core/src/nautilus_model/orders/limit.rs.html +++ b/nightly/core/src/nautilus_model/orders/limit.rs.html @@ -1,4 +1,4 @@ -limit.rs - source 380 381 382 +383 +384
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -711,16 +713,18 @@ 

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.price) + self.core.set_slippage(self.price); }; Ok(()) } fn update(&mut self, event: &OrderUpdated) { - if event.trigger_price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!( + event.trigger_price.is_none(), + "{}", + OrderError::InvalidOrderEvent + ); if let Some(price) = event.price { self.price = price; @@ -733,7 +737,7 @@

    Files

    impl From<OrderInitialized> for LimitOrder { fn from(event: OrderInitialized) -> Self { - LimitOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/limit_if_touched.rs.html b/nightly/core/src/nautilus_model/orders/limit_if_touched.rs.html index 44792cd555ed..c05b03181a2f 100644 --- a/nightly/core/src/nautilus_model/orders/limit_if_touched.rs.html +++ b/nightly/core/src/nautilus_model/orders/limit_if_touched.rs.html @@ -1,4 +1,4 @@ -limit_if_touched.rs - source pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") )]
    pub struct LimitIfTouchedOrder { - core: OrderCore, pub price: Price, pub trigger_price: Price, pub trigger_type: TriggerType, @@ -454,6 +453,7 @@

    Files

    pub trigger_instrument_id: Option<InstrumentId>, pub is_triggered: bool, pub ts_triggered: Option<UnixNanos>, + core: OrderCore, } impl LimitIfTouchedOrder { @@ -737,7 +737,7 @@

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.price) + self.core.set_slippage(self.price); }; Ok(()) @@ -759,7 +759,7 @@

    Files

    impl From<OrderInitialized> for LimitIfTouchedOrder { fn from(event: OrderInitialized) -> Self { - LimitIfTouchedOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/market.rs.html b/nightly/core/src/nautilus_model/orders/market.rs.html index 2dc648f68de3..b3e866f49b9c 100644 --- a/nightly/core/src/nautilus_model/orders/market.rs.html +++ b/nightly/core/src/nautilus_model/orders/market.rs.html @@ -1,4 +1,4 @@ -market.rs - source 396 397 398 +399 +400
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -721,12 +723,12 @@ 

    Files

    } fn update(&mut self, event: &OrderUpdated) { - if event.price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } - if event.trigger_price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!(event.price.is_none(), "{}", OrderError::InvalidOrderEvent); + assert!( + event.trigger_price.is_none(), + "{}", + OrderError::InvalidOrderEvent + ); self.quantity = event.quantity; self.leaves_qty = self.quantity - self.filled_qty; @@ -735,7 +737,7 @@

    Files

    impl From<OrderInitialized> for MarketOrder { fn from(event: OrderInitialized) -> Self { - MarketOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, @@ -767,10 +769,12 @@

    Files

    mod tests { use rstest::rstest; - use crate::enums::OrderSide; - use crate::instruments::currency_pair::CurrencyPair; - use crate::instruments::stubs::*; - use crate::{enums::TimeInForce, orders::stubs::*, types::quantity::Quantity}; + use crate::{ + enums::{OrderSide, TimeInForce}, + instruments::{currency_pair::CurrencyPair, stubs::*}, + orders::stubs::*, + types::quantity::Quantity, + }; #[rstest] #[should_panic(expected = "Condition failed: invalid `Quantity`, should be positive and was 0")] diff --git a/nightly/core/src/nautilus_model/orders/market_if_touched.rs.html b/nightly/core/src/nautilus_model/orders/market_if_touched.rs.html index 04a0bd57ceeb..92e45ce5f54a 100644 --- a/nightly/core/src/nautilus_model/orders/market_if_touched.rs.html +++ b/nightly/core/src/nautilus_model/orders/market_if_touched.rs.html @@ -1,4 +1,4 @@ -market_if_touched.rs - source 385 386 387 -388 -389
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -434,7 +432,6 @@ 

    Files

    pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") )]
    pub struct MarketIfTouchedOrder { - core: OrderCore, pub trigger_price: Price, pub trigger_type: TriggerType, pub expire_time: Option<UnixNanos>, @@ -442,6 +439,7 @@

    Files

    pub trigger_instrument_id: Option<InstrumentId>, pub is_triggered: bool, pub ts_triggered: Option<UnixNanos>, + core: OrderCore, } impl MarketIfTouchedOrder { @@ -721,16 +719,14 @@

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.trigger_price) + self.core.set_slippage(self.trigger_price); }; Ok(()) } fn update(&mut self, event: &OrderUpdated) { - if event.price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!(event.price.is_none(), "{}", OrderError::InvalidOrderEvent); if let Some(trigger_price) = event.trigger_price { self.trigger_price = trigger_price; @@ -743,7 +739,7 @@

    Files

    impl From<OrderInitialized> for MarketIfTouchedOrder { fn from(event: OrderInitialized) -> Self { - MarketIfTouchedOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/market_to_limit.rs.html b/nightly/core/src/nautilus_model/orders/market_to_limit.rs.html index 8775fefecd45..570c8d4bde60 100644 --- a/nightly/core/src/nautilus_model/orders/market_to_limit.rs.html +++ b/nightly/core/src/nautilus_model/orders/market_to_limit.rs.html @@ -1,4 +1,4 @@ -market_to_limit.rs - source 370 371 372 +373 +374
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -696,16 +698,18 @@ 

    Files

    self.core.apply(event)?; if is_order_filled && self.price.is_some() { - self.core.set_slippage(self.price.unwrap()) + self.core.set_slippage(self.price.unwrap()); }; Ok(()) } fn update(&mut self, event: &OrderUpdated) { - if event.trigger_price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!( + event.trigger_price.is_none(), + "{}", + OrderError::InvalidOrderEvent + ); if let Some(price) = event.price { self.price = Some(price); @@ -718,7 +722,7 @@

    Files

    impl From<OrderInitialized> for MarketToLimitOrder { fn from(event: OrderInitialized) -> Self { - MarketToLimitOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/mod.rs.html b/nightly/core/src/nautilus_model/orders/mod.rs.html index 4404b1dfa9aa..078f75e75edc 100644 --- a/nightly/core/src/nautilus_model/orders/mod.rs.html +++ b/nightly/core/src/nautilus_model/orders/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source pub trigger_instrument_id: Option<InstrumentId>, pub is_triggered: bool, pub ts_triggered: Option<UnixNanos>, + core: OrderCore, } impl StopLimitOrder { @@ -737,7 +737,7 @@

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.price) + self.core.set_slippage(self.price); }; Ok(()) @@ -761,7 +761,7 @@

    Files

    impl From<OrderInitialized> for StopLimitOrder { fn from(event: OrderInitialized) -> Self { - StopLimitOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/stop_market.rs.html b/nightly/core/src/nautilus_model/orders/stop_market.rs.html index fada829e0255..396a9566472d 100644 --- a/nightly/core/src/nautilus_model/orders/stop_market.rs.html +++ b/nightly/core/src/nautilus_model/orders/stop_market.rs.html @@ -1,4 +1,4 @@ -stop_market.rs - source 386 387 388 -389 -390
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -436,7 +434,6 @@ 

    Files

    pyclass(module = "nautilus_trader.core.nautilus_pyo3.model") )]
    pub struct StopMarketOrder { - core: OrderCore, pub trigger_price: Price, pub trigger_type: TriggerType, pub expire_time: Option<UnixNanos>, @@ -444,6 +441,7 @@

    Files

    pub trigger_instrument_id: Option<InstrumentId>, pub is_triggered: bool, pub ts_triggered: Option<UnixNanos>, + core: OrderCore, } impl StopMarketOrder { @@ -723,16 +721,14 @@

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.trigger_price) + self.core.set_slippage(self.trigger_price); }; Ok(()) } fn update(&mut self, event: &OrderUpdated) { - if event.price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!(event.price.is_none(), "{}", OrderError::InvalidOrderEvent); if let Some(trigger_price) = event.trigger_price { self.trigger_price = trigger_price; @@ -745,7 +741,7 @@

    Files

    impl From<OrderInitialized> for StopMarketOrder { fn from(event: OrderInitialized) -> Self { - StopMarketOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/stubs.rs.html b/nightly/core/src/nautilus_model/orders/stubs.rs.html index 272f701f5e3c..bb75b6015975 100644 --- a/nightly/core/src/nautilus_model/orders/stubs.rs.html +++ b/nightly/core/src/nautilus_model/orders/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source 131 132 133 +134 +135 +136 +137 +138
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -152,14 +157,18 @@ 

    Files

    use nautilus_core::uuid::UUID4; -use crate::identifiers::client_order_id::ClientOrderId; -use crate::identifiers::instrument_id::InstrumentId; use crate::{ enums::{LiquiditySide, OrderSide, TimeInForce}, events::order::filled::OrderFilled, identifiers::{ - account_id::AccountId, position_id::PositionId, strategy_id::StrategyId, stubs::*, - trade_id::TradeId, venue_order_id::VenueOrderId, + account_id::AccountId, + client_order_id::ClientOrderId, + instrument_id::InstrumentId, + position_id::PositionId, + strategy_id::StrategyId, + stubs::{strategy_id_ema_cross, trader_id}, + trade_id::TradeId, + venue_order_id::VenueOrderId, }, instruments::Instrument, orders::{base::Order, market::MarketOrder}, @@ -230,7 +239,8 @@

    Files

    pub struct TestOrderStubs; impl TestOrderStubs { - pub fn market_order( + #[must_use] + pub fn market_order( instrument_id: InstrumentId, order_side: OrderSide, quantity: Quantity, @@ -251,7 +261,7 @@

    Files

    quantity, time_in_force, UUID4::new(), - 12321312321312, + 12_321_312_321_312, false, false, None, diff --git a/nightly/core/src/nautilus_model/orders/trailing_stop_limit.rs.html b/nightly/core/src/nautilus_model/orders/trailing_stop_limit.rs.html index 4e33256533dd..42817831c6ce 100644 --- a/nightly/core/src/nautilus_model/orders/trailing_stop_limit.rs.html +++ b/nightly/core/src/nautilus_model/orders/trailing_stop_limit.rs.html @@ -1,4 +1,4 @@ -trailing_stop_limit.rs - source self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.price) + self.core.set_slippage(self.price); }; Ok(()) @@ -780,7 +780,7 @@

    Files

    impl From<OrderInitialized> for TrailingStopLimitOrder { fn from(event: OrderInitialized) -> Self { - TrailingStopLimitOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/orders/trailing_stop_market.rs.html b/nightly/core/src/nautilus_model/orders/trailing_stop_market.rs.html index 821437511b0f..6477eb258b67 100644 --- a/nightly/core/src/nautilus_model/orders/trailing_stop_market.rs.html +++ b/nightly/core/src/nautilus_model/orders/trailing_stop_market.rs.html @@ -1,4 +1,4 @@ -trailing_stop_market.rs - source 394 395 396 -397 -398
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -737,16 +735,14 @@ 

    Files

    self.core.apply(event)?; if is_order_filled { - self.core.set_slippage(self.trigger_price) + self.core.set_slippage(self.trigger_price); }; Ok(()) } fn update(&mut self, event: &OrderUpdated) { - if event.price.is_some() { - panic!("{}", OrderError::InvalidOrderEvent); - } + assert!(event.price.is_none(), "{}", OrderError::InvalidOrderEvent); if let Some(trigger_price) = event.trigger_price { self.trigger_price = trigger_price; @@ -759,7 +755,7 @@

    Files

    impl From<OrderInitialized> for TrailingStopMarketOrder { fn from(event: OrderInitialized) -> Self { - TrailingStopMarketOrder::new( + Self::new( event.trader_id, event.strategy_id, event.instrument_id, diff --git a/nightly/core/src/nautilus_model/position.rs.html b/nightly/core/src/nautilus_model/position.rs.html index 7a275611449d..391131663ac4 100644 --- a/nightly/core/src/nautilus_model/position.rs.html +++ b/nightly/core/src/nautilus_model/position.rs.html @@ -1,4 +1,4 @@ -position.rs - source 2078 2079 2080 -2081 -2082 -2083 -2084
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -2099,32 +2095,28 @@ 

    Files

    // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use std::collections::{HashMap, HashSet}; -use std::fmt::Display; -use std::hash::{Hash, Hasher}; +use std::{ + collections::{HashMap, HashSet}, + fmt::Display, + hash::{Hash, Hasher}, +}; use anyhow::Result; use nautilus_core::time::UnixNanos; use pyo3::prelude::*; use serde::{Deserialize, Serialize}; -use crate::enums::{OrderSide, PositionSide}; -use crate::events::order::filled::OrderFilled; -use crate::identifiers::account_id::AccountId; -use crate::identifiers::client_order_id::ClientOrderId; -use crate::identifiers::instrument_id::InstrumentId; -use crate::identifiers::position_id::PositionId; -use crate::identifiers::strategy_id::StrategyId; -use crate::identifiers::symbol::Symbol; -use crate::identifiers::trade_id::TradeId; -use crate::identifiers::trader_id::TraderId; -use crate::identifiers::venue::Venue; -use crate::identifiers::venue_order_id::VenueOrderId; -use crate::instruments::Instrument; -use crate::types::currency::Currency; -use crate::types::money::Money; -use crate::types::price::Price; -use crate::types::quantity::Quantity; +use crate::{ + enums::{OrderSide, PositionSide}, + events::order::filled::OrderFilled, + identifiers::{ + account_id::AccountId, client_order_id::ClientOrderId, instrument_id::InstrumentId, + position_id::PositionId, strategy_id::StrategyId, symbol::Symbol, trade_id::TradeId, + trader_id::TraderId, venue::Venue, venue_order_id::VenueOrderId, + }, + instruments::Instrument, + types::{currency::Currency, money::Money, price::Price, quantity::Quantity}, +}; /// Represents a position in a financial market. /// @@ -2611,27 +2603,27 @@

    Files

    ////////////////////////////////////////////////////////////////////////////////
    #[cfg(test)] mod tests { - use crate::enums::{LiquiditySide, OrderSide, OrderType, PositionSide}; - use crate::events::order::filled::OrderFilled; - use crate::identifiers::account_id::AccountId; - use crate::identifiers::position_id::PositionId; - use crate::identifiers::strategy_id::StrategyId; - use crate::identifiers::stubs::uuid4; - use crate::identifiers::trade_id::TradeId; - use crate::identifiers::venue_order_id::VenueOrderId; - use crate::instruments::crypto_perpetual::CryptoPerpetual; - use crate::instruments::currency_pair::CurrencyPair; - use crate::instruments::stubs::*; - use crate::orders::market::MarketOrder; - use crate::orders::stubs::{TestOrderEventStubs, TestOrderStubs}; - use crate::position::Position; - use crate::stubs::*; - use crate::types::money::Money; - use crate::types::price::Price; - use crate::types::quantity::Quantity; - use rstest::rstest; use std::str::FromStr; + use rstest::rstest; + + use crate::{ + enums::{LiquiditySide, OrderSide, OrderType, PositionSide}, + events::order::filled::OrderFilled, + identifiers::{ + account_id::AccountId, position_id::PositionId, strategy_id::StrategyId, stubs::uuid4, + trade_id::TradeId, venue_order_id::VenueOrderId, + }, + instruments::{crypto_perpetual::CryptoPerpetual, currency_pair::CurrencyPair, stubs::*}, + orders::{ + market::MarketOrder, + stubs::{TestOrderEventStubs, TestOrderStubs}, + }, + position::Position, + stubs::*, + types::{money::Money, price::Price, quantity::Quantity}, + }; + #[rstest] fn test_position_long_display(test_position_long: Position) { let display = format!("{test_position_long}"); diff --git a/nightly/core/src/nautilus_model/python/common.rs.html b/nightly/core/src/nautilus_model/python/common.rs.html index 08503db43b88..214fa22abbb8 100644 --- a/nightly/core/src/nautilus_model/python/common.rs.html +++ b/nightly/core/src/nautilus_model/python/common.rs.html @@ -1,4 +1,4 @@ -common.rs - source 211 212 213 -214 -215 -216
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -235,7 +232,6 @@ 

    Files

    exceptions::PyValueError, prelude::*, types::{PyDict, PyList}, - PyResult, Python, }; use serde_json::Value; use strum::IntoEnumIterator; @@ -261,7 +257,8 @@

    Files

    } impl EnumIterator { - pub fn new<E>(py: Python<'_>) -> Self + #[must_use] + pub fn new<E>(py: Python<'_>) -> Self where E: strum::IntoEnumIterator + IntoPy<Py<PyAny>>, <E as IntoEnumIterator>::Iterator: Send, @@ -283,7 +280,7 @@

    Files

    match val { Value::Object(map) => { - for (key, value) in map.iter() { + for (key, value) in map { let py_value = value_to_pyobject(py, value)?; dict.set_item(key, py_value)?; } @@ -311,7 +308,7 @@

    Files

    } Value::Array(arr) => { let py_list = PyList::new(py, &[] as &[PyObject]); - for item in arr.iter() { + for item in arr { let py_item = value_to_pyobject(py, item)?; py_list.append(py_item)?; } @@ -374,16 +371,13 @@

    Files

    .unwrap(), 42 ); - assert_eq!( - py_dict - .get_item("is_reconciliation") - .unwrap() - .unwrap() - .downcast::<PyBool>() - .unwrap() - .is_true(), - false - ); + assert!(!py_dict + .get_item("is_reconciliation") + .unwrap() + .unwrap() + .downcast::<PyBool>() + .unwrap() + .is_true()); }); } @@ -405,7 +399,7 @@

    Files

    let val = Value::Bool(true); let py_obj = value_to_pyobject(py, &val).unwrap(); - assert_eq!(py_obj.extract::<bool>(py).unwrap(), true); + assert!(py_obj.extract::<bool>(py).unwrap()); }); } diff --git a/nightly/core/src/nautilus_model/python/data/bar.rs.html b/nightly/core/src/nautilus_model/python/data/bar.rs.html index 3bcb92ece963..8fc56329e5e7 100644 --- a/nightly/core/src/nautilus_model/python/data/bar.rs.html +++ b/nightly/core/src/nautilus_model/python/data/bar.rs.html @@ -1,4 +1,4 @@ -bar.rs - source 360 361 362 -363
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -391,6 +390,7 @@ 

    Files

    }; use pyo3::{prelude::*, pyclass::CompareOp, types::PyDict}; +use super::data_to_pycapsule; use crate::{ data::{ bar::{Bar, BarSpecification, BarType}, @@ -402,8 +402,6 @@

    Files

    types::{price::Price, quantity::Quantity}, }; -use super::data_to_pycapsule; - #[pymethods] impl BarSpecification { #[new] @@ -491,7 +489,7 @@

    Files

    #[staticmethod] #[pyo3(name = "from_str")] fn py_from_str(value: &str) -> PyResult<Self> { - BarType::from_str(value).map_err(to_pyvalue_err) + Self::from_str(value).map_err(to_pyvalue_err) } } @@ -697,7 +695,7 @@

    Files

    Python::with_gil(|py| { let dict_string = bar.py_as_dict(py).unwrap().to_string(); - let expected_string = r#"{'type': 'Bar', 'bar_type': 'AUDUSD.SIM-1-MINUTE-BID-EXTERNAL', 'open': '1.00001', 'high': '1.00004', 'low': '1.00002', 'close': '1.00003', 'volume': '100000', 'ts_event': 0, 'ts_init': 1}"#; + let expected_string = r"{'type': 'Bar', 'bar_type': 'AUDUSD.SIM-1-MINUTE-BID-EXTERNAL', 'open': '1.00001', 'high': '1.00004', 'low': '1.00002', 'close': '1.00003', 'volume': '100000', 'ts_event': 0, 'ts_init': 1}"; assert_eq!(dict_string, expected_string); }); } diff --git a/nightly/core/src/nautilus_model/python/data/delta.rs.html b/nightly/core/src/nautilus_model/python/data/delta.rs.html index f62a31acc13b..1d09a832964c 100644 --- a/nightly/core/src/nautilus_model/python/data/delta.rs.html +++ b/nightly/core/src/nautilus_model/python/data/delta.rs.html @@ -1,4 +1,4 @@ -delta.rs - source 264 265 266 -267
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -294,6 +293,7 @@ 

    Files

    }; use pyo3::{prelude::*, pyclass::CompareOp, types::PyDict}; +use super::data_to_pycapsule; use crate::{ data::{delta::OrderBookDelta, order::BookOrder, Data}, enums::BookAction, @@ -301,8 +301,6 @@

    Files

    python::common::PY_MODULE_MODEL, }; -use super::data_to_pycapsule; - #[pymethods] impl OrderBookDelta { #[new] @@ -505,7 +503,7 @@

    Files

    Python::with_gil(|py| { let dict_string = delta.py_as_dict(py).unwrap().to_string(); - let expected_string = r#"{'type': 'OrderBookDelta', 'instrument_id': 'AAPL.XNAS', 'action': 'ADD', 'order': {'side': 'BUY', 'price': '100.00', 'size': '10', 'order_id': 123456}, 'flags': 0, 'sequence': 1, 'ts_event': 1, 'ts_init': 2}"#; + let expected_string = r"{'type': 'OrderBookDelta', 'instrument_id': 'AAPL.XNAS', 'action': 'ADD', 'order': {'side': 'BUY', 'price': '100.00', 'size': '10', 'order_id': 123456}, 'flags': 0, 'sequence': 1, 'ts_event': 1, 'ts_init': 2}"; assert_eq!(dict_string, expected_string); }); } diff --git a/nightly/core/src/nautilus_model/python/data/deltas.rs.html b/nightly/core/src/nautilus_model/python/data/deltas.rs.html index 8eaa11ee1687..39e0b294db1c 100644 --- a/nightly/core/src/nautilus_model/python/data/deltas.rs.html +++ b/nightly/core/src/nautilus_model/python/data/deltas.rs.html @@ -1,4 +1,4 @@ -deltas.rs - source 122 123 124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -142,13 +155,15 @@ 

    Files

    use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, + ops::Deref, }; use nautilus_core::time::UnixNanos; -use pyo3::{prelude::*, pyclass::CompareOp}; +use pyo3::{prelude::*, pyclass::CompareOp, types::PyCapsule}; use crate::{ data::{delta::OrderBookDelta, deltas::OrderBookDeltas}, + ffi::data::deltas::OrderBookDeltas_API, identifiers::instrument_id::InstrumentId, python::common::PY_MODULE_MODEL, }; @@ -225,6 +240,17 @@

    Files

    format!("{}:{}", PY_MODULE_MODEL, stringify!(OrderBookDeltas)) } + #[staticmethod] + #[pyo3(name = "from_pycapsule")] + pub fn py_from_pycapsule(capsule: &PyAny) -> Self { + let capsule: &PyCapsule = capsule + .downcast() + .expect("Error on downcast to `&PyCapsule`"); + let data: &OrderBookDeltas_API = + unsafe { &*(capsule.pointer() as *const OrderBookDeltas_API) }; + data.deref().clone() + } + // /// Creates a `PyCapsule` containing a raw pointer to a `Data::Delta` object. // /// // /// This function takes the current object (assumed to be of a type that can be represented as diff --git a/nightly/core/src/nautilus_model/python/data/depth.rs.html b/nightly/core/src/nautilus_model/python/data/depth.rs.html index 92bf58068a34..77606c82942e 100644 --- a/nightly/core/src/nautilus_model/python/data/depth.rs.html +++ b/nightly/core/src/nautilus_model/python/data/depth.rs.html @@ -1,4 +1,4 @@ -depth.rs - source 304 305 306 -307
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -334,6 +333,7 @@ 

    Files

    }; use pyo3::{prelude::*, pyclass::CompareOp, types::PyDict}; +use super::data_to_pycapsule; use crate::{ data::{ depth::{OrderBookDepth10, DEPTH10_LEN}, @@ -346,8 +346,6 @@

    Files

    types::{price::Price, quantity::Quantity}, }; -use super::data_to_pycapsule; - #[pymethods] impl OrderBookDepth10 { #[allow(clippy::too_many_arguments)] @@ -575,7 +573,7 @@

    Files

    let bid_counts: [u32; 10] = [1; 10]; let ask_counts: [u32; 10] = [1; 10]; - OrderBookDepth10::new( + Self::new( instrument_id, bids, asks, diff --git a/nightly/core/src/nautilus_model/python/data/mod.rs.html b/nightly/core/src/nautilus_model/python/data/mod.rs.html index a70a5684c9dd..f0ccfe53ec52 100644 --- a/nightly/core/src/nautilus_model/python/data/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/data/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 73 74 75 +76 +77 +78
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -121,6 +124,7 @@ 

    Files

    /// `PyCapsule` in Python must ensure they understand how to extract and use the /// encapsulated `Data` safely, especially when converting the capsule back to a /// Rust data structure. +
    #[must_use] pub fn data_to_pycapsule(py: Python, data: Data) -> PyObject { let capsule = PyCapsule::new(py, data, None).expect("Error creating `PyCapsule`"); capsule.into_py(py) @@ -144,7 +148,9 @@

    Files

    /// Incorrect usage can lead to memory corruption or undefined behavior. #[pyfunction] pub fn drop_cvec_pycapsule(capsule: &PyAny) { - let capsule: &PyCapsule = capsule.downcast().expect("Error on downcast to capsule"); + let capsule: &PyCapsule = capsule + .downcast() + .expect("Error on downcast to `&PyCapsule`"); let cvec: &CVec = unsafe { &*(capsule.pointer() as *const CVec) }; let data: Vec<Data> = unsafe { Vec::from_raw_parts(cvec.ptr.cast::<Data>(), cvec.len, cvec.cap) }; diff --git a/nightly/core/src/nautilus_model/python/data/order.rs.html b/nightly/core/src/nautilus_model/python/data/order.rs.html index 3081863c9452..3e728de94994 100644 --- a/nightly/core/src/nautilus_model/python/data/order.rs.html +++ b/nightly/core/src/nautilus_model/python/data/order.rs.html @@ -1,4 +1,4 @@ -order.rs - source Python::with_gil(|py| { let dict_string = book_order.py_as_dict(py).unwrap().to_string(); let expected_string = - r#"{'side': 'BUY', 'price': '100.00', 'size': '10', 'order_id': 123456}"#; + r"{'side': 'BUY', 'price': '100.00', 'size': '10', 'order_id': 123456}"; assert_eq!(dict_string, expected_string); }); } diff --git a/nightly/core/src/nautilus_model/python/data/quote.rs.html b/nightly/core/src/nautilus_model/python/data/quote.rs.html index 465eed49187f..59c04a735804 100644 --- a/nightly/core/src/nautilus_model/python/data/quote.rs.html +++ b/nightly/core/src/nautilus_model/python/data/quote.rs.html @@ -1,4 +1,4 @@ -quote.rs - source 383 384 385 -386
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -418,6 +417,7 @@ 

    Files

    types::{PyDict, PyLong, PyString, PyTuple}, }; +use super::data_to_pycapsule; use crate::{ data::{quote::QuoteTick, Data}, enums::PriceType, @@ -426,8 +426,6 @@

    Files

    types::{price::Price, quantity::Quantity}, }; -use super::data_to_pycapsule; - #[pymethods] impl QuoteTick { #[new] @@ -655,7 +653,7 @@

    Files

    ts_event: UnixNanos, ts_init: UnixNanos, ) -> PyResult<Self> { - QuoteTick::new( + Self::new( instrument_id, Price::from_raw(bid_price_raw, bid_price_prec).map_err(to_pyvalue_err)?, Price::from_raw(ask_price_raw, ask_price_prec).map_err(to_pyvalue_err)?, @@ -743,7 +741,7 @@

    Files

    Python::with_gil(|py| { let dict_string = tick.py_as_dict(py).unwrap().to_string(); - let expected_string = r#"{'type': 'QuoteTick', 'instrument_id': 'ETHUSDT-PERP.BINANCE', 'bid_price': '10000.0000', 'ask_price': '10001.0000', 'bid_size': '1.00000000', 'ask_size': '1.00000000', 'ts_event': 0, 'ts_init': 1}"#; + let expected_string = r"{'type': 'QuoteTick', 'instrument_id': 'ETHUSDT-PERP.BINANCE', 'bid_price': '10000.0000', 'ask_price': '10001.0000', 'bid_size': '1.00000000', 'ask_size': '1.00000000', 'ts_event': 0, 'ts_init': 1}"; assert_eq!(dict_string, expected_string); }); } diff --git a/nightly/core/src/nautilus_model/python/data/trade.rs.html b/nightly/core/src/nautilus_model/python/data/trade.rs.html index aff0097c63b9..6727ec1a345d 100644 --- a/nightly/core/src/nautilus_model/python/data/trade.rs.html +++ b/nightly/core/src/nautilus_model/python/data/trade.rs.html @@ -1,4 +1,4 @@ -trade.rs - source 335 336 337 -338
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -370,6 +369,7 @@ 

    Files

    types::{PyDict, PyLong, PyString, PyTuple}, }; +use super::data_to_pycapsule; use crate::{ data::{trade::TradeTick, Data}, enums::{AggressorSide, FromU8}, @@ -378,8 +378,6 @@

    Files

    types::{price::Price, quantity::Quantity}, }; -use super::data_to_pycapsule; - #[pymethods] impl TradeTick { #[new] @@ -647,7 +645,7 @@

    Files

    Python::with_gil(|py| { let dict_string = tick.py_as_dict(py).unwrap().to_string(); - let expected_string = r#"{'type': 'TradeTick', 'instrument_id': 'ETHUSDT-PERP.BINANCE', 'price': '10000.0000', 'size': '1.00000000', 'aggressor_side': 'BUYER', 'trade_id': '123456789', 'ts_event': 0, 'ts_init': 1}"#; + let expected_string = r"{'type': 'TradeTick', 'instrument_id': 'ETHUSDT-PERP.BINANCE', 'price': '10000.0000', 'size': '1.00000000', 'aggressor_side': 'BUYER', 'trade_id': '123456789', 'ts_event': 0, 'ts_init': 1}"; assert_eq!(dict_string, expected_string); }); } diff --git a/nightly/core/src/nautilus_model/python/events/account/mod.rs.html b/nightly/core/src/nautilus_model/python/events/account/mod.rs.html index cc8847b4141e..dcb184490a0c 100644 --- a/nightly/core/src/nautilus_model/python/events/account/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/events/account/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source ts_init: UnixNanos, base_currency: Option<Currency>, ) -> PyResult<Self> { - AccountState::new( + Self::new( account_id, account_type, balances, @@ -208,10 +204,8 @@

    Files

    stringify!(AccountState), self.account_id, self.account_type, - self.base_currency - .map(|base_currency | format!("{}", base_currency.code)) - .unwrap_or_else(|| "None".to_string()), self.balances.iter().map(|b| format!("{}", b)).collect::<Vec<String>>().join(","), - self.margins.iter().map(|m| format!("{}", m)).collect::<Vec<String>>().join(","), + self.base_currency.map_or_else(|| "None".to_string(), |base_currency | format!("{}", base_currency.code)), self.balances.iter().map(|b| format!("{b}")).collect::<Vec<String>>().join(","), + self.margins.iter().map(|m| format!("{m}")).collect::<Vec<String>>().join(","), self.is_reported, self.event_id, ) @@ -223,10 +217,8 @@

    Files

    stringify!(AccountState), self.account_id, self.account_type, - self.base_currency - .map(|base_currency | format!("{}", base_currency.code)) - .unwrap_or_else(|| "None".to_string()), self.balances.iter().map(|b| format!("{}", b)).collect::<Vec<String>>().join(","), - self.margins.iter().map(|m| format!("{}", m)).collect::<Vec<String>>().join(","), + self.base_currency.map_or_else(|| "None".to_string(), |base_currency | format!("{}", base_currency.code)), self.balances.iter().map(|b| format!("{b}")).collect::<Vec<String>>().join(","), + self.margins.iter().map(|m| format!("{m}")).collect::<Vec<String>>().join(","), self.is_reported, self.event_id, ) @@ -257,8 +249,8 @@

    Files

    dict.set_item("ts_init", self.ts_init.to_u64())?; match self.base_currency { Some(base_currency) => { - dict.set_item("base_currency", base_currency.code.to_string())? - } + dict.set_item("base_currency", base_currency.code.to_string())?; + } None => dict.set_item("base_currency", "None")?, } Ok(dict.into()) diff --git a/nightly/core/src/nautilus_model/python/events/mod.rs.html b/nightly/core/src/nautilus_model/python/events/mod.rs.html index 329ee00b9a87..6204862b3f3f 100644 --- a/nightly/core/src/nautilus_model/python/events/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/events/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source stringify!(OrderCancelRejected), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.reason, self.ts_event, ) diff --git a/nightly/core/src/nautilus_model/python/events/order/canceled.rs.html b/nightly/core/src/nautilus_model/python/events/order/canceled.rs.html index b4225b4d6519..54b4946727a7 100644 --- a/nightly/core/src/nautilus_model/python/events/order/canceled.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/canceled.rs.html @@ -1,4 +1,4 @@ -canceled.rs - source 124 125 126 -127 -128 -129 -130 -131 -132 -133 -134
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -212,12 +204,8 @@ 

    Files

    self.strategy_id, self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.event_id, self.ts_event, self.ts_init @@ -230,12 +218,8 @@

    Files

    stringify!(OrderCanceled), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.ts_event, ) } diff --git a/nightly/core/src/nautilus_model/python/events/order/denied.rs.html b/nightly/core/src/nautilus_model/python/events/order/denied.rs.html index db3254a6eed8..b93a10b17970 100644 --- a/nightly/core/src/nautilus_model/python/events/order/denied.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/denied.rs.html @@ -1,4 +1,4 @@ -denied.rs - source stringify!(OrderExpired), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.ts_event, ) } diff --git a/nightly/core/src/nautilus_model/python/events/order/filled.rs.html b/nightly/core/src/nautilus_model/python/events/order/filled.rs.html index 0be61de59081..313bbdec2847 100644 --- a/nightly/core/src/nautilus_model/python/events/order/filled.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/filled.rs.html @@ -1,4 +1,4 @@ -filled.rs - source self.reduce_only, self.quote_quantity, self.price - .map(|price| format!("{}", price)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |price| format!("{price}")), self.emulation_trigger - .map(|trigger| format!("{}", trigger)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |trigger| format!("{trigger}")), self.trigger_instrument_id - .map(|instrument_id| format!("{}", instrument_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |instrument_id| format!( + "{instrument_id}" + )), self.contingency_type - .map(|contingency_type| format!("{}", contingency_type)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |contingency_type| format!( + "{contingency_type}" + )), self.order_list_id - .map(|order_list_id| format!("{}", order_list_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |order_list_id| format!( + "{order_list_id}" + )), self.linked_order_ids .as_ref() - .map(|linked_order_ids| linked_order_ids + .map_or("None".to_string(), |linked_order_ids| linked_order_ids .iter() .map(ToString::to_string) .collect::<Vec<_>>() - .join(", ")) - .unwrap_or("None".to_string()), + .join(", ")), self.parent_order_id - .map(|parent_order_id| format!("{}", parent_order_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |parent_order_id| format!( + "{parent_order_id}" + )), self.exec_algorithm_id - .map(|exec_algorithm_id| format!("{}", exec_algorithm_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_algorithm_id| format!( + "{exec_algorithm_id}" + )), self.exec_algorithm_params .as_ref() - .map(|exec_algorithm_params| format!("{:?}", exec_algorithm_params)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_algorithm_params| format!( + "{exec_algorithm_params:?}" + )), self.exec_spawn_id - .map(|exec_spawn_id| format!("{}", exec_spawn_id)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |exec_spawn_id| format!( + "{exec_spawn_id}" + )), self.tags .as_ref() - .map(|tags| format!("{}", tags)) - .unwrap_or("None".to_string()), + .map_or("None".to_string(), |tags| format!("{tags}")), self.event_id, self.ts_init ) } fn __str__(&self) -> String { - format!("{}", self) + format!("{self}") } #[staticmethod] @@ -593,14 +599,14 @@

    Files

    } match self.trailing_offset { Some(trailing_offset) => { - dict.set_item("trailing_offset", trailing_offset.to_string())? - } + dict.set_item("trailing_offset", trailing_offset.to_string())?; + } None => dict.set_item("trailing_offset", py.None())?, } match self.trailing_offset_type { Some(trailing_offset_type) => { - dict.set_item("trailing_offset_type", trailing_offset_type.to_string())? - } + dict.set_item("trailing_offset_type", trailing_offset_type.to_string())?; + } None => dict.set_item("trailing_offset_type", py.None())?, } match self.expire_time { @@ -613,20 +619,20 @@

    Files

    } match self.emulation_trigger { Some(emulation_trigger) => { - dict.set_item("emulation_trigger", emulation_trigger.to_string())? - } + dict.set_item("emulation_trigger", emulation_trigger.to_string())?; + } None => dict.set_item("emulation_trigger", py.None())?, } match self.trigger_instrument_id { Some(trigger_instrument_id) => { - dict.set_item("trigger_instrument_id", trigger_instrument_id.to_string())? - } + dict.set_item("trigger_instrument_id", trigger_instrument_id.to_string())?; + } None => dict.set_item("trigger_instrument_id", py.None())?, } match self.contingency_type { Some(contingency_type) => { - dict.set_item("contingency_type", contingency_type.to_string())? - } + dict.set_item("contingency_type", contingency_type.to_string())?; + } None => dict.set_item("contingency_type", py.None())?, } match self.order_list_id { @@ -645,14 +651,14 @@

    Files

    } match self.parent_order_id { Some(parent_order_id) => { - dict.set_item("parent_order_id", parent_order_id.to_string())? - } + dict.set_item("parent_order_id", parent_order_id.to_string())?; + } None => dict.set_item("parent_order_id", py.None())?, } match self.exec_algorithm_id { Some(exec_algorithm_id) => { - dict.set_item("exec_algorithm_id", exec_algorithm_id.to_string())? - } + dict.set_item("exec_algorithm_id", exec_algorithm_id.to_string())?; + } None => dict.set_item("exec_algorithm_id", py.None())?, } match &self.exec_algorithm_params { diff --git a/nightly/core/src/nautilus_model/python/events/order/mod.rs.html b/nightly/core/src/nautilus_model/python/events/order/mod.rs.html index 91d1d6310e0e..f32b204f222e 100644 --- a/nightly/core/src/nautilus_model/python/events/order/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source self.strategy_id, self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.reason, self.event_id, self.ts_event, @@ -252,12 +240,8 @@

    Files

    stringify!(OrderModifyRejected), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.reason, self.ts_event, ) @@ -278,15 +262,15 @@

    Files

    dict.set_item("client_order_id", self.client_order_id.to_string())?; dict.set_item( "venue_order_id", - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else( + || "None".to_string(), + |venue_order_id| format!("{venue_order_id}"), + ), )?; dict.set_item( "account_id", self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + .map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), )?; dict.set_item("reason", self.reason.to_string())?; dict.set_item("event_id", self.event_id.to_string())?; diff --git a/nightly/core/src/nautilus_model/python/events/order/pending_cancel.rs.html b/nightly/core/src/nautilus_model/python/events/order/pending_cancel.rs.html index f3e2d119823f..4a285a9c9ddd 100644 --- a/nightly/core/src/nautilus_model/python/events/order/pending_cancel.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/pending_cancel.rs.html @@ -1,4 +1,4 @@ -pending_cancel.rs - source 121 122 123 -124 -125 -126 -127
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -205,9 +201,7 @@ 

    Files

    self.strategy_id, self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.event_id, self.ts_event, @@ -221,9 +215,7 @@

    Files

    stringify!(OrderPendingCancel), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.ts_event, ) diff --git a/nightly/core/src/nautilus_model/python/events/order/pending_update.rs.html b/nightly/core/src/nautilus_model/python/events/order/pending_update.rs.html index 914a0a09bf50..038db167f1e1 100644 --- a/nightly/core/src/nautilus_model/python/events/order/pending_update.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/pending_update.rs.html @@ -1,4 +1,4 @@ -pending_update.rs - source 121 122 123 -124 -125 -126 -127
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -205,9 +201,7 @@ 

    Files

    self.strategy_id, self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.event_id, self.ts_event, @@ -221,9 +215,7 @@

    Files

    stringify!(OrderPendingUpdate), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), self.account_id, self.ts_event, ) diff --git a/nightly/core/src/nautilus_model/python/events/order/rejected.rs.html b/nightly/core/src/nautilus_model/python/events/order/rejected.rs.html index 16ade02290aa..5958aa18ea16 100644 --- a/nightly/core/src/nautilus_model/python/events/order/rejected.rs.html +++ b/nightly/core/src/nautilus_model/python/events/order/rejected.rs.html @@ -1,4 +1,4 @@ -rejected.rs - source self.strategy_id, self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.quantity, - self.price - .map(|price| format!("{}", price)) - .unwrap_or_else(|| "None".to_string()), - self.trigger_price - .map(|trigger_price| format!("{}", trigger_price)) - .unwrap_or_else(|| "None".to_string()), + self.price.map_or_else(|| "None".to_string(), |price| format!("{price}")), + self.trigger_price.map_or_else(|| "None".to_string(), |trigger_price| format!("{trigger_price}")), self.event_id, self.ts_event, self.ts_init @@ -276,19 +252,11 @@

    Files

    stringify!(OrderUpdated), self.instrument_id, self.client_order_id, - self.venue_order_id - .map(|venue_order_id| format!("{}", venue_order_id)) - .unwrap_or_else(|| "None".to_string()), - self.account_id - .map(|account_id| format!("{}", account_id)) - .unwrap_or_else(|| "None".to_string()), + self.venue_order_id.map_or_else(|| "None".to_string(), |venue_order_id| format!("{venue_order_id}")), + self.account_id.map_or_else(|| "None".to_string(), |account_id| format!("{account_id}")), self.quantity, - self.price - .map(|price| format!("{}", price)) - .unwrap_or_else(|| "None".to_string()), - self.trigger_price - .map(|trigger_price| format!("{}", trigger_price)) - .unwrap_or_else(|| "None".to_string()), + self.price.map_or_else(|| "None".to_string(), |price| format!("{price}")), + self.trigger_price.map_or_else(|| "None".to_string(), |trigger_price| format!("{trigger_price}")), self.ts_event, ) } diff --git a/nightly/core/src/nautilus_model/python/identifiers/instrument_id.rs.html b/nightly/core/src/nautilus_model/python/identifiers/instrument_id.rs.html index 64149d8d1947..7356da04c289 100644 --- a/nightly/core/src/nautilus_model/python/identifiers/instrument_id.rs.html +++ b/nightly/core/src/nautilus_model/python/identifiers/instrument_id.rs.html @@ -1,4 +1,4 @@ -instrument_id.rs - source
    impl InstrumentId { #[new] fn py_new(symbol: Symbol, venue: Venue) -> PyResult<Self> { - Ok(InstrumentId::new(symbol, venue)) + Ok(Self::new(symbol, venue)) } fn __setstate__(&mut self, py: Python, state: PyObject) -> PyResult<()> { @@ -175,11 +175,11 @@

    Files

    #[staticmethod] fn _safe_constructor() -> PyResult<Self> { - Ok(InstrumentId::from_str("NULL.NULL").unwrap()) // Safe default + Ok(Self::from_str("NULL.NULL").unwrap()) // Safe default } fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> Py<PyAny> { - if let Ok(other) = other.extract::<InstrumentId>(py) { + if let Ok(other) = other.extract::<Self>(py) { match op { CompareOp::Eq => self.eq(&other).into_py(py), CompareOp::Ne => self.ne(&other).into_py(py), @@ -223,8 +223,8 @@

    Files

    #[staticmethod] #[pyo3(name = "from_str")] - fn py_from_str(value: &str) -> PyResult<InstrumentId> { - InstrumentId::from_str(value).map_err(to_pyvalue_err) +
    fn py_from_str(value: &str) -> PyResult<Self> { + Self::from_str(value).map_err(to_pyvalue_err) } #[pyo3(name = "is_synthetic")] diff --git a/nightly/core/src/nautilus_model/python/identifiers/mod.rs.html b/nightly/core/src/nautilus_model/python/identifiers/mod.rs.html index 89cf68d43f8b..31a12beff94b 100644 --- a/nightly/core/src/nautilus_model/python/identifiers/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/identifiers/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 14 15 16 +17
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -32,4 +33,5 @@ 

    Files

    // -------------------------------------------------------------------------------------------------
    pub mod instrument_id; +pub mod trade_id;
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/python/identifiers/trade_id.rs.html b/nightly/core/src/nautilus_model/python/identifiers/trade_id.rs.html new file mode 100644 index 000000000000..8e1239992c8b --- /dev/null +++ b/nightly/core/src/nautilus_model/python/identifiers/trade_id.rs.html @@ -0,0 +1,223 @@ +trade_id.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +use std::{
    +    collections::hash_map::DefaultHasher,
    +    ffi::CString,
    +    hash::{Hash, Hasher},
    +    str::FromStr,
    +};
    +
    +use nautilus_core::python::to_pyvalue_err;
    +use pyo3::{
    +    prelude::*,
    +    pyclass::CompareOp,
    +    types::{PyString, PyTuple},
    +};
    +
    +use crate::identifiers::trade_id::TradeId;
    +
    +#[pymethods]
    +impl TradeId {
    +    #[new]
    +    fn py_new(value: &str) -> PyResult<Self> {
    +        Self::new(value).map_err(to_pyvalue_err)
    +    }
    +
    +    fn __setstate__(&mut self, py: Python, state: PyObject) -> PyResult<()> {
    +        let value: (&PyString,) = state.extract(py)?;
    +        let value_str: String = value.0.extract()?;
    +
    +        // TODO: Extract this to single function
    +        let c_string = CString::new(value_str).expect("`CString` conversion failed");
    +        let bytes = c_string.as_bytes_with_nul();
    +        let mut value = [0; 65];
    +        value[..bytes.len()].copy_from_slice(bytes);
    +        self.value = value;
    +
    +        Ok(())
    +    }
    +
    +    fn __getstate__(&self, py: Python) -> PyResult<PyObject> {
    +        Ok((self.to_string(),).to_object(py))
    +    }
    +
    +    fn __reduce__(&self, py: Python) -> PyResult<PyObject> {
    +        let safe_constructor = py.get_type::<Self>().getattr("_safe_constructor")?;
    +        let state = self.__getstate__(py)?;
    +        Ok((safe_constructor, PyTuple::empty(py), state).to_object(py))
    +    }
    +
    +    #[staticmethod]
    +    fn _safe_constructor() -> PyResult<Self> {
    +        Ok(Self::from_str("NULL").unwrap()) // Safe default
    +    }
    +
    +    fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> Py<PyAny> {
    +        if let Ok(other) = other.extract::<Self>(py) {
    +            match op {
    +                CompareOp::Eq => self.eq(&other).into_py(py),
    +                CompareOp::Ne => self.ne(&other).into_py(py),
    +                _ => py.NotImplemented(),
    +            }
    +        } else {
    +            py.NotImplemented()
    +        }
    +    }
    +
    +    fn __hash__(&self) -> isize {
    +        let mut h = DefaultHasher::new();
    +        self.hash(&mut h);
    +        h.finish() as isize
    +    }
    +
    +    fn __str__(&self) -> String {
    +        self.to_string()
    +    }
    +
    +    fn __repr__(&self) -> String {
    +        format!("{}('{}')", stringify!(TradeId), self)
    +    }
    +
    +    #[getter]
    +    fn value(&self) -> String {
    +        self.to_string()
    +    }
    +
    +    #[staticmethod]
    +    #[pyo3(name = "from_str")]
    +    fn py_from_str(value: &str) -> PyResult<Self> {
    +        Self::new(value).map_err(to_pyvalue_err)
    +    }
    +}
    +
    +impl ToPyObject for TradeId {
    +    fn to_object(&self, py: Python) -> PyObject {
    +        self.into_py(py)
    +    }
    +}
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/python/instruments/crypto_future.rs.html b/nightly/core/src/nautilus_model/python/instruments/crypto_future.rs.html index dd5311b67014..5f2976502fa0 100644 --- a/nightly/core/src/nautilus_model/python/instruments/crypto_future.rs.html +++ b/nightly/core/src/nautilus_model/python/instruments/crypto_future.rs.html @@ -1,4 +1,4 @@ -crypto_future.rs - source #[pyo3(name = "bids")] fn py_bids(&self) -> Vec<Level> { - // TODO: Improve efficiency - self.bids() - .iter() - .map(|level_ref| (*level_ref).clone()) - .collect() + // Clone each `Level` to create owned levels for Python interop + // and to meet the pyo3::PyAny trait bound. + self.bids().map(|level_ref| (*level_ref).clone()).collect() } #[pyo3(name = "asks")] fn py_asks(&self) -> Vec<Level> { - // TODO: Improve efficiency - self.asks() - .iter() - .map(|level_ref| (*level_ref).clone()) - .collect() + // Clone each `Level` to create owned levels for Python interop + // and to meet the pyo3::PyAny trait bound. + self.asks().map(|level_ref| (*level_ref).clone()).collect() } #[pyo3(name = "best_bid_price")] diff --git a/nightly/core/src/nautilus_model/python/orderbook/level.rs.html b/nightly/core/src/nautilus_model/python/orderbook/level.rs.html new file mode 100644 index 000000000000..219827acda0c --- /dev/null +++ b/nightly/core/src/nautilus_model/python/orderbook/level.rs.html @@ -0,0 +1,155 @@ +level.rs - source +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +
    // -------------------------------------------------------------------------------------------------
    +//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
    +//  https://nautechsystems.io
    +//
    +//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
    +//  You may not use this file except in compliance with the License.
    +//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
    +//
    +//  Unless required by applicable law or agreed to in writing, software
    +//  distributed under the License is distributed on an "AS IS" BASIS,
    +//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +//  See the License for the specific language governing permissions and
    +//  limitations under the License.
    +// -------------------------------------------------------------------------------------------------
    +
    +use pyo3::prelude::*;
    +
    +use crate::{data::order::BookOrder, orderbook::level::Level, types::price::Price};
    +
    +#[pymethods]
    +impl Level {
    +    fn __str__(&self) -> String {
    +        // TODO: Return debug string for now
    +        format!("{self:?}")
    +    }
    +
    +    fn __repr__(&self) -> String {
    +        format!("{self:?}")
    +    }
    +
    +    #[getter]
    +    #[pyo3(name = "price")]
    +    fn py_price(&self) -> Price {
    +        self.price.value
    +    }
    +
    +    #[pyo3(name = "len")]
    +    fn py_len(&self) -> usize {
    +        self.len()
    +    }
    +
    +    #[pyo3(name = "is_empty")]
    +    fn py_is_empty(&self) -> bool {
    +        self.is_empty()
    +    }
    +
    +    #[pyo3(name = "size")]
    +    fn py_size(&self) -> f64 {
    +        self.size()
    +    }
    +
    +    #[pyo3(name = "size_raw")]
    +    fn py_size_raw(&self) -> u64 {
    +        self.size_raw()
    +    }
    +
    +    #[pyo3(name = "exposure")]
    +    fn py_exposure(&self) -> f64 {
    +        self.exposure()
    +    }
    +
    +    #[pyo3(name = "exposure_raw")]
    +    fn py_exposure_raw(&self) -> u64 {
    +        self.exposure_raw()
    +    }
    +
    +    #[pyo3(name = "first")]
    +    fn py_fist(&self) -> Option<BookOrder> {
    +        self.first().copied()
    +    }
    +
    +    #[pyo3(name = "get_orders")]
    +    fn py_get_orders(&self) -> Vec<BookOrder> {
    +        self.get_orders()
    +    }
    +}
    +
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/python/orderbook/mod.rs.html b/nightly/core/src/nautilus_model/python/orderbook/mod.rs.html index 364a16721511..036e9b1764db 100644 --- a/nightly/core/src/nautilus_model/python/orderbook/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/orderbook/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source 15 16 17 +18
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -34,4 +35,5 @@ 

    Files

    pub mod book_mbo; pub mod book_mbp; +pub mod level;
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/python/orders/market.rs.html b/nightly/core/src/nautilus_model/python/orders/market.rs.html index 2f7ca7c1d84c..e1a0ce38a300 100644 --- a/nightly/core/src/nautilus_model/python/orders/market.rs.html +++ b/nightly/core/src/nautilus_model/python/orders/market.rs.html @@ -1,4 +1,4 @@ -market.rs - source 169 170 171 -172 -173
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -195,12 +193,10 @@ 

    Files

    use rust_decimal::Decimal; use ustr::Ustr; -use crate::enums::OrderType; -use crate::identifiers::account_id::AccountId; use crate::{ - enums::{ContingencyType, OrderSide, PositionSide, TimeInForce}, + enums::{ContingencyType, OrderSide, OrderType, PositionSide, TimeInForce}, identifiers::{ - client_order_id::ClientOrderId, exec_algorithm_id::ExecAlgorithmId, + account_id::AccountId, client_order_id::ClientOrderId, exec_algorithm_id::ExecAlgorithmId, instrument_id::InstrumentId, order_list_id::OrderListId, strategy_id::StrategyId, trader_id::TraderId, }, @@ -257,7 +253,7 @@

    Files

    exec_spawn_id: Option<ClientOrderId>, tags: Option<String>, ) -> PyResult<Self> { - MarketOrder::new( + Self::new( trader_id, strategy_id, instrument_id, diff --git a/nightly/core/src/nautilus_model/python/orders/mod.rs.html b/nightly/core/src/nautilus_model/python/orders/mod.rs.html index 832532fa6a8a..6468933573e1 100644 --- a/nightly/core/src/nautilus_model/python/orders/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/orders/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use nautilus_core::python::serialization::from_dict_pyo3; -use nautilus_core::python::to_pyvalue_err; -use nautilus_core::time::UnixNanos; -use pyo3::basic::CompareOp; -use pyo3::prelude::*; -use pyo3::types::{PyDict, PyList}; +use nautilus_core::{ + python::{serialization::from_dict_pyo3, to_pyvalue_err}, + time::UnixNanos, +}; +use pyo3::{ + basic::CompareOp, + prelude::*, + types::{PyDict, PyList}, +}; use rust_decimal::prelude::ToPrimitive; -use crate::enums::{OrderSide, PositionSide}; -use crate::events::order::filled::OrderFilled; -use crate::identifiers::client_order_id::ClientOrderId; -use crate::identifiers::instrument_id::InstrumentId; -use crate::identifiers::position_id::PositionId; -use crate::identifiers::strategy_id::StrategyId; -use crate::identifiers::symbol::Symbol; -use crate::identifiers::trade_id::TradeId; -use crate::identifiers::trader_id::TraderId; -use crate::identifiers::venue::Venue; -use crate::identifiers::venue_order_id::VenueOrderId; -use crate::instruments::crypto_future::CryptoFuture; -use crate::instruments::crypto_perpetual::CryptoPerpetual; -use crate::instruments::currency_pair::CurrencyPair; -use crate::instruments::equity::Equity; -use crate::instruments::futures_contract::FuturesContract; -use crate::instruments::options_contract::OptionsContract; -use crate::position::Position; -use crate::types::currency::Currency; -use crate::types::money::Money; -use crate::types::price::Price; -use crate::types::quantity::Quantity; +use crate::{ + enums::{OrderSide, PositionSide}, + events::order::filled::OrderFilled, + identifiers::{ + client_order_id::ClientOrderId, instrument_id::InstrumentId, position_id::PositionId, + strategy_id::StrategyId, symbol::Symbol, trade_id::TradeId, trader_id::TraderId, + venue::Venue, venue_order_id::VenueOrderId, + }, + instruments::{ + crypto_future::CryptoFuture, crypto_perpetual::CryptoPerpetual, + currency_pair::CurrencyPair, equity::Equity, futures_contract::FuturesContract, + options_contract::OptionsContract, + }, + position::Position, + types::{currency::Currency, money::Money, price::Price, quantity::Quantity}, +}; #[pymethods] impl Position { diff --git a/nightly/core/src/nautilus_model/python/types/balance.rs.html b/nightly/core/src/nautilus_model/python/types/balance.rs.html index 50fb92dccaf8..514b27192054 100644 --- a/nightly/core/src/nautilus_model/python/types/balance.rs.html +++ b/nightly/core/src/nautilus_model/python/types/balance.rs.html @@ -1,4 +1,4 @@ -balance.rs - source #[staticmethod] fn _safe_constructor() -> PyResult<Self> { - Ok(Currency::AUD()) // Safe default + Ok(Self::AUD()) // Safe default } fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> Py<PyAny> { @@ -257,7 +256,7 @@

    Files

    } fn __repr__(&self) -> String { - format!("{:?}", self) + format!("{self:?}") } #[getter] @@ -293,34 +292,33 @@

    Files

    #[staticmethod] #[pyo3(name = "is_fiat")] fn py_is_fiat(code: &str) -> PyResult<bool> { - Currency::is_fiat(code).map_err(to_pyvalue_err) + Self::is_fiat(code).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "is_crypto")] fn py_is_crypto(code: &str) -> PyResult<bool> { - Currency::is_crypto(code).map_err(to_pyvalue_err) + Self::is_crypto(code).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "is_commodity_backed")] fn py_is_commodidity_backed(code: &str) -> PyResult<bool> { - Currency::is_commodity_backed(code).map_err(to_pyvalue_err) + Self::is_commodity_backed(code).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_str")] #[pyo3(signature = (value, strict = false))] - fn py_from_str(value: &str, strict: bool) -> PyResult<Currency> { - match Currency::from_str(value) { +
    fn py_from_str(value: &str, strict: bool) -> PyResult<Self> { + match Self::from_str(value) { Ok(currency) => Ok(currency), Err(e) => { if strict { Err(to_pyvalue_err(e)) } else { // SAFETY: Unwrap safe as using known values - let new_crypto = - Currency::new(value, 8, 0, value, CurrencyType::Crypto).unwrap(); +
    let new_crypto = Self::new(value, 8, 0, value, CurrencyType::Crypto).unwrap(); Ok(new_crypto) } } @@ -330,8 +328,8 @@

    Files

    #[staticmethod] #[pyo3(name = "register")] #[pyo3(signature = (currency, overwrite = false))] - fn py_register(currency: Currency, overwrite: bool) -> PyResult<()> { - Currency::register(currency, overwrite).map_err(|e| PyRuntimeError::new_err(e.to_string())) + fn py_register(currency: Self, overwrite: bool) -> PyResult<()> { + Self::register(currency, overwrite).map_err(|e| PyRuntimeError::new_err(e.to_string())) } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/python/types/mod.rs.html b/nightly/core/src/nautilus_model/python/types/mod.rs.html index 6d6ad16b1853..0509dc9dfed6 100644 --- a/nightly/core/src/nautilus_model/python/types/mod.rs.html +++ b/nightly/core/src/nautilus_model/python/types/mod.rs.html @@ -1,4 +1,4 @@ -mod.rs - source #[staticmethod] fn _safe_constructor() -> PyResult<Self> { - Ok(Money::new(0.0, Currency::AUD()).unwrap()) // Safe default + Ok(Self::new(0.0, Currency::AUD()).unwrap()) // Safe default } fn __add__(&self, other: PyObject, py: Python) -> PyResult<PyObject> { if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() + other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() + other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() + other_dec).into_py(py)) @@ -460,7 +460,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float + self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() + self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec + self.as_decimal()).into_py(py)) @@ -476,7 +476,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() - other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() - other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() - other_dec).into_py(py)) @@ -492,7 +492,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float - self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() - self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec - self.as_decimal()).into_py(py)) @@ -508,7 +508,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() * other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() * other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() * other_dec).into_py(py)) @@ -524,7 +524,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float * self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() * self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec * self.as_decimal()).into_py(py)) @@ -540,7 +540,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() / other_dec).into_py(py)) @@ -556,7 +556,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() / self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec / self.as_decimal()).into_py(py)) @@ -572,7 +572,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).floor().into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_qty.as_decimal()) .floor() .into_py(py)) @@ -590,7 +590,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).floor().into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() / self.as_decimal()) .floor() .into_py(py)) @@ -608,7 +608,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() % other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() % other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() % other_dec).into_py(py)) @@ -624,7 +624,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float % self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Money>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() % self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec % self.as_decimal()).into_py(py)) @@ -663,7 +663,7 @@

    Files

    } fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> PyResult<Py<PyAny>> { - if let Ok(other_money) = other.extract::<Money>(py) { + if let Ok(other_money) = other.extract::<Self>(py) { if self.currency != other_money.currency { return Err(PyErr::new::<PyValueError, _>( "Cannot compare `Money` with different currencies", @@ -712,20 +712,20 @@

    Files

    #[staticmethod] #[pyo3(name = "zero")] - fn py_zero(currency: Currency) -> PyResult<Money> { - Money::new(0.0, currency).map_err(to_pyvalue_err) +
    fn py_zero(currency: Currency) -> PyResult<Self> { + Self::new(0.0, currency).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_raw")] - fn py_from_raw(raw: i64, currency: Currency) -> PyResult<Money> { - Ok(Money::from_raw(raw, currency)) +
    fn py_from_raw(raw: i64, currency: Currency) -> PyResult<Self> { + Ok(Self::from_raw(raw, currency)) } #[staticmethod] #[pyo3(name = "from_str")] - fn py_from_str(value: &str) -> PyResult<Money> { - Money::from_str(value).map_err(to_pyvalue_err) +
    fn py_from_str(value: &str) -> PyResult<Self> { + Self::from_str(value).map_err(to_pyvalue_err) } #[pyo3(name = "is_zero")] diff --git a/nightly/core/src/nautilus_model/python/types/price.rs.html b/nightly/core/src/nautilus_model/python/types/price.rs.html index 0ff468600f2f..cd6469c00276 100644 --- a/nightly/core/src/nautilus_model/python/types/price.rs.html +++ b/nightly/core/src/nautilus_model/python/types/price.rs.html @@ -1,4 +1,4 @@ -price.rs - source impl Price { #[new] fn py_new(value: f64, precision: u8) -> PyResult<Self> { - Price::new(value, precision).map_err(to_pyvalue_err) + Self::new(value, precision).map_err(to_pyvalue_err) } fn __setstate__(&mut self, py: Python, state: PyObject) -> PyResult<()> { @@ -439,14 +439,14 @@

    Files

    #[staticmethod] fn _safe_constructor() -> PyResult<Self> { - Ok(Price::zero(0)) // Safe default + Ok(Self::zero(0)) // Safe default } fn __add__(&self, other: PyObject, py: Python) -> PyResult<PyObject> { if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() + other_float).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() + other_price.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() + other_dec).into_py(py)) @@ -462,7 +462,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float + self.as_f64()).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() + self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec + self.as_decimal()).into_py(py)) @@ -478,7 +478,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() - other_float).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() - other_price.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() - other_dec).into_py(py)) @@ -494,7 +494,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float - self.as_f64()).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() - self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec - self.as_decimal()).into_py(py)) @@ -510,7 +510,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() * other_float).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() * other_price.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() * other_dec).into_py(py)) @@ -526,7 +526,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float * self.as_f64()).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() * self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec * self.as_decimal()).into_py(py)) @@ -542,7 +542,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_price.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() / other_dec).into_py(py)) @@ -558,7 +558,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() / self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec / self.as_decimal()).into_py(py)) @@ -574,7 +574,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).floor().into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_price.as_decimal()) .floor() .into_py(py)) @@ -592,7 +592,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).floor().into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() / self.as_decimal()) .floor() .into_py(py)) @@ -610,7 +610,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() % other_float).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((self.as_decimal() % other_price.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() % other_dec).into_py(py)) @@ -626,7 +626,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float % self.as_f64()).into_py(py)) - } else if let Ok(other_price) = other.extract::<Price>(py) { + } else if let Ok(other_price) = other.extract::<Self>(py) { Ok((other_price.as_decimal() % self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec % self.as_decimal()).into_py(py)) @@ -665,7 +665,7 @@

    Files

    } fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> Py<PyAny> { - if let Ok(other_price) = other.extract::<Price>(py) { + if let Ok(other_price) = other.extract::<Self>(py) { match op { CompareOp::Eq => self.eq(&other_price).into_py(py), CompareOp::Ne => self.ne(&other_price).into_py(py), @@ -714,27 +714,27 @@

    Files

    #[staticmethod] #[pyo3(name = "from_raw")] - fn py_from_raw(raw: i64, precision: u8) -> PyResult<Price> { - Price::from_raw(raw, precision).map_err(to_pyvalue_err) +
    fn py_from_raw(raw: i64, precision: u8) -> PyResult<Self> { + Self::from_raw(raw, precision).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "zero")] #[pyo3(signature = (precision = 0))] - fn py_zero(precision: u8) -> PyResult<Price> { - Price::new(0.0, precision).map_err(to_pyvalue_err) +
    fn py_zero(precision: u8) -> PyResult<Self> { + Self::new(0.0, precision).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_int")] - fn py_from_int(value: u64) -> PyResult<Price> { - Price::new(value as f64, 0).map_err(to_pyvalue_err) + fn py_from_int(value: u64) -> PyResult<Self> { + Self::new(value as f64, 0).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_str")] - fn py_from_str(value: &str) -> PyResult<Price> { - Price::from_str(value).map_err(to_pyvalue_err) + fn py_from_str(value: &str) -> PyResult<Self> { + Self::from_str(value).map_err(to_pyvalue_err) } #[pyo3(name = "is_zero")] diff --git a/nightly/core/src/nautilus_model/python/types/quantity.rs.html b/nightly/core/src/nautilus_model/python/types/quantity.rs.html index 5fa3888c74a0..3d6ea584dcfe 100644 --- a/nightly/core/src/nautilus_model/python/types/quantity.rs.html +++ b/nightly/core/src/nautilus_model/python/types/quantity.rs.html @@ -1,4 +1,4 @@ -quantity.rs - source impl Quantity { #[new] fn py_new(value: f64, precision: u8) -> PyResult<Self> { - Quantity::new(value, precision).map_err(to_pyvalue_err) + Self::new(value, precision).map_err(to_pyvalue_err) } fn __setstate__(&mut self, py: Python, state: PyObject) -> PyResult<()> { @@ -439,14 +439,14 @@

    Files

    #[staticmethod] fn _safe_constructor() -> PyResult<Self> { - Ok(Quantity::zero(0)) // Safe default + Ok(Self::zero(0)) // Safe default } fn __add__(&self, other: PyObject, py: Python) -> PyResult<PyObject> { if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() + other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() + other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() + other_dec).into_py(py)) @@ -462,7 +462,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float + self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() + self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec + self.as_decimal()).into_py(py)) @@ -478,7 +478,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() - other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() - other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() - other_dec).into_py(py)) @@ -494,7 +494,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float - self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() - self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec - self.as_decimal()).into_py(py)) @@ -510,7 +510,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() * other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() * other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() * other_dec).into_py(py)) @@ -526,7 +526,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float * self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() * self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec * self.as_decimal()).into_py(py)) @@ -542,7 +542,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() / other_dec).into_py(py)) @@ -558,7 +558,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() / self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec / self.as_decimal()).into_py(py)) @@ -574,7 +574,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() / other_float).floor().into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() / other_qty.as_decimal()) .floor() .into_py(py)) @@ -592,7 +592,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float / self.as_f64()).floor().into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() / self.as_decimal()) .floor() .into_py(py)) @@ -610,7 +610,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((self.as_f64() % other_float).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((self.as_decimal() % other_qty.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((self.as_decimal() % other_dec).into_py(py)) @@ -626,7 +626,7 @@

    Files

    if other.as_ref(py).is_instance_of::<PyFloat>() { let other_float: f64 = other.extract(py)?; Ok((other_float % self.as_f64()).into_py(py)) - } else if let Ok(other_qty) = other.extract::<Quantity>(py) { + } else if let Ok(other_qty) = other.extract::<Self>(py) { Ok((other_qty.as_decimal() % self.as_decimal()).into_py(py)) } else if let Ok(other_dec) = other.extract::<Decimal>(py) { Ok((other_dec % self.as_decimal()).into_py(py)) @@ -665,7 +665,7 @@

    Files

    } fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> Py<PyAny> { - if let Ok(other_qty) = other.extract::<Quantity>(py) { + if let Ok(other_qty) = other.extract::<Self>(py) { match op { CompareOp::Eq => self.eq(&other_qty).into_py(py), CompareOp::Ne => self.ne(&other_qty).into_py(py), @@ -714,27 +714,27 @@

    Files

    #[staticmethod] #[pyo3(name = "from_raw")] - fn py_from_raw(raw: u64, precision: u8) -> PyResult<Quantity> { - Quantity::from_raw(raw, precision).map_err(to_pyvalue_err) +
    fn py_from_raw(raw: u64, precision: u8) -> PyResult<Self> { + Self::from_raw(raw, precision).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "zero")] #[pyo3(signature = (precision = 0))] - fn py_zero(precision: u8) -> PyResult<Quantity> { - Quantity::new(0.0, precision).map_err(to_pyvalue_err) + fn py_zero(precision: u8) -> PyResult<Self> { + Self::new(0.0, precision).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_int")] - fn py_from_int(value: u64) -> PyResult<Quantity> { - Quantity::new(value as f64, 0).map_err(to_pyvalue_err) + fn py_from_int(value: u64) -> PyResult<Self> { + Self::new(value as f64, 0).map_err(to_pyvalue_err) } #[staticmethod] #[pyo3(name = "from_str")] - fn py_from_str(value: &str) -> PyResult<Quantity> { - Quantity::from_str(value).map_err(to_pyvalue_err) + fn py_from_str(value: &str) -> PyResult<Self> { + Self::from_str(value).map_err(to_pyvalue_err) } #[pyo3(name = "is_zero")] diff --git a/nightly/core/src/nautilus_model/stubs.rs.html b/nightly/core/src/nautilus_model/stubs.rs.html index eb3af803c441..f70094aa7b55 100644 --- a/nightly/core/src/nautilus_model/stubs.rs.html +++ b/nightly/core/src/nautilus_model/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source 97 98 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -114,20 +195,24 @@ 

    Files

    // limitations under the License. // ------------------------------------------------------------------------------------------------- -
    use crate::enums::{LiquiditySide, OrderSide}; -use crate::instruments::currency_pair::CurrencyPair; -use crate::instruments::stubs::*; -use crate::instruments::Instrument; -use crate::orders::market::MarketOrder; -use crate::orders::stubs::{TestOrderEventStubs, TestOrderStubs}; -use crate::position::Position; -use crate::types::money::Money; -use crate::types::price::Price; -use crate::types::quantity::Quantity; -use anyhow::Result; +use anyhow::Result; use rstest::fixture; use rust_decimal::prelude::ToPrimitive; +use crate::{ + data::order::BookOrder, + enums::{LiquiditySide, OrderSide}, + identifiers::instrument_id::InstrumentId, + instruments::{currency_pair::CurrencyPair, stubs::audusd_sim, Instrument}, + orderbook::book_mbp::OrderBookMbp, + orders::{ + market::MarketOrder, + stubs::{TestOrderEventStubs, TestOrderStubs}, + }, + position::Position, + types::{money::Money, price::Price, quantity::Quantity}, +}; + /// Calculate commission for testing pub fn calculate_commission<T: Instrument>( instrument: T, @@ -198,4 +283,81 @@

    Files

    ); Position::new(audusd_sim, order_filled).unwrap() } + +#[must_use] +pub fn stub_order_book_mbp_appl_xnas() -> OrderBookMbp { + stub_order_book_mbp( + InstrumentId::from("AAPL.XNAS"), + 101.0, + 100.0, + 100.0, + 100.0, + 2, + 0.01, + 0, + 100.0, + 10, + ) +} + +#[allow(clippy::too_many_arguments)] +#[must_use] +pub fn stub_order_book_mbp( + instrument_id: InstrumentId, + top_ask_price: f64, + top_bid_price: f64, + top_ask_size: f64, + top_bid_size: f64, + price_precision: u8, + price_increment: f64, + size_precision: u8, + size_increment: f64, + num_levels: usize, +) -> OrderBookMbp { + let mut book = OrderBookMbp::new(instrument_id, false); + + // Generate bids + for i in 0..num_levels { + let price = Price::new( + price_increment.mul_add(-(i as f64), top_bid_price), + price_precision, + ) + .unwrap(); + let size = Quantity::new( + size_increment.mul_add(i as f64, top_bid_size), + size_precision, + ) + .unwrap(); + let order = BookOrder::new( + OrderSide::Buy, + price, + size, + 0, // order_id not applicable for MBP (market by price) books + ); + book.add(order, 0, 1); + } + + // Generate asks + for i in 0..num_levels { + let price = Price::new( + price_increment.mul_add(i as f64, top_ask_price), + price_precision, + ) + .unwrap(); + let size = Quantity::new( + size_increment.mul_add(i as f64, top_ask_size), + size_precision, + ) + .unwrap(); + let order = BookOrder::new( + OrderSide::Sell, + price, + size, + 0, // order_id not applicable for MBP (market by price) books + ); + book.add(order, 0, 1); + } + + book +}
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/types/balance.rs.html b/nightly/core/src/nautilus_model/types/balance.rs.html index 1ea00f9c6bd3..3bb3641b56eb 100644 --- a/nightly/core/src/nautilus_model/types/balance.rs.html +++ b/nightly/core/src/nautilus_model/types/balance.rs.html @@ -1,4 +1,4 @@ -balance.rs - source 151 152 153 -154 -155 -156
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -196,12 +193,9 @@ 

    Files

    impl AccountBalance { pub fn new(total: Money, locked: Money, free: Money) -> Result<Self> { - if total != locked + free { - panic!( - "Total balance is not equal to the sum of locked and free balances: {} != {} + {}", - total, locked, free - ); - } + assert!(total == locked + free, + "Total balance is not equal to the sum of locked and free balances: {total} != {locked} + {free}" + ); Ok(Self { currency: total.currency, total, @@ -289,11 +283,11 @@

    Files

    #[rstest] fn test_account_balance_display(account_balance_test: AccountBalance) { - let display = format!("{}", account_balance_test); + let display = format!("{account_balance_test}"); assert_eq!( "AccountBalance(total=1525000.00 USD, locked=25000.00 USD, free=1500000.00 USD)", display - ) + ); } #[rstest] @@ -305,11 +299,11 @@

    Files

    #[rstest] fn test_margin_balance_display(margin_balance_test: MarginBalance) { - let display = format!("{}", margin_balance_test); + let display = format!("{margin_balance_test}"); assert_eq!( "MarginBalance(initial=5000.00 USD, maintenance=20000.00 USD, instrument_id=BTCUSDT.COINBASE)", display - ) + ); } }
    \ No newline at end of file diff --git a/nightly/core/src/nautilus_model/types/currency.rs.html b/nightly/core/src/nautilus_model/types/currency.rs.html index 59a4ad9848c2..2b6de54ebef4 100644 --- a/nightly/core/src/nautilus_model/types/currency.rs.html +++ b/nightly/core/src/nautilus_model/types/currency.rs.html @@ -1,4 +1,4 @@ -currency.rs - source }) } - pub fn register(currency: Currency, overwrite: bool) -> Result<()> { + pub fn register(currency: Self, overwrite: bool) -> Result<()> { let mut map = CURRENCY_MAP.lock().map_err(|e| anyhow!(e.to_string()))?; if !overwrite && map.contains_key(currency.code.as_str()) { @@ -284,17 +284,17 @@

    Files

    } pub fn is_fiat(code: &str) -> Result<bool> { - let currency = Currency::from_str(code)?; + let currency = Self::from_str(code)?; Ok(currency.currency_type == CurrencyType::Fiat) } pub fn is_crypto(code: &str) -> Result<bool> { - let currency = Currency::from_str(code)?; + let currency = Self::from_str(code)?; Ok(currency.currency_type == CurrencyType::Crypto) } pub fn is_commodity_backed(code: &str) -> Result<bool> { - let currency = Currency::from_str(code)?; + let currency = Self::from_str(code)?; Ok(currency.currency_type == CurrencyType::CommodityBacked) } } @@ -346,7 +346,7 @@

    Files

    D: serde::Deserializer<'de>, { let currency_str: &str = Deserialize::deserialize(deserializer)?; - Currency::from_str(currency_str).map_err(serde::de::Error::custom) + Self::from_str(currency_str).map_err(serde::de::Error::custom) } } diff --git a/nightly/core/src/nautilus_model/types/fixed.rs.html b/nightly/core/src/nautilus_model/types/fixed.rs.html index 6c1efc6499bd..683cac7b66e1 100644 --- a/nightly/core/src/nautilus_model/types/fixed.rs.html +++ b/nightly/core/src/nautilus_model/types/fixed.rs.html @@ -1,4 +1,4 @@ -fixed.rs - source // Ensure we have both the amount and currency if parts.len() != 2 { return Err(format!( - "Invalid input format: '{}'. Expected '<amount> <currency>'", - input - )); + "Invalid input format: '{input}'. Expected '<amount> <currency>'" + )); } // Parse amount @@ -702,7 +700,7 @@

    Files

    let currency = Currency::from_str(currency_str) .map_err(|_| serde::de::Error::custom("Invalid currency"))?; - Ok(Money::new(amount, currency).unwrap()) // TODO: Properly handle the error + Ok(Self::new(amount, currency).unwrap()) // TODO: Properly handle the error } } diff --git a/nightly/core/src/nautilus_model/types/price.rs.html b/nightly/core/src/nautilus_model/types/price.rs.html index ded141ec8a47..c7c84f2e599e 100644 --- a/nightly/core/src/nautilus_model/types/price.rs.html +++ b/nightly/core/src/nautilus_model/types/price.rs.html @@ -1,4 +1,4 @@ -price.rs - source 503 504 505 +506 +507 +508 +509 +510
    // -------------------------------------------------------------------------------------------------
     //  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
     //  https://nautechsystems.io
    @@ -611,8 +616,8 @@ 

    Files

    #[must_use] pub fn as_decimal(&self) -> Decimal { // Scale down the raw value to match the precision - let rescaled_raw = self.raw / i64::pow(10, (FIXED_PRECISION - self.precision) as u32); - Decimal::from_i128_with_scale(rescaled_raw as i128, self.precision as u32) +
    let rescaled_raw = self.raw / i64::pow(10, u32::from(FIXED_PRECISION - self.precision)); + Decimal::from_i128_with_scale(i128::from(rescaled_raw), u32::from(self.precision)) } #[must_use] @@ -654,7 +659,7 @@

    Files

    impl Hash for Price { fn hash<H: Hasher>(&self, state: &mut H) { - self.raw.hash(state) + self.raw.hash(state); } } @@ -790,7 +795,7 @@

    Files

    D: Deserializer<'de>, { let price_str: &str = Deserialize::deserialize(_deserializer)?; - let price: Price = price_str.into(); + let price: Self = price_str.into(); Ok(price) } } @@ -853,7 +858,12 @@

    Files

    assert_eq!(price.to_string(), "0.00812000"); assert!(!price.is_zero()); assert_eq!(price.as_decimal(), dec!(0.00812000)); - assert!(approx_eq!(f64, price.as_f64(), 0.00812, epsilon = 0.000001)); + assert!(approx_eq!( + f64, + price.as_f64(), + 0.00812, + epsilon = 0.000_001 + )); } #[rstest] @@ -967,7 +977,7 @@

    Files

    let price1 = Price::new(1.000, 3).unwrap(); let price2 = Price::new(1.011, 3).unwrap(); let price3 = price1 + price2; - assert_eq!(price3.raw, 2_011_000_000) + assert_eq!(price3.raw, 2_011_000_000); } #[rstest] @@ -982,14 +992,14 @@

    Files

    fn test_add_assign() { let mut price = Price::new(1.000, 3).unwrap(); price += Price::new(1.011, 3).unwrap(); - assert_eq!(price.raw, 2_011_000_000) + assert_eq!(price.raw, 2_011_000_000); } #[rstest] fn test_sub_assign() { let mut price = Price::new(1.000, 3).unwrap(); price -= Price::new(0.011, 3).unwrap(); - assert_eq!(price.raw, 989_000_000) + assert_eq!(price.raw, 989_000_000); } #[rstest] @@ -997,7 +1007,7 @@

    Files

    let price1 = Price::new(1.000, 3).unwrap(); let price2 = Price::new(1.011, 3).unwrap(); let result = price1 * price2.into(); - assert!(approx_eq!(f64, result, 1.011, epsilon = 0.000001)); + assert!(approx_eq!(f64, result, 1.011, epsilon = 0.000_001)); } #[rstest] diff --git a/nightly/core/src/nautilus_model/types/quantity.rs.html b/nightly/core/src/nautilus_model/types/quantity.rs.html index 3929f4db6d92..881d9f9dd500 100644 --- a/nightly/core/src/nautilus_model/types/quantity.rs.html +++ b/nightly/core/src/nautilus_model/types/quantity.rs.html @@ -1,4 +1,4 @@ -quantity.rs - source #[must_use] pub fn zero(precision: u8) -> Self { check_fixed_precision(precision).unwrap(); - Quantity::new(0.0, precision).unwrap() + Self::new(0.0, precision).unwrap() } #[must_use] @@ -592,8 +592,8 @@

    Files

    #[must_use] pub fn as_decimal(&self) -> Decimal { // Scale down the raw value to match the precision - let rescaled_raw = self.raw / u64::pow(10, (FIXED_PRECISION - self.precision) as u32); - Decimal::from_i128_with_scale(rescaled_raw as i128, self.precision as u32) +
    let rescaled_raw = self.raw / u64::pow(10, u32::from(FIXED_PRECISION - self.precision)); + Decimal::from_i128_with_scale(i128::from(rescaled_raw), u32::from(self.precision)) } #[must_use] @@ -641,7 +641,7 @@

    Files

    impl Hash for Quantity { fn hash<H: Hasher>(&self, state: &mut H) { - self.raw.hash(state) + self.raw.hash(state); } } @@ -781,7 +781,7 @@

    Files

    D: Deserializer<'de>, { let qty_str: &str = Deserialize::deserialize(_deserializer)?; - let qty: Quantity = qty_str.into(); + let qty: Self = qty_str.into(); Ok(qty) } } @@ -845,7 +845,7 @@

    Files

    assert!(!qty.is_zero()); assert!(qty.is_positive()); assert_eq!(qty.as_decimal(), dec!(0.00812000)); - assert!(approx_eq!(f64, qty.as_f64(), 0.00812, epsilon = 0.000001)); + assert!(approx_eq!(f64, qty.as_f64(), 0.00812, epsilon = 0.000_001)); } #[rstest] @@ -875,7 +875,7 @@

    Files

    #[rstest] fn test_with_minimum_positive_value() { - let qty = Quantity::new(0.000000001, 9).unwrap(); + let qty = Quantity::new(0.000_000_001, 9).unwrap(); assert_eq!(qty.raw, 1); assert_eq!(qty.as_decimal(), dec!(0.000000001)); assert_eq!(qty.to_string(), "0.000000001"); diff --git a/nightly/core/src/nautilus_model/types/stubs.rs.html b/nightly/core/src/nautilus_model/types/stubs.rs.html index 8061c7fd25e3..1ed49b649ac6 100644 --- a/nightly/core/src/nautilus_model/types/stubs.rs.html +++ b/nightly/core/src/nautilus_model/types/stubs.rs.html @@ -1,4 +1,4 @@ -stubs.rs - source