use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum PortfolioType {
Default,
Consumer,
Intx,
#[serde(other)]
Undefined,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Portfolio {
pub name: String,
pub uuid: String,
#[serde(rename = "type")]
pub portfolio_type: PortfolioType,
#[serde(default)]
pub deleted: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PortfolioBalance {
pub value: String,
pub currency: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PortfolioBalances {
pub total_balance: PortfolioBalance,
#[serde(default)]
pub total_futures_balance: Option<PortfolioBalance>,
#[serde(default)]
pub total_cash_equivalent_balance: Option<PortfolioBalance>,
#[serde(default)]
pub total_crypto_balance: Option<PortfolioBalance>,
#[serde(default)]
pub futures_unrealized_pnl: Option<PortfolioBalance>,
#[serde(default)]
pub perp_unrealized_pnl: Option<PortfolioBalance>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct SpotPosition {
pub asset: String,
pub account_uuid: String,
#[serde(default)]
pub total_balance_fiat: f64,
#[serde(default)]
pub total_balance_crypto: f64,
#[serde(default)]
pub available_to_trade_fiat: f64,
#[serde(default)]
pub allocation: f64,
#[serde(default)]
pub cost_basis: Option<PortfolioBalance>,
#[serde(default)]
pub asset_img_url: Option<String>,
#[serde(default)]
pub is_cash: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PortfolioBreakdown {
pub portfolio: Portfolio,
#[serde(default)]
pub portfolio_balances: Option<PortfolioBalances>,
#[serde(default)]
pub spot_positions: Vec<SpotPosition>,
#[serde(default)]
pub perp_positions: Vec<serde_json::Value>,
#[serde(default)]
pub futures_positions: Vec<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ListPortfoliosResponse {
pub portfolios: Vec<Portfolio>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct GetPortfolioBreakdownResponse {
pub breakdown: PortfolioBreakdown,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PortfolioResponse {
pub portfolio: Portfolio,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct ListPortfoliosParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub portfolio_type: Option<String>,
}
impl ListPortfoliosParams {
pub fn new() -> Self {
Self::default()
}
pub fn portfolio_type(mut self, portfolio_type: impl Into<String>) -> Self {
self.portfolio_type = Some(portfolio_type.into());
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CreatePortfolioRequest {
pub name: String,
}
impl CreatePortfolioRequest {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
}
#[derive(Debug, Clone, Serialize)]
pub struct EditPortfolioRequest {
pub name: String,
}
impl EditPortfolioRequest {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
}
#[derive(Debug, Clone, Serialize)]
pub struct MoveFunds {
pub value: String,
pub currency: String,
}
impl MoveFunds {
pub fn new(value: impl Into<String>, currency: impl Into<String>) -> Self {
Self {
value: value.into(),
currency: currency.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct MoveFundsRequest {
pub funds: MoveFunds,
pub source_portfolio_uuid: String,
pub target_portfolio_uuid: String,
}
impl MoveFundsRequest {
pub fn new(
funds: MoveFunds,
source_portfolio_uuid: impl Into<String>,
target_portfolio_uuid: impl Into<String>,
) -> Self {
Self {
funds,
source_portfolio_uuid: source_portfolio_uuid.into(),
target_portfolio_uuid: target_portfolio_uuid.into(),
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct MoveFundsResponse {
pub source_portfolio_uuid: String,
pub target_portfolio_uuid: String,
}