use crate::core::sync_mode::SyncMode;
use crate::core::AccountOutcomeEntry;
use crate::core::{
HasAccountAdjustmentBalance, HasAccountAdjustmentBalanceAverageEntryPrice,
HasAccountAdjustmentBalanceLowerBound, HasAccountAdjustmentBalanceRealizedPnl,
HasAccountAdjustmentBalanceUpperBound, HasAccountAdjustmentHeld,
HasAccountAdjustmentHeldLowerBound, HasAccountAdjustmentHeldUpperBound,
HasAccountAdjustmentIncoming, HasAccountAdjustmentIncomingLowerBound,
HasAccountAdjustmentIncomingUpperBound, HasAccountId, HasBalanceAsset,
HasExecutionReportIsFinal, HasExecutionReportLastTrade, HasInstrument, HasLeavesQuantity,
HasOrderPrice, HasPreTradeLock, HasSide, HasTradeAmount,
};
use crate::marketdata::MarketDataSync;
use crate::param::{AccountId, Asset};
use crate::pretrade::holdings::HoldingsStore;
use crate::pretrade::policy::{PolicyGroupId, PolicyName};
use crate::pretrade::ConfigurablePolicy;
use crate::pretrade::PreTradePolicy;
use crate::pretrade::{PolicyPreTradeResult, PostTradeResult, PreTradeContext, Rejects};
use crate::storage::{CreateStorageFor, LockingPolicyFactory, StorageBuilder};
use crate::{AccountAdjustmentContext, Mutations};
mod adjustment;
mod execution;
mod market_data;
mod market_order_pricer;
mod pre_trade;
mod rejects;
mod rollback;
mod views;
#[cfg(test)]
mod tests;
pub use market_data::{
SpotFundsConfigError, SpotFundsMarketData, SpotFundsOverride, SpotFundsOverrideTarget,
SpotFundsPricingSource, SpotFundsSettings,
};
pub(super) type HoldingsKey = (AccountId, Asset);
pub struct SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
Sync::StorageLockingPolicyFactory: LockingPolicyFactory,
MarketDataSyncMode: MarketDataSync,
{
pub(super) holdings: <<Sync as SyncMode>::StorageLockingPolicyFactory
as crate::storage::LockingPolicyFactory>::Shared<
HoldingsStore<
<<Sync as SyncMode>::StorageLockingPolicyFactory
as crate::storage::LockingPolicyFactory>::Policy,
>,
>,
pub(super) settings: <Sync::StorageLockingPolicyFactory
as LockingPolicyFactory>::Config<SpotFundsSettings>,
pub(super) market_orders: Option<SpotFundsMarketData<MarketDataSyncMode>>,
group_id: PolicyGroupId,
}
impl<Sync, MarketDataSyncMode> SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
Sync::StorageLockingPolicyFactory: LockingPolicyFactory,
MarketDataSyncMode: MarketDataSync,
{
pub const NAME: &'static str = "SpotFundsPolicy";
pub fn new(
settings: SpotFundsSettings,
market_orders: Option<SpotFundsMarketData<MarketDataSyncMode>>,
storage_builder: &StorageBuilder<<Sync as SyncMode>::StorageLockingPolicyFactory>,
) -> Self
where
<Sync as SyncMode>::StorageLockingPolicyFactory: CreateStorageFor<(AccountId, Asset)>,
{
Self {
holdings: <<Sync as SyncMode>::StorageLockingPolicyFactory
as crate::storage::LockingPolicyFactory>::new_shared(
HoldingsStore::new(storage_builder),
),
settings: <Sync::StorageLockingPolicyFactory
as LockingPolicyFactory>::new_config(settings),
market_orders,
group_id: crate::pretrade::DEFAULT_POLICY_GROUP_ID,
}
}
pub(super) fn group_id(&self) -> PolicyGroupId {
self.group_id
}
pub fn with_policy_group_id(mut self, id: PolicyGroupId) -> Self {
self.group_id = id;
self
}
}
impl<Sync, MarketDataSyncMode> PolicyName for SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
Sync::StorageLockingPolicyFactory: LockingPolicyFactory,
MarketDataSyncMode: MarketDataSync,
{
fn policy_name(&self) -> &str {
Self::NAME
}
}
impl<Order, ExecutionReport, AccountAdjustment, Sync, MarketDataSyncMode>
PreTradePolicy<Order, ExecutionReport, AccountAdjustment, Sync>
for SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Order: HasInstrument + HasAccountId + HasSide + HasTradeAmount + HasOrderPrice,
ExecutionReport: HasInstrument
+ HasAccountId
+ HasSide
+ HasExecutionReportLastTrade
+ HasLeavesQuantity
+ HasExecutionReportIsFinal
+ HasPreTradeLock,
AccountAdjustment: HasBalanceAsset
+ HasAccountAdjustmentBalance
+ HasAccountAdjustmentBalanceAverageEntryPrice
+ HasAccountAdjustmentBalanceRealizedPnl
+ HasAccountAdjustmentBalanceLowerBound
+ HasAccountAdjustmentBalanceUpperBound
+ HasAccountAdjustmentHeld
+ HasAccountAdjustmentHeldLowerBound
+ HasAccountAdjustmentHeldUpperBound
+ HasAccountAdjustmentIncoming
+ HasAccountAdjustmentIncomingLowerBound
+ HasAccountAdjustmentIncomingUpperBound,
Sync: SyncMode,
Sync::StorageLockingPolicyFactory: LockingPolicyFactory,
MarketDataSyncMode: MarketDataSync,
<<Sync as SyncMode>::StorageLockingPolicyFactory as crate::storage::LockingPolicyFactory>::Policy: 'static,
{
fn name(&self) -> &str {
Self::NAME
}
fn policy_group_id(&self) -> PolicyGroupId {
self.group_id()
}
#[allow(private_interfaces)]
fn built_in_config_entry(
&self,
) -> Option<crate::core::ConfigEntry<<Sync as SyncMode>::StorageLockingPolicyFactory>> {
Some(crate::core::ConfigEntry::SpotFunds(
crate::pretrade::ConfigurablePolicy::settings_cell(self),
))
}
fn apply_account_adjustment(
&self,
ctx: &AccountAdjustmentContext<<Sync as SyncMode>::StorageLockingPolicyFactory>,
account_id: AccountId,
adjustment: &AccountAdjustment,
mutations: &mut Mutations,
) -> Result<Vec<AccountOutcomeEntry>, Rejects> {
self.apply_account_adjustment_impl(
Some(ctx.account_control.clone()),
account_id,
adjustment,
mutations,
)
}
fn apply_execution_report(
&self,
ctx: &crate::pretrade::PostTradeContext<
<Sync as crate::core::SyncMode>::StorageLockingPolicyFactory,
>,
report: &ExecutionReport,
) -> Option<PostTradeResult> {
self.apply_execution_report_impl(ctx, report)
}
fn perform_pre_trade_check(
&self,
ctx: &PreTradeContext<<Sync as SyncMode>::StorageLockingPolicyFactory>,
order: &Order,
mutations: &mut Mutations,
) -> Result<Option<PolicyPreTradeResult>, Rejects> {
self.perform_pre_trade_check_impl(ctx.account_control.clone(), ctx, order, mutations)
}
fn perform_pre_trade_check_dry_run(
&self,
ctx: &PreTradeContext<<Sync as SyncMode>::StorageLockingPolicyFactory>,
order: &Order,
_mutations: &mut Mutations,
) -> Result<Option<PolicyPreTradeResult>, Rejects> {
self.perform_pre_trade_check_dry_run_impl(ctx, order)
}
}
impl<Sync, MarketDataSyncMode> ConfigurablePolicy<<Sync as SyncMode>::StorageLockingPolicyFactory>
for SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
Sync::StorageLockingPolicyFactory: LockingPolicyFactory,
MarketDataSyncMode: MarketDataSync,
{
type Settings = SpotFundsSettings;
fn settings_cell(
&self,
) -> <Sync::StorageLockingPolicyFactory as LockingPolicyFactory>::Config<SpotFundsSettings>
{
self.settings.clone()
}
}