use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderBookQuery {
pub id: Option<String>,
pub order_tag: Option<String>,
}
impl OrderBookQuery {
pub fn by_id(id: impl Into<String>) -> Self {
Self {
id: Some(id.into()),
order_tag: None,
}
}
pub fn by_order_tag(order_tag: impl Into<String>) -> Self {
Self {
id: None,
order_tag: Some(order_tag.into()),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaceOrderRequest {
pub symbol: String,
pub qty: i64,
#[serde(rename = "type")]
pub order_type: i64,
pub side: i64,
#[serde(rename = "productType")]
pub product_type: String,
#[serde(rename = "limitPrice")]
pub limit_price: f64,
#[serde(rename = "stopPrice")]
pub stop_price: f64,
pub validity: String,
#[serde(rename = "disclosedQty")]
pub disclosed_qty: i64,
#[serde(rename = "offlineOrder")]
pub offline_order: bool,
#[serde(default, rename = "stopLoss", skip_serializing_if = "Option::is_none")]
pub stop_loss: Option<f64>,
#[serde(
default,
rename = "takeProfit",
skip_serializing_if = "Option::is_none"
)]
pub take_profit: Option<f64>,
#[serde(default, rename = "orderTag", skip_serializing_if = "Option::is_none")]
pub order_tag: Option<String>,
#[serde(
default,
rename = "isSliceOrder",
skip_serializing_if = "Option::is_none"
)]
pub is_slice_order: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ModifyOrderRequest {
pub id: String,
#[serde(rename = "type")]
pub order_type: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub qty: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub side: Option<i64>,
#[serde(
default,
rename = "limitPrice",
skip_serializing_if = "Option::is_none"
)]
pub limit_price: Option<f64>,
#[serde(default, rename = "stopPrice", skip_serializing_if = "Option::is_none")]
pub stop_price: Option<f64>,
#[serde(
default,
rename = "disclosedQty",
skip_serializing_if = "Option::is_none"
)]
pub disclosed_qty: Option<i64>,
#[serde(
default,
rename = "offlineOrder",
skip_serializing_if = "Option::is_none"
)]
pub offline_order: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CancelOrderRequest {
pub id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderActionResponse {
pub code: i64,
pub s: String,
pub message: String,
#[serde(deserialize_with = "deserialize_string_from_value")]
pub id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AsyncOrderActionResponse {
pub code: i64,
pub s: String,
pub message: String,
pub id_fyers: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AsyncMultiOrderActionResponse {
pub code: i64,
pub s: String,
pub message: String,
pub data: Vec<MultiOrderItemResponse<AsyncOrderActionResponse>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MultiOrderActionResponse {
pub code: i64,
pub s: String,
pub message: String,
pub data: Vec<MultiOrderItemResponse<OrderActionResponse>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MultiOrderItemResponse<T> {
#[serde(rename = "statusCode")]
pub status_code: i64,
pub body: T,
#[serde(rename = "statusDescription")]
pub status_description: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MultiLegOrderRequest {
#[serde(default, rename = "orderTag", skip_serializing_if = "Option::is_none")]
pub order_tag: Option<String>,
#[serde(rename = "productType")]
pub product_type: String,
#[serde(rename = "offlineOrder")]
pub offline_order: bool,
#[serde(rename = "orderType")]
pub order_type: String,
pub validity: String,
pub legs: MultiLegOrderLegs,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MultiLegOrderLegs {
pub leg1: MultiLegOrderLeg,
pub leg2: MultiLegOrderLeg,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub leg3: Option<MultiLegOrderLeg>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MultiLegOrderLeg {
pub symbol: String,
pub qty: i64,
pub side: i64,
#[serde(rename = "type")]
pub order_type: i64,
#[serde(rename = "limitPrice")]
pub limit_price: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OrderBookResponse {
pub code: i64,
pub s: String,
pub message: String,
#[serde(rename = "orderBook")]
pub order_book: Vec<OrderBookEntry>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OrderBookEntry {
#[serde(rename = "clientId")]
pub client_id: String,
pub id: String,
#[serde(default)]
pub id_fyers: Option<String>,
#[serde(rename = "exchOrdId")]
pub exch_ord_id: String,
pub qty: i64,
#[serde(rename = "remainingQuantity")]
pub remaining_quantity: i64,
#[serde(rename = "filledQty")]
pub filled_qty: i64,
#[serde(rename = "discloseQty")]
pub disclose_qty: i64,
#[serde(rename = "limitPrice")]
pub limit_price: f64,
#[serde(rename = "stopPrice")]
pub stop_price: f64,
#[serde(rename = "tradedPrice")]
pub traded_price: f64,
#[serde(rename = "type")]
pub order_type: i64,
#[serde(rename = "fyToken")]
pub fy_token: String,
pub exchange: i64,
pub segment: i64,
pub symbol: String,
pub instrument: i64,
pub message: String,
#[serde(rename = "offlineOrder")]
pub offline_order: bool,
#[serde(rename = "orderDateTime")]
pub order_date_time: String,
#[serde(default, rename = "parentId")]
pub parent_id: Option<String>,
#[serde(rename = "orderValidity")]
pub order_validity: String,
pub pan: String,
#[serde(rename = "productType")]
pub product_type: String,
pub side: i64,
pub status: i64,
pub source: String,
pub ex_sym: String,
pub description: String,
pub ch: f64,
pub chp: f64,
pub lp: f64,
#[serde(rename = "slNo")]
pub sl_no: i64,
#[serde(rename = "dqQtyRem")]
pub dq_qty_rem: i64,
#[serde(rename = "orderNumStatus")]
pub order_num_status: String,
#[serde(rename = "disclosedQty")]
pub disclosed_qty: i64,
#[serde(rename = "orderTag")]
pub order_tag: String,
#[serde(rename = "takeProfit")]
pub take_profit: f64,
#[serde(rename = "stopLoss")]
pub stop_loss: f64,
}
fn deserialize_string_from_value<'de, D>(deserializer: D) -> std::result::Result<String, D::Error>
where
D: Deserializer<'de>,
{
match Value::deserialize(deserializer)? {
Value::String(value) => Ok(value),
Value::Number(value) => Ok(value.to_string()),
other => Err(serde::de::Error::custom(format!(
"expected string or number, got {other}"
))),
}
}