kiteticker-async-manager 0.4.0

High-performance async WebSocket client for Kite Connect API with multi-connection support, dynamic subscription management, and optimized data processing.
Documentation
use chrono::{DateTime, NaiveDateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::{serde_as, DefaultOnNull};

use crate::Exchange;

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
#[serde(rename_all = "UPPERCASE")]
pub enum OrderTransactionType {
  Buy,
  Sell,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
pub enum OrderValidity {
  DAY,
  IOC,
  TTL,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
#[serde(rename_all = "UPPERCASE")]
pub enum OrderStatus {
  COMPLETE,
  REJECTED,
  CANCELLED,
  UPDATE,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct TimeStamp(i64);

impl From<String> for TimeStamp {
  fn from(value: String) -> Self {
    let secs = NaiveDateTime::parse_from_str(&value, "%Y-%m-%d %H:%M:%S")
      .unwrap()
      .and_utc()
      .timestamp();
    TimeStamp(secs)
  }
}

impl From<TimeStamp> for String {
  fn from(value: TimeStamp) -> Self {
    DateTime::<Utc>::from_timestamp(value.0, 0)
      .unwrap_or_default()
      .naive_utc()
      .format("%Y-%m-%d %H:%M:%S")
      .to_string()
  }
}

#[serde_with::serde_as]
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
pub struct Order {
  pub order_id: String,

  #[serde_as(as = "DefaultOnNull")]
  pub exchange_order_id: Option<String>,

  #[serde_as(as = "DefaultOnNull")]
  pub parent_order_id: Option<String>,

  pub placed_by: String,
  pub app_id: u64,

  pub status: OrderStatus,

  #[serde_as(as = "DefaultOnNull")]
  pub status_message: Option<String>,

  #[serde_as(as = "DefaultOnNull")]
  pub status_message_raw: Option<String>,

  pub tradingsymbol: String,
  pub instrument_token: u32,

  #[serde_as(as = "serde_with::FromInto<String>")]
  pub exchange: Exchange,

  pub order_type: String,
  pub transaction_type: OrderTransactionType,

  pub validity: OrderValidity,
  pub variety: String,
  pub product: Option<String>,

  #[serde(default)]
  pub average_price: f64,

  #[serde(default)]
  pub disclosed_quantity: f64,

  pub price: f64,
  pub quantity: u64,
  pub filled_quantity: u64,

  #[serde(default)]
  pub unfilled_quantity: u64,

  #[serde(default)]
  pub pending_quantity: u64,

  #[serde(default)]
  pub cancelled_quantity: u64,

  #[serde(default)]
  pub trigger_price: f64,

  pub user_id: String,

  #[serde_as(as = "serde_with::FromInto<String>")]
  pub order_timestamp: TimeStamp,
  #[serde_as(as = "serde_with::FromInto<String>")]
  pub exchange_timestamp: TimeStamp,
  #[serde_as(as = "serde_with::FromInto<String>")]
  pub exchange_update_timestamp: TimeStamp,

  pub checksum: String,
  #[serde(default)]
  pub meta: Option<serde_json::Map<String, Value>>,

  #[serde_as(as = "DefaultOnNull")]
  #[serde(default)]
  pub tag: Option<String>,
}