/*
 * Websocket Subscription Schemas
 *
 * Schema definitions Websocket API subscriptions for Thalex exchange.
 *
 * The version of the OpenAPI document: 1.0.0
 *
 * Generated by: https://openapi-generator.tech
 */

use crate::models;
use serde::{Deserialize, Serialize};

#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Levels {
    /// Individually identifies this bot instance. You can use it to cancel this specific one.
    #[serde(rename = "bot_id")]
    pub bot_id: String,
    #[serde(rename = "status")]
    pub status: Status,
    /// The reason why the bot stopped executing.
    #[serde(rename = "stop_reason", skip_serializing_if = "Option::is_none")]
    pub stop_reason: Option<StopReason>,
    /// equal to \"levels\"
    #[serde(rename = "strategy")]
    pub strategy: String,
    /// Name of the instrument the bot instance is trading.
    #[serde(rename = "instrument_name")]
    pub instrument_name: String,
    /// The default price levels the bot will be bidding at. See [the bot strategies section](#tag/bot_strategies) for more explanation.
    #[serde(rename = "bids")]
    pub bids: Vec<rust_decimal::Decimal>,
    /// The default price levels the bot will be quoting on the ask side. See [the bot strategies section](#tag/bot_strategies) for more explanation.
    #[serde(rename = "asks")]
    pub asks: Vec<rust_decimal::Decimal>,
    /// The price level to exit positions at.
    #[serde(rename = "target_mean_price")]
    pub target_mean_price: rust_decimal::Decimal,
    /// The default size of to quote on one level. See [the bot strategies section](#tag/bot_strategies) for more explanation.
    #[serde(rename = "step_size")]
    pub step_size: rust_decimal::Decimal,
    /// Will be used as a reference to compare the subaccount's portfolio position in the instrument that this bot is trading to. See [the bot strategies section](#tag/bot_strategies) for more explanation.
    #[serde(rename = "base_position")]
    pub base_position: rust_decimal::Decimal,
    /// If the mark price of the instrument this bot is trading goes above `upside_exit_price`, the bot cancels the maker orders, aggressively trades into `base_position`, and then stops executing.
    #[serde(rename = "upside_exit_price", skip_serializing_if = "Option::is_none")]
    pub upside_exit_price: Option<rust_decimal::Decimal>,
    /// If the mark price of the instrument this bot is trading goes below `downside_exit_price`, the bot cancels the maker orders, aggressively trades into `base_position`, and then stops executing.
    #[serde(
        rename = "downside_exit_price",
        skip_serializing_if = "Option::is_none"
    )]
    pub downside_exit_price: Option<rust_decimal::Decimal>,
    /// Maximum slippage per trade when exiting any position, expressed as % of the traded instruments mark price.
    #[serde(rename = "max_slippage", skip_serializing_if = "Option::is_none")]
    pub max_slippage: Option<rust_decimal::Decimal>,
    /// Timestamp when the bot stops executing, cancelling its orders and leaving all positions of the subaccount intact.
    #[serde(rename = "end_time")]
    pub end_time: rust_decimal::Decimal,
    /// Timestamp indicating when the bot was created.
    #[serde(rename = "start_time")]
    pub start_time: rust_decimal::Decimal,
    /// Timestamp indicating when the bot stopped working due to specified `stop_reason`.
    #[serde(rename = "stop_time", skip_serializing_if = "Option::is_none")]
    pub stop_time: Option<rust_decimal::Decimal>,
    /// A label that the bot will add to all orders for easy identification.
    #[serde(rename = "label", skip_serializing_if = "Option::is_none")]
    pub label: Option<String>,
    /// Realized P&L made by this bot since the start.
    #[serde(rename = "realized_pnl")]
    pub realized_pnl: rust_decimal::Decimal,
    /// Trade fees by this bot.
    #[serde(rename = "fee")]
    pub fee: rust_decimal::Decimal,
    /// Average entry price of the position (if any).
    #[serde(rename = "average_price", skip_serializing_if = "Option::is_none")]
    pub average_price: Option<rust_decimal::Decimal>,
    /// Position size (if any).
    #[serde(rename = "position_size", skip_serializing_if = "Option::is_none")]
    pub position_size: Option<rust_decimal::Decimal>,
    /// Mark price of the bot instrument at the moment the bot was stopped.
    #[serde(rename = "mark_price_at_stop", skip_serializing_if = "Option::is_none")]
    pub mark_price_at_stop: Option<rust_decimal::Decimal>,
}

impl Levels {
    pub fn new(
        bot_id: String,
        status: Status,
        strategy: String,
        instrument_name: String,
        bids: Vec<rust_decimal::Decimal>,
        asks: Vec<rust_decimal::Decimal>,
        target_mean_price: rust_decimal::Decimal,
        step_size: rust_decimal::Decimal,
        base_position: rust_decimal::Decimal,
        end_time: rust_decimal::Decimal,
        start_time: rust_decimal::Decimal,
        realized_pnl: rust_decimal::Decimal,
        fee: rust_decimal::Decimal,
    ) -> Levels {
        Levels {
            bot_id,
            status,
            stop_reason: None,
            strategy,
            instrument_name,
            bids,
            asks,
            target_mean_price,
            step_size,
            base_position,
            upside_exit_price: None,
            downside_exit_price: None,
            max_slippage: None,
            end_time,
            start_time,
            stop_time: None,
            label: None,
            realized_pnl,
            fee,
            average_price: None,
            position_size: None,
            mark_price_at_stop: None,
        }
    }
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Status {
    #[serde(rename = "active")]
    Active,
    #[serde(rename = "stopped")]
    Stopped,
}

impl Default for Status {
    fn default() -> Status {
        Self::Active
    }
}
/// The reason why the bot stopped executing.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum StopReason {
    #[serde(rename = "client_cancel")]
    ClientCancel,
    #[serde(rename = "client_bulk_cancel")]
    ClientBulkCancel,
    #[serde(rename = "end_time")]
    EndTime,
    #[serde(rename = "instrument_deactivated")]
    InstrumentDeactivated,
    #[serde(rename = "margin_breach")]
    MarginBreach,
    #[serde(rename = "admin_cancel")]
    AdminCancel,
    #[serde(rename = "conflict")]
    Conflict,
    #[serde(rename = "strategy")]
    Strategy,
    #[serde(rename = "self_trade_prevention")]
    SelfTradePrevention,
}

impl Default for StopReason {
    fn default() -> StopReason {
        Self::ClientCancel
    }
}
