use crate::core::sync_mode::SyncMode;
use crate::core::AccountOutcomeEntry;
use crate::core::{
HasAccountAdjustmentBalance, HasAccountAdjustmentBalanceLowerBound,
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::PreTradePolicy;
use crate::pretrade::DEFAULT_POLICY_GROUP_ID;
use crate::pretrade::{PolicyPreTradeResult, PostTradeResult, PreTradeContext, Rejects};
use crate::storage::{CreateStorageFor, 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,
};
pub(super) type HoldingsKey = (AccountId, Asset);
pub struct SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
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) market_orders: Option<SpotFundsMarketData<MarketDataSyncMode>>,
pub(super) group_id: PolicyGroupId,
}
impl<Sync, MarketDataSyncMode> SpotFundsPolicy<Sync, MarketDataSyncMode>
where
Sync: SyncMode,
MarketDataSyncMode: MarketDataSync,
{
pub const NAME: &'static str = "SpotFundsPolicy";
pub fn new(
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),
),
market_orders,
group_id: DEFAULT_POLICY_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,
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
+ HasAccountAdjustmentBalanceLowerBound
+ HasAccountAdjustmentBalanceUpperBound
+ HasAccountAdjustmentHeld
+ HasAccountAdjustmentHeldLowerBound
+ HasAccountAdjustmentHeldUpperBound
+ HasAccountAdjustmentIncoming
+ HasAccountAdjustmentIncomingLowerBound
+ HasAccountAdjustmentIncomingUpperBound,
Sync: SyncMode,
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
}
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(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)
}
}