use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
use pyo3::{prelude::*, types::PyDict};
use crate::{
accounts::{Account, BettingAccount, CashAccount, MarginAccount, WalletAccount},
events::AccountState,
};
#[pyfunction]
#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.model")]
#[pyo3(signature = (events, calculate_account_state, allow_borrowing = false))]
pub fn cash_account_from_account_events(
events: Vec<Bound<'_, PyDict>>,
calculate_account_state: bool,
allow_borrowing: bool,
) -> PyResult<CashAccount> {
let account_events = events
.into_iter()
.map(|obj| AccountState::py_from_dict(&obj))
.collect::<PyResult<Vec<AccountState>>>()?;
if account_events.is_empty() {
return Err(to_pyvalue_err("No account events"));
}
let init_event = account_events[0].clone();
let mut cash_account = CashAccount::new(init_event, calculate_account_state, allow_borrowing);
for event in account_events.iter().skip(1) {
cash_account
.apply(event.clone())
.map_err(to_pyruntime_err)?;
}
Ok(cash_account)
}
#[pyfunction]
#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.model")]
pub fn betting_account_from_account_events(
events: Vec<Bound<'_, PyDict>>,
calculate_account_state: bool,
) -> PyResult<BettingAccount> {
let account_events = events
.into_iter()
.map(|obj| AccountState::py_from_dict(&obj))
.collect::<PyResult<Vec<AccountState>>>()?;
if account_events.is_empty() {
return Err(to_pyvalue_err("No account events"));
}
let init_event = account_events[0].clone();
let mut betting_account = BettingAccount::new(init_event, calculate_account_state);
for event in account_events.iter().skip(1) {
betting_account
.apply(event.clone())
.map_err(to_pyruntime_err)?;
}
Ok(betting_account)
}
#[pyfunction]
#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.model")]
#[pyo3(signature = (events, calculate_account_state))]
pub fn wallet_account_from_account_events(
events: Vec<Bound<'_, PyDict>>,
calculate_account_state: bool,
) -> PyResult<WalletAccount> {
let account_events = events
.into_iter()
.map(|obj| AccountState::py_from_dict(&obj))
.collect::<PyResult<Vec<AccountState>>>()?;
let Some((init_event, remaining_events)) = account_events.split_first() else {
return Err(to_pyvalue_err("No account events"));
};
let mut wallet_account =
WalletAccount::new_checked(init_event.clone(), calculate_account_state)
.map_err(to_pyvalue_err)?;
for event in remaining_events {
wallet_account
.apply(event.clone())
.map_err(to_pyruntime_err)?;
}
Ok(wallet_account)
}
#[pyfunction]
#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.model")]
pub fn margin_account_from_account_events(
events: Vec<Bound<'_, PyDict>>,
calculate_account_state: bool,
) -> PyResult<MarginAccount> {
let account_events = events
.into_iter()
.map(|obj| AccountState::py_from_dict(&obj))
.collect::<PyResult<Vec<AccountState>>>()?;
if account_events.is_empty() {
return Err(to_pyvalue_err("No account events"));
}
let init_event = account_events[0].clone();
let mut margin_account = MarginAccount::new(init_event, calculate_account_state);
for event in account_events.iter().skip(1) {
margin_account
.apply(event.clone())
.map_err(to_pyruntime_err)?;
}
Ok(margin_account)
}