Files
api_internal/trading/zerodha_kite/models/instruments.py
T
khushalps b53ef86ef8 Squashed 'utils_v2/' content from commit 7f27356
git-subtree-dir: utils_v2
git-subtree-split: 7f273565196085feb05ee3328aa2e80d3d721fc3
2025-06-12 10:54:05 +05:30

223 lines
7.4 KiB
Python

"""
AUTHOR:
Khushal P Soonderji
DATE:
Monday, 6th Jan., 2024.
OBJECTIVE:
To provide a data model for describing the instruments supported by Zerodha Kite.
REFERENCES:
N/A
DOWNLOADS:
N/A
"""
# *****************************************************************************************************************
# ***** ****
# *** IMPORT ***
# ***** ****
# *****************************************************************************************************************
# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")
# For system-level activities:
import io
# For making data behaviour_models:
from pydantic import BaseModel, Field, field_validator, model_validator, AwareDatetime
from typing import Optional, Literal, Union, Dict, List, Any
# Related to Google:
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
# 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
import dateparser
# For working with tabulated data:
import pandas as pd
# To make API calls:
import httpx
# *****************************************************************************************************************
# ***** ****
# *** MACROS / ONE-TIME INIT ***
# ***** ****
# *****************************************************************************************************************
# --- Nothing Yet
# *****************************************************************************************************************
# ***** ****
# *** VARIABLES ***
# ***** ****
# *****************************************************************************************************************
# --- Nothing Yet
# *****************************************************************************************************************
# ***** ****
# *** FUNCTIONS ***
# ***** ****
# *****************************************************************************************************************
class ZerodhaKiteInstrument(BaseModel):
instrumentToken: int = Field(
description = "The token by which Zerodha recognizes this instrument.",
frozen = True,
alias = "instrument_token"
)
exchangeToken: int | str = Field(
description = "The way the exchange recognizes this instrument.",
frozen = True,
alias = "exchange_token"
)
symbol: str | None = Field(
description = "The trading symbol pf this instrument.",
frozen = True,
alias = "tradingsymbol"
)
name: str | None = Field(
description = "The name of the company (for stocks), or the trading symbol (for derivatives).",
frozen = True,
alias = "name"
)
ltp: float | int = Field(
description = "The last price at which this instrument was traded.",
frozen = True,
alias = "last_price"
)
expiry: str | None = Field(
description = "The expiry date (if derivative).",
frozen = True,
alias = "expiry"
)
strike: float | int | None = Field(
description = "The strike price (if option).",
frozen = True,
alias = "strike"
)
tickSize: float | int = Field(
description = "The minimum value by which the price must move to change.",
frozen = True,
alias = "tick_size"
)
lotSize: float | int = Field(
description = "The minimum trading qty. (if derivative).",
frozen = True,
alias = "lot_size"
)
segment: str = Field(
description = "The segment that the instrument belongs to.",
frozen = True,
alias = "segment"
)
instrumentType: str = Field(
description = "the subtype of the 'segment'.",
frozen = True,
alias = "instrument_type"
)
exchange: str = Field(
description = "The exchange on which this instrument is traded.",
alias = "exchange"
)
# ┏┓ ┏•
# ┃ ┏┓┏┓╋┓┏┓
# ┗┛┗┛┛┗┛┗┗┫
# ┛
class Config:
extra = "ignore"
populate_by_name = True
# ┓┏ ┓• ┓ •
# ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓
# ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗
pass
# ┏┓ •
# ┃┃┏┓┏┓┏┓┏┓┏┓╋┓┏┓┏
# ┣┛┛ ┗┛┣┛┗ ┛ ┗┗┗ ┛
# ┛
pass
# ┏┓ ┏┓
# ┃ ┓┏┏╋┏┓┏┳┓ ┣ ┓┏┏┓┏┏
# ┗┛┗┻┛┗┗┛┛┗┗ ┻ ┗┻┛┗┗┛
def __str__(self):
return f"{self.exchange}:{self.symbol}"
def __repr__(self):
return str(self)
@staticmethod
def from_api_data(api_data: bytes | io.BytesIO | pd.DataFrame | List[dict] | dict) -> "ZerodhaKiteInstrument":
# Convert the input to a list of dicts:
if isinstance(api_data, bytes): api_data = io.BytesIO(api_data)
if isinstance(api_data, io.BytesIO): api_data = pd.read_csv(api_data)
if isinstance(api_data, pd.DataFrame):
api_data = api_data.map(lambda x: None if pd.isna(x) else x)
api_data = api_data.to_dict(orient = "records")
if isinstance(api_data, dict): api_data = [api_data]
# Model the records and return the values:
modelled_instruments = [ZerodhaKiteInstrument(**instrument) for instrument in api_data]
return modelled_instruments
# *****************************************************************************************************************
# ***** ****
# *** MAIN PROGRAM ***
# ***** ****
# *****************************************************************************************************************
if __name__ == "__main__":
pass