c7259cfe9f
git-subtree-dir: utils_v2 git-subtree-split: ddefb8fec3a72ccff2cd85e75bd6687d0067c37b
359 lines
11 KiB
Python
359 lines
11 KiB
Python
"""
|
|
|
|
AUTHOR:
|
|
|
|
Khushal P Soonderji
|
|
|
|
DATE:
|
|
|
|
Tuesday, 7th jan., 2024.
|
|
|
|
OBJECTIVE:
|
|
|
|
To provide a structure to represent trading tick updates from Zerodha.
|
|
|
|
REFERENCES:
|
|
|
|
N/A
|
|
|
|
DOWNLOADS:
|
|
|
|
N/A
|
|
|
|
"""
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** IMPORT ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# To make sibling directories accessible for imports:
|
|
import sys
|
|
sys.path.append(".")
|
|
sys.path.append("..")
|
|
|
|
# For making data behaviour_models:
|
|
from pydantic import BaseModel, Field, field_validator, PastDatetime, model_validator, AwareDatetime, computed_field
|
|
from typing import Optional, Literal, Union, List
|
|
|
|
# My utils:
|
|
from utils_v2.string import json
|
|
from utils_v2.string import regex
|
|
from utils_v2.date_time import date_time
|
|
|
|
# To work with date and time:
|
|
import datetime
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** MACROS / ONE-TIME INIT ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# --- Nothing Yet
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** VARIABLES ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# --- Nothing Yet
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** FUNCTIONS ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
class OneZerodhaKiteMarketDepth(BaseModel):
|
|
|
|
price: float = Field(
|
|
description = "a price at which trader(s) are willing to trade this instrument",
|
|
frozen = True,
|
|
alias = "price"
|
|
)
|
|
|
|
qty: int = Field(
|
|
description = "the no. of shares available at the above price",
|
|
frozen = True,
|
|
alias = "quantity"
|
|
)
|
|
|
|
orders: int = Field(
|
|
description = "how many orders have contributed to the above quantity",
|
|
frozen = True,
|
|
alias = "orders"
|
|
)
|
|
|
|
@computed_field
|
|
def lqdty(self) -> float:
|
|
return self.price * self.qty
|
|
|
|
# ┏┓ ┏•
|
|
# ┃ ┏┓┏┓╋┓┏┓
|
|
# ┗┛┗┛┛┗┛┗┗┫
|
|
# ┛
|
|
|
|
class Config:
|
|
extra = "forbid"
|
|
|
|
|
|
# ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
class ZerodhaKiteMarketDepth(BaseModel):
|
|
|
|
buy: List[OneZerodhaKiteMarketDepth] = Field(
|
|
description = "the buying side market depth",
|
|
frozen = True
|
|
)
|
|
|
|
sell: List[OneZerodhaKiteMarketDepth] = Field(
|
|
description = "the selling side market depth",
|
|
frozen = True
|
|
)
|
|
|
|
# ┏┓ ┏•
|
|
# ┃ ┏┓┏┓╋┓┏┓
|
|
# ┗┛┗┛┛┗┛┗┗┫
|
|
# ┛
|
|
|
|
class Config:
|
|
extra = "forbid"
|
|
|
|
# ┓┏ ┓• ┓ •
|
|
# ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓
|
|
# ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗
|
|
|
|
@field_validator("buy", mode = "after")
|
|
def sort_buying_depth(cls, value):
|
|
value.sort(key = lambda x: x.price, reverse = True)
|
|
return value
|
|
|
|
@field_validator("sell", mode = "after")
|
|
def sort_selling_depth(cls, value):
|
|
value.sort(key = lambda x: x.price, reverse = False)
|
|
return value
|
|
|
|
|
|
# ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
class ZerodhaKiteTick(BaseModel):
|
|
|
|
tickMode: Literal["ltp", "quote", "full"] = Field(
|
|
description = "The mode in which this tick was received.",
|
|
frozen = True
|
|
)
|
|
|
|
instrumentToken: int = Field(
|
|
description = "The code by which Zerodha identifies this instrument.",
|
|
frozen = True
|
|
)
|
|
|
|
tradeable: bool = Field(
|
|
description = "Whether, or not, this instrument is tradeable.",
|
|
frozen = True
|
|
)
|
|
|
|
exchange: str = Field(
|
|
description = "The exchange on which this instrument gets traded.",
|
|
frozen = True
|
|
)
|
|
|
|
prevClose: float | None = Field(
|
|
description = "The previous session's closing price for this instrument.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
ltp: float = Field(
|
|
description = "The last price of this instrument.",
|
|
frozen = True
|
|
)
|
|
|
|
qty: int | None = Field(
|
|
description = "How many units were traded in this tick.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
chg: float | None = Field(
|
|
description = "The absolute change since the previous close.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
pChg: float | None = Field(
|
|
description = "The percentage change since the previous close.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
o: float | None = Field(
|
|
description = "This session's open price.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
h: float | None = Field(
|
|
description = "This session's highest price.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
l: float | None = Field(
|
|
description = "This session's lowest price.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
c: float | None = Field(
|
|
description = "This session's close price; typically the same as the LTP.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
totVol: int | None = Field(
|
|
description = "The total volume of this instrument that has been traded in this session.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
vwap: float | None = Field(
|
|
description = "The volume weighted average price in this session.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
totBuyQty: int | None = Field(
|
|
description = "The total open buy qty. on the exchange for this symbol.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
totSellQty: int | None = Field(
|
|
description = "The total open sell qty. on the exchange for this symbol.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
oi: int | None = Field(
|
|
description = "The total open interest of this instrument (if derivative).",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
oiDayHigh: int | None = Field(
|
|
description = "This session's highest open interest of this instrument (if derivative).",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
oiDayLow: int | None = Field(
|
|
description = "This session's lowest open interest of this instrument (if derivative).",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
tradeTs: AwareDatetime | None = Field(
|
|
description = "The last trade time (UTC) of this instrument.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
tradeTz: str | None = Field(
|
|
description = "The timezone (pytz compatible) in which the last trade time should be interpreted.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True,
|
|
examples = ["UTC", "Asia/Kolkata"]
|
|
)
|
|
|
|
exchgTs: AwareDatetime | None = Field(
|
|
description = "The time (UTC) at which this update was received from the exchange.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
exchgTz: str | None = Field(
|
|
description = "The timezone (pytz compatible) in which the exchange's time should be interpreted.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True,
|
|
examples = ["UTC", "Asia/Kolkata"]
|
|
)
|
|
|
|
depth: ZerodhaKiteMarketDepth | None = Field(
|
|
description = "The market depth data for this instrument at the time of this tick.",
|
|
frozen = True,
|
|
default = None,
|
|
validate_default = True
|
|
)
|
|
|
|
# ┏┓ ┏┓ ┓ ┏┓• ┓ ┓
|
|
# ┣┫┓┏╋┏┓━━┃ ┏┓┏┳┓┏┓┓┏╋┏┓┏┫ ┣ ┓┏┓┃┏┫┏
|
|
# ┛┗┗┻┗┗┛ ┗┛┗┛┛┗┗┣┛┗┻┗┗ ┗┻ ┻ ┗┗ ┗┗┻┛
|
|
# ┛
|
|
|
|
pass
|
|
|
|
# ┏┓ ┏•
|
|
# ┃ ┏┓┏┓╋┓┏┓
|
|
# ┗┛┗┛┛┗┛┗┗┫
|
|
# ┛
|
|
|
|
class Config:
|
|
extra = "forbid"
|
|
|
|
# ┏┓ ┏┓
|
|
# ┃ ┓┏┏╋┏┓┏┳┓ ┣ ┓┏┏┓┏┏
|
|
# ┗┛┗┻┛┗┗┛┛┗┗ ┻ ┗┻┛┗┗┛
|
|
|
|
pass
|
|
|
|
# ┓┏ ┓• ┓ •
|
|
# ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓
|
|
# ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗
|
|
|
|
pass
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** MAIN PROGRAM ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
pass
|