Kite Usage

Aio-Trader contains the aio_trader.kite package and aio_trader.utils module.

aio_trader.kite package comes with 2 modules - Kite and KiteFeed.

You can import them as

from aio_trader.kite import Kite, KiteFeed
from aio_trader import utils

kite.Kite

Kite provides methods for managing orders, accessing profiles, and getting historical market data and quotes.

With async context manager

async with Kite() as kite:
  await kite.authorize()

Without context manager

kite = Kite()
await kite.authorize()

# Close session
kite.close()

Kite Login and authorization

All arguments are optional. It defaults to Kite web login if no arguments are provided. You will be required to enter your credentials via terminal user input.

Once authorization is complete, the token is set. You can access them as

  • kite.enctoken - For Kite web login

  • kite.access_token - For KiteConnect login

These can be stored or saved and reused on the next run. You can pass the token to the Kite class during initialization.

For Kite web login, Kite.authorize takes the following optional parameters:

  • user_id: Kite Web user-id

  • password: Kite Web login password

  • twofa: string or callable function that returns OTP

To generate OTP you can use a package like pyotp, just pass totp.now to twofa argument.

# Kite Web Login
async with Kite(enctoken=enctoken) as kite:
  await kite.authorize(
      user_id=user_id,
      password=pwd,
      twofa="123124",
  )

For KiteConnect login, Kite.authorize takes the following optional parameters:

  • request_token : KiteConnect request_token

  • api_key: KiteConnect API key

  • secret: KiteConnect API secret

# KiteConnect login
async with Kite(access_token=access_token) as kite:
  await kite.authorize(
      request_token=request_token,
      api_key=api_key,
      secret=secret,
  )

kite.KiteFeed

KiteFeed provides a WebSocket connection to receive real-time market quotes and order updates.

With async context manager

async with KiteFeed(user_id=user_id, enctoken=enctoken) as kws:

  # No code executes after this line
  await Kws.connect()

Without context manager

It is important to close WebSocket connections and Client Session before exiting the application.

In the below example, kws.close will not be executed. However, it is shown here for completeness.

kws = KiteFeed(api_key=api_key, access_token=access_token)

# No code executes after this line
await kws.connect()

# Close Unsubscribe instruments, close WebSocket connection, and session
kws.close()

KiteFeed requires the following optional arguments

For Kite Web:

  • user_id: Kite Web user-id

  • enctoken: enctoken obtained from Kite Web Login

For KiteConnect:

  • api_key: Kite Web user-id

  • access_token : access_token obtained from KiteConnect login

Event handlers

The KiteFeed class accepts the below optional handlers. You may define them as per your needs.

def on_tick(tick: List, binary=False):
  # To receive market quotes
  pass

def on_connect(kws: KiteFeed):
  # Notify when WebSockets connection established
  pass

def on_order_update(data: dict):
  # Notify on order updates
  pass

def on_error(kws: KiteFeed, reason: str):
  # Notify on error
  pass

def on_message(msg: str):
  # Other text messages or alerts
  pass

with KiteFeed(user_id=user_id, enctoken=enctoken) as kws:
  kws.on_tick = on_tick
  kws.on_connect = on_connect
  kws.on_order_update = on_order_update
  kws.on_error = on_error

  await kws.connect()

Get Raw Binary data

If you wish to receive the raw binary data from the WebSocket connection, you can set the parse_data argument of KiteFeed to False.

kws = KiteFeed(parse_data=False)

You may want to use a custom binary parser or forward the data to the browser and parse it client-side. It avoids the overhead of serializing and deserializing the data.

Authorization Flow

  1. On running Kite.authorize, it first checks if enctoken or access_token was set during initialization.
    • If yes, the authorization headers are updated, and the class is ready to make API requests.

  2. If request_token and secret are provided, proceed with KiteConnect login. Once the access_token is received, set the authorization headers.

  3. For Kite Web login, enctoken is stored in cookies. Check if the cookie file exists and has not expired. If yes, load the enctoken and update headers.

  4. If no cookie file exists or has expired, proceed with Kite Web login. Once the enctoken is received:
    • Set the cookie expiry for the end of the day.

    • Save the cookie to file

    • Update the authorization headers with enctoken

Session Sharing

Both Kite and KiteFeed store an instance of aiohttp.ClientSession. A session allows sharing of cookies and maintains a connection pool, to be reused between HTTP requests. It speeds up requests by not having to reestablish secure connections.

You can access the session object with Kite.session and KiteFeed.session.

A Kite session, can be shared with KiteFeed by passing it during initialization.

kite = Kite()

kws = KiteFeed(session=kite.session)

Logging

Aio-Trader uses the Python logging module to output logs. You can define your logger and pass the instance to Kite and KiteFeed.

kite = Kite(logger=logger)

# Share the same logger instance
kws = KiteFeed(logger=kite.log)

Alternatively, the aio_trader.utils module provides a helper function configure_default_logger. It takes an optional name argument, which defaults to aio_trader and returns a configured logger instance of that name.

from aio_trader.utils import configure_default_logger
import logging

# Returns a logging.Logger instance of name aio_trader
logger = configure_default_logger('aio_trader')

# Default level is INFO
logger.setLevel(logging.WARNING)

kite = Kite(logger=logger)