""" 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