nautilus_model/accounts/
stubs.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use rstest::fixture;
17
18use crate::{
19    accounts::{AccountAny, base::Account, cash::CashAccount, margin::MarginAccount},
20    enums::{AccountType, LiquiditySide},
21    events::account::{state::AccountState, stubs::*},
22    identifiers::stubs::{account_id, uuid4},
23    instruments::InstrumentAny,
24    types::{AccountBalance, Currency, Money, Price, Quantity},
25};
26
27impl Default for CashAccount {
28    /// Creates a new default [`CashAccount`] instance.
29    fn default() -> Self {
30        // million dollar account
31        let init_event = AccountState::new(
32            account_id(),
33            AccountType::Cash,
34            vec![AccountBalance::new(
35                Money::from("1000000 USD"),
36                Money::from("0 USD"),
37                Money::from("1000000 USD"),
38            )],
39            vec![],
40            true,
41            uuid4(),
42            0.into(),
43            0.into(),
44            Some(Currency::USD()),
45        );
46        Self::new(init_event, false)
47    }
48}
49
50impl Default for AccountAny {
51    /// Creates a new default [`AccountAny`] instance.
52    fn default() -> Self {
53        AccountAny::Cash(CashAccount::default())
54    }
55}
56
57#[fixture]
58pub fn margin_account(margin_account_state: AccountState) -> MarginAccount {
59    MarginAccount::new(margin_account_state, true)
60}
61
62#[fixture]
63pub fn cash_account(cash_account_state: AccountState) -> CashAccount {
64    CashAccount::new(cash_account_state, true)
65}
66
67#[fixture]
68pub fn cash_account_million_usd(cash_account_state_million_usd: AccountState) -> CashAccount {
69    CashAccount::new(cash_account_state_million_usd, true)
70}
71
72#[fixture]
73pub fn cash_account_multi(cash_account_state_multi: AccountState) -> CashAccount {
74    CashAccount::new(cash_account_state_multi, true)
75}
76
77#[must_use]
78pub fn calculate_commission(
79    instrument: InstrumentAny,
80    quantity: Quantity,
81    price: Price,
82    currency: Option<Currency>,
83) -> Money {
84    let account_state = if Some(Currency::USDT()) == currency {
85        cash_account_state_million_usdt()
86    } else {
87        cash_account_state_million_usd("1000000 USD", "0 USD", "1000000 USD")
88    };
89    let account = cash_account_million_usd(account_state);
90    account
91        .calculate_commission(instrument, quantity, price, LiquiditySide::Taker, None)
92        .unwrap()
93}