use barter_execution::client::mock::MockExecutionConfig;
use barter_instrument::{
Underlying,
asset::{Asset, name::AssetNameExchange},
exchange::ExchangeId,
instrument::{
Instrument,
kind::{
InstrumentKind, future::FutureContract, option::OptionContract,
perpetual::PerpetualContract,
},
name::{InstrumentNameExchange, InstrumentNameInternal},
quote::InstrumentQuoteAsset,
spec::{InstrumentSpec, InstrumentSpecQuantity, OrderQuantityUnits},
},
};
use derive_more::From;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
pub struct SystemConfig {
pub instruments: Vec<InstrumentConfig>,
pub executions: Vec<ExecutionConfig>,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
pub struct InstrumentConfig {
pub exchange: ExchangeId,
pub name_exchange: InstrumentNameExchange,
pub underlying: Underlying<AssetNameExchange>,
pub quote: InstrumentQuoteAsset,
pub kind: InstrumentKind<AssetNameExchange>,
pub spec: Option<InstrumentSpec<AssetNameExchange>>,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, From)]
#[serde(untagged)]
pub enum ExecutionConfig {
Mock(MockExecutionConfig),
}
impl From<InstrumentConfig> for Instrument<ExchangeId, Asset> {
fn from(value: InstrumentConfig) -> Self {
Self {
exchange: value.exchange,
name_internal: InstrumentNameInternal::new_from_exchange_underlying(
value.exchange,
&value.underlying.base,
&value.underlying.quote,
),
name_exchange: value.name_exchange,
underlying: Underlying {
base: Asset::new_from_exchange(value.underlying.base),
quote: Asset::new_from_exchange(value.underlying.quote),
},
quote: value.quote,
kind: match value.kind {
InstrumentKind::Spot => InstrumentKind::Spot,
InstrumentKind::Perpetual(contract) => {
InstrumentKind::Perpetual(PerpetualContract {
contract_size: contract.contract_size,
settlement_asset: Asset::new_from_exchange(contract.settlement_asset),
})
}
InstrumentKind::Future(contract) => InstrumentKind::Future(FutureContract {
contract_size: contract.contract_size,
settlement_asset: Asset::new_from_exchange(contract.settlement_asset),
expiry: contract.expiry,
}),
InstrumentKind::Option(contract) => InstrumentKind::Option(OptionContract {
contract_size: contract.contract_size,
settlement_asset: Asset::new_from_exchange(contract.settlement_asset),
kind: contract.kind,
exercise: contract.exercise,
expiry: contract.expiry,
strike: contract.strike,
}),
},
spec: value.spec.map(|spec| InstrumentSpec {
price: spec.price,
quantity: InstrumentSpecQuantity {
unit: match spec.quantity.unit {
OrderQuantityUnits::Asset(asset) => {
OrderQuantityUnits::Asset(Asset::new_from_exchange(asset))
}
OrderQuantityUnits::Contract => OrderQuantityUnits::Contract,
OrderQuantityUnits::Quote => OrderQuantityUnits::Quote,
},
min: spec.quantity.min,
increment: spec.quantity.increment,
},
notional: spec.notional,
}),
}
}
}