Package: kitetrader
Kite-TraderUnofficial Python Client for Zerodha Kite with built-in request throttling so you never exceed Kite's API limits.If you :heart: my work so far, please :star2: this repo.InstallationSupports Python version >= 3.8pip install kitetraderUsagefromkitetraderimportKite# Using with statement (context manager)withKite()askite:kite.profile()# user profilekite.holdings()# user portfolio# orkite=Kite()kite.profile()kite.holdings()# close the requests sessionkite.close()LoginOn first initialization, Kite will check for user authentication. If no arguments are provided, the script prompts for username, password, and OTP.On successful login, anenctokenis generated and stored in a cookie file.If the cookie file exists on subsequent initialization, theenctokenis reused, eliminating the need to log in again.This method will logout all Kite web (browser) sessions. (You can continue to use the Kite Mobile App).You can reuse the browserenctoken, passing it to Kite. This way, you can use Kite without getting logged out.kite = Kite(enctoken='<token string>')To access the browserenctoken, login to kite.zerodha.com and pressSHIFT + F9to open the Storage inspector (On Firefox). You will find the info under cookies.Passing credentials file pathCredentials file is no longer supported. Storing plain text passwords in a file, could be unsafe.NOTESStartingv1.1.0, kitetrader no longer exits on error. You must handle the error appropriately.Methods may raise the following errors:ARuntimeErroris raised if too many (>15) 429 reponse codes are returned.ATimeoutErroris raised if server takes too long to respond.AConnectionErroris raised if:Session expiredBad request or invalid parametersInternal server errorAvailable MethodsAlmost all methods defined on the Kite Connect 3 api have been covered except Webhooks and Websocket streaming. You can refer to theKite Connect Docsfor more information# Userkite.profile()kite.margins(segment=kite.MARGIN_EQUITY)# or kite.MARGIN_COMMODITY# Portfoliokite.holdings()# long-term holdingskite.positions()# short-term positionskite.auctions()# list all auctions# Orderskite.orders()# list all orders for the daykite.order_history('171229000724687')# order_idkite.trades()# list all executed tradeskite.order_trades('171229000724687')# order_idkite.place_order(kite.VARIETY_REGULAR,kite.EXCHANGE_NSE,'INFY',kite.TRANSACTION_TYPE_BUY,1,kite.PRODUCT_NRML,kite.ORDER_TYPE_MARKET)# Buy INFY at market price from NSE with product type NRMLkite.modify_order(kite.VARIETY_REGULAR,'171229000724687',5)# order_id with quantity 5kite.cancel_order(kite.VARIETY_REGULAR,'171229000724687')Market Quotes# Get the full market quotes - ohlc, OI, bid/ask, etcinstruments=['NSE:INFY','NSE:RELIANCE','NSE:HDFCBANK','NSE:TCS']kite.quote(instruments)# accepts list or a single string# orkite.quote('NSE:INFY')kite.ohlc(instruments)# Get OHLCV and last traded pricekite.ltp(instruments)# Last traded price of all instrumentsHistorical Candle datafromkitetraderimportKitefrompandasimportDataFrame,to_datetimefromdatetimeimportdatetime'''An example to load historical candle data in Pandas DataFrame'''defto_dataframe(data,oi=False):'''Returns a pandas DataFrame with Date as Index'''columns=['Date','Open','High','Low','Close','Volume']ifoi:columns.append('OpenInterest')df=DataFrame(data,columns=columns)df['Date']=to_datetime(df['Date'])returndf.set_index('Date')from_dt=datetime(2023,10,4,9,15)to_dt=datetime(2023,10,4,15,30)instrument_token='8979970'# banknifty oct futureswithKite()askite:data=kite.historical_data(instrument_token,from_dt,to_dt,interval='15minute',oi=True)df=to_dataframe(data,oi=True)print(df.head())df.to_csv(kite.base_dir/'BANKNIFTY_OCT_FUT.csv')InstrumentsInstruments method will return a dump of all tradable instruments. This is a large file of 7MB with 10k+ records. Only download what is required by specifying the exchange.fromkitetraderimportKitefromioimportBytesIOfrompandasimportread_csv'''Example to load and save instruments to csv file. '''withKite()askite:# returns data in binary formatdata=kite.instruments(kite.EXCHANGE_NSE)# Save as csv file using pathlib.path(kite.base_dir/'instruments.csv').write_bytes(data)# or using file open with write binarywithopen('instruments.csv','wb')asf:f.write(data)# To convert data to Pandas DataFramedf=read_csv(BytesIO(data),index_col='tradingsymbol')# or load the saved csv file as DataFramedf=read_csv('instruments.csv',index_col='tradingsymbol')# to query an instrument tokeninstrument_token=df.loc['INFY','instrument_token']ConstantsThe below contants have been defined on the Kite class. You can use them as arguments to the various methods.# ExchangesEXCHANGE_NSE="NSE"EXCHANGE_BSE="BSE"EXCHANGE_NFO="NFO"EXCHANGE_CDS="CDS"EXCHANGE_BFO="BFO"EXCHANGE_MCX="MCX"EXCHANGE_BCD="BCD"# ProductsPRODUCT_MIS="MIS"PRODUCT_CNC="CNC"PRODUCT_NRML="NRML"PRODUCT_CO="CO"# Order typesORDER_TYPE_MARKET="MARKET"ORDER_TYPE_LIMIT="LIMIT"ORDER_TYPE_SLM="SL-M"ORDER_TYPE_SL="SL"# VaritiesVARIETY_REGULAR="regular"VARIETY_CO="co"VARIETY_AMO="amo"VARIETY_ICEBERG="iceberg"VARIETY_AUCTION="auction"# Transaction typeTRANSACTION_TYPE_BUY="BUY"TRANSACTION_TYPE_SELL="SELL"# ValidityVALIDITY_DAY="DAY"VALIDITY_IOC="IOC"VALIDITY_TTL="TTL"# Position TypePOSITION_TYPE_DAY="day"POSITION_TYPE_OVERNIGHT="overnight"# Margins segmentsMARGIN_EQUITY="equity"MARGIN_COMMODITY="commodity"# GTT order typeGTT_TYPE_OCO="two-leg"GTT_TYPE_SINGLE="single"API limits and ThrottlingWhen making large number of requests its essential to respect theAPI limits set by Zerodha.The Throttle class ensures you do not exceed these limits. Its takes two arguments - a dictionary configuration and an integer max_penalty_count.Themax_penalty_countis maximum number of 429 HTTP error code, allowed to be returned during a session. Exceeding this limit will result in a runtime error.The configuration is a dictionary which defines the limits for each endpoint. Here,RPSstands for Requests Per Second andRPMstands for Requests Per Minute. Limits are set for each end point.throttle_config={'quote':{'rps':1,},'historical':{'rps':3,},'order':{'rps':8,'rpm':180,},'default':{'rps':8,}}max_penalty_count=15th=Throttle(throttle_config,max_penalty_count)Class and Method signatureclassKite(builtins.object)|Kite(enctoken:Optional[str]=None)||UnofficialimplementationofZerodhaKiteapi||Methodsdefinedhere:||__init__(self,enctoken:Optional[str]=None)|Initializeself.Seehelp(type(self))foraccuratesignature.||auctions(self)|Retrievethelistofauctionsthatarecurrentlybeingheld||cancel_order(self,variety,order_id)|Cancelanorder.||close(self)|ClosetheRequestssession||historical_data(self,instrument_token:str,from_dt:Union[datetime.datetime,str],to_dt:Union[datetime.datetime,str],interval:str,continuous=False,oi=False)|returnhistoricalcandlerecordsforagiveninstrument.||holdings(self)|Returnthelistoflongtermequityholdings||instruments(self,exchange:Optional[str]=None)|returnaCSVdumpofalltradableinstruments||ltp(self,instruments:Union[str,collections.abc.Collection])|Returnsthelasttradedprice||margins(self,segment:Optional[str]=None)|Returnsfunds,cash,andmargininformationfortheuser|forequityandcommoditysegments||modify_order(self,variety,order_id,quantity=None,price=None,order_type=None,trigger_price=None,validity=None,disclosed_quantity=None)|Modifyanopenorder.||ohlc(self,instruments:Union[str,collections.abc.Collection])|Returnsohlcandlasttradedprice||order_history(self,order_id)|Gethistoryofindividualorders||order_trades(self,order_id)|Getthethetradesgeneratedbyanorder||orders(self)|Getlistofallordersfortheday||place_order(self,variety,exchange,tradingsymbol,transaction_type,quantity,product,order_type,price=None,validity=None,validity_ttl=None,disclosed_quantity=None,trigger_price=None,iceberg_legs=None,iceberg_quantity=None,auction_number=None,tag=None)|Placeanorderofaparticularvariety||positions(self)|Retrievethelistofshorttermpositions||profile(self)|Retrievetheuserprofile||quote(self,instruments:Union[str,collections.abc.Collection])|Returnthefullmarketquotes-ohlc,OI,bid/asketc||trades(self)|Getthelistofallexecutedtradesfortheday||Dataandotherattributesdefinedhere:||EXCHANGE_BCD='BCD'||EXCHANGE_BFO='BFO'||EXCHANGE_BSE='BSE'||EXCHANGE_CDS='CDS'||EXCHANGE_MCX='MCX'||EXCHANGE_NFO='NFO'||EXCHANGE_NSE='NSE'||GTT_TYPE_OCO='two-leg'||GTT_TYPE_SINGLE='single'||MARGIN_COMMODITY='commodity'||MARGIN_EQUITY='equity'||ORDER_TYPE_LIMIT='LIMIT'||ORDER_TYPE_MARKET='MARKET'||ORDER_TYPE_SL='SL'||ORDER_TYPE_SLM='SL-M'||POSITION_TYPE_DAY='day'||POSITION_TYPE_OVERNIGHT='overnight'||PRODUCT_CNC='CNC'||PRODUCT_CO='CO'||PRODUCT_MIS='MIS'||PRODUCT_NRML='NRML'||TRANSACTION_TYPE_BUY='BUY'||TRANSACTION_TYPE_SELL='SELL'||VALIDITY_DAY='DAY'||VALIDITY_IOC='IOC'||VALIDITY_TTL='TTL'||VARIETY_AMO='amo'||VARIETY_AUCTION='auction'||VARIETY_CO='co'||VARIETY_ICEBERG='iceberg'||VARIETY_REGULAR='regular'|