Sunday, December 10, 2023

Easy methods to Fetch Realtime Inventory Market Quotes utilizing SmartAPI Python Library


SmartAPI, offered by Angel Broking, provides a sturdy resolution for merchants and builders seeking to combine real-time inventory market knowledge into their purposes. Using WebSocket know-how, SmartAPI ensures seamless and environment friendly streaming of dwell monetary knowledge.

Smart API Websocket

Step1 : Set up the Python Library

use the next pip instructions to put in the python library

pip set up smartapi-python
pip set up websocket-client
pip set up pyotp
pip set up pytz
pip set up logzero

Step 2: Generate the Token

1) Go to smartapi.angelbroking.com/enable-totp
2) Enter your Angel One consumer id and buying and selling terminal password or MPIN
3) Enter OTP despatched to the Registered electronic mail & cellular. As soon as OTP is entered, you will notice a QR code on the display screen and a token quantity on the display screen.

Step 3 : Generate the API Key

1)Login to SmartAPI Developer Portal
2)Click on on Create an App button
3)Choose the Market Feeds APIs possibility and enter the app title, enter the redirect url and postback url as proven beneath ,enter your Angel Shopper ID, and click on the Create App button

4)Copy the API Key and hold it seperately.

Step 4 : Getting ready the config.py file

apikey = '9bmmTPjj'
username = 'R464999'
pwd = '1111'
token = '4YYB6RA2LXXXEKEZZ3BS7SJ3Y'

The config.py file is a Python configuration script containing delicate info required for authenticating and connecting to a SmartAPI

Step 5 : Authentication

First to get authenticated one ought to learn to Autogenerate TOTP for Angel Broking

Right here is the next block of code which lets the dealer auto-authenticated

# package deal import assertion
from SmartApi import SmartConnect #or from smartapi.smartConnect import SmartConnect

import pyotp,time, pytz
from datetime import datetime
import threading
from config import *

#create object of name
obj=SmartConnect(api_key=apikey)

#login api name

knowledge = obj.generateSession(username,pwd,pyotp.TOTP(token).now())
#cls
# print (knowledge)
refreshToken= knowledge['data']['refreshToken']
AUTH_TOKEN = knowledge['data']['jwtToken']

#fetch the feedtoken
FEED_TOKEN =obj.getfeedToken()
#print ("Feed Token: "+FEED_TOKEN)

#fetch Consumer Profile
res= obj.getProfile(refreshToken) 
print(res['data']['exchanges'])

Fetching Tokens: After authentication, it retrieves refreshToken and AUTH_TOKEN for sustaining the session, and FEED_TOKEN for fetching knowledge feeds.

Options of Good Websocket 2.0

As per the newest documentation of SmartAPI listed here are the next options of AngelOne Good WebsocketV2

The SmartAPI provides a streamlined and uniform construction for each JSON requests and binary responses. It additionally offers an easy heartbeat mechanism for message exchanges.

Purchasers, every recognized by their distinctive Angel One buying and selling account ID, can keep as much as three simultaneous WebSocket connections. There’s no necessity to disconnect and reconnect for modifying subscriptions; the present connection will be successfully utilized for real-time subscription changes.

Failures in modifying subscriptions gained’t have an effect on present subscriptions, making certain uninterrupted knowledge feeds. Unsubscription requests for non-subscribed tokens are seamlessly dealt with with out disturbing the info circulation of lively subscriptions.

Every WebSocket session helps a most of 1,000 token subscriptions. As an example, subscribing to completely different modes (like LTP, Quote, and SnapQuote) for a single entity equivalent to Infosys NSE counts as separate subscriptions.

Redundant subscriptions to the identical token and mode are effectively managed, not affecting the subscription restrict. Purchasers obtain a definite knowledge replace (tick) for every mixture of token and mode. Within the case of a number of modes subscribed for a single entity, like Infosys NSE, a separate tick is shipped for every mode with related info.

Step 6. Operating the Websocket to Fetch LTP Quotes

Full Python Code to Fetch the Realtime LTP quotes

# package deal import assertion
from SmartApi import SmartConnect #or from smartapi.smartConnect import SmartConnect

import pyotp,time, pytz
from datetime import datetime
import threading
from config import *

#create object of name
obj=SmartConnect(api_key=apikey)

#login api name

knowledge = obj.generateSession(username,pwd,pyotp.TOTP(token).now())
#cls
# print (knowledge)
refreshToken= knowledge['data']['refreshToken']
AUTH_TOKEN = knowledge['data']['jwtToken']

#fetch the feedtoken
FEED_TOKEN =obj.getfeedToken()
#print ("Feed Token: "+FEED_TOKEN)

#fetch Consumer Profile
res= obj.getProfile(refreshToken) 
print(res['data']['exchanges'])


from SmartApi.smartWebSocketV2 import SmartWebSocketV2
from logzero import logger


correlation_id = "ws_test"
motion = 1 #motion = 1, subscribe to the feeds motion = 2 - unsubscribe
mode = 1   #mode = 1 , Fetches LTP quotes

token_list = [
    {
        "exchangeType": 2,
        "tokens": ["57920","57919"]
    }
]
token_list1 = [
    {
        "exchangeType": 1,
        "tokens": ["26000","26009"]
    }
]

sws = SmartWebSocketV2(AUTH_TOKEN, apikey, username, FEED_TOKEN,max_retry_attempt=5)

#row_format = "Trade Sort: {exchange_type}, Token: {token}, Final Traded Worth: {last_traded_price}"


def on_data(wsapp, message):
    # Convert timestamp from milliseconds to seconds
    timestamp = message['exchange_timestamp'] / 1000  # Convert to seconds
    utc_time = datetime.utcfromtimestamp(timestamp)

    # Outline the timezone for UTC +05:30
    timezone = pytz.timezone('Asia/Kolkata')  # 'Asia/Kolkata' is the timezone for UTC +05:30

    # Convert UTC time to UTC +05:30
    local_time = utc_time.substitute(tzinfo=pytz.utc).astimezone(timezone)
    formatted_timestamp = local_time.strftime('%Y-%m-%d %H:%M:%S')

    # Outline the format for the output with two decimal locations for Final Traded Worth
    row_format = "Trade Sort: {exchange_type}, Token: {token}, Final Traded Worth: {last_traded_price:.2f}, Timestamp: {timestamp}"

    # Format the message knowledge
    formatted_row = row_format.format(
        exchange_type=message['exchange_type'],
        token=message['token'],
        last_traded_price=message['last_traded_price'] / 100,  # Assuming this division by 100 is required to your particular case
        timestamp=formatted_timestamp
    )

    # Print the formatted knowledge
    logger.data(formatted_row)



def on_open(wsapp):
    logger.data("on open")
    sws.subscribe(correlation_id, mode, token_list)
    sws.subscribe(correlation_id, mode, token_list1)
    
    # sws.unsubscribe(correlation_id, mode, token_list1)


def on_error(wsapp, error):
    logger.data(error)


def on_close(wsapp):
    logger.data("Shut")



def close_connection():
    sws.close_connection()


# Assign the callbacks.
sws.on_open = on_open
sws.on_data = on_data
sws.on_error = on_error
sws.on_close = on_close

threading.Thread(goal=sws.join).begin()

The above code makes use of a separate thread is began for the WebSocket connection to run asynchronously. The tokens “57920”, “57919” correspond to Nifty and Financial institution Nifty Nov 23 Futures contracts, and “26000”, “26009” correspond to Nifty and Financial institution Nifty Index Information.

Pattern Output

[I 231120 12:24:35 smartwebsocket:79] Trade Sort: 1, Token: 26000, Final Traded Worth: 19698.10, Timestamp: 2023-11-20 12:24:35
[I 231120 12:24:35 smartwebsocket:79] Trade Sort: 1, Token: 26009, Final Traded Worth: 43629.95, Timestamp: 2023-11-20 12:24:35
[I 231120 12:24:35 smartwebsocket:79] Trade Sort: 1, Token: 26000, Final Traded Worth: 19696.75, Timestamp: 2023-11-20 12:24:36
[I 231120 12:24:35 smartwebsocket:79] Trade Sort: 1, Token: 26009, Final Traded Worth: 43628.00, Timestamp: 2023-11-20 12:24:36
[I 231120 12:24:36 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43765.00, Timestamp: 2023-11-20 12:24:36
[I 231120 12:24:36 smartwebsocket:79] Trade Sort: 2, Token: 57920, Final Traded Worth: 19750.00, Timestamp: 2023-11-20 12:24:36
[I 231120 12:24:36 smartwebsocket:79] Trade Sort: 2, Token: 57920, Final Traded Worth: 19750.00, Timestamp: 2023-11-20 12:24:36
[I 231120 12:24:36 smartwebsocket:79] Trade Sort: 1, Token: 26000, Final Traded Worth: 19696.70, Timestamp: 2023-11-20 12:24:37
[I 231120 12:24:36 smartwebsocket:79] Trade Sort: 1, Token: 26009, Final Traded Worth: 43631.30, Timestamp: 2023-11-20 12:24:37
[I 231120 12:24:37 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43769.35, Timestamp: 2023-11-20 12:24:37
[I 231120 12:24:37 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43769.35, Timestamp: 2023-11-20 12:24:37
[I 231120 12:24:37 smartwebsocket:79] Trade Sort: 2, Token: 57920, Final Traded Worth: 19750.00, Timestamp: 2023-11-20 12:24:37
[I 231120 12:24:37 smartwebsocket:79] Trade Sort: 1, Token: 26000, Final Traded Worth: 19698.25, Timestamp: 2023-11-20 12:24:38
[I 231120 12:24:37 smartwebsocket:79] Trade Sort: 1, Token: 26009, Final Traded Worth: 43631.10, Timestamp: 2023-11-20 12:24:38
[I 231120 12:24:38 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43769.35, Timestamp: 2023-11-20 12:24:38
[I 231120 12:24:38 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43769.35, Timestamp: 2023-11-20 12:24:38
[I 231120 12:24:38 smartwebsocket:79] Trade Sort: 1, Token: 26000, Final Traded Worth: 19696.00, Timestamp: 2023-11-20 12:24:39
[I 231120 12:24:38 smartwebsocket:79] Trade Sort: 1, Token: 26009, Final Traded Worth: 43627.85, Timestamp: 2023-11-20 12:24:39
[I 231120 12:24:38 smartwebsocket:79] Trade Sort: 2, Token: 57920, Final Traded Worth: 19750.00, Timestamp: 2023-11-20 12:24:39
[I 231120 12:24:39 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43765.00, Timestamp: 2023-11-20 12:24:39
[I 231120 12:24:39 smartwebsocket:79] Trade Sort: 2, Token: 57919, Final Traded Worth: 43765.00, Timestamp: 2023-11-20 12:24:39

Step 7 : Fetching Open, Excessive, Shut, LTP, Quantity Information

Right here is the python code smartwebsocketquotes.py which fetches the realtime inventory market worth quotes together with quantity knowledge

# package deal import assertion
from SmartApi import SmartConnect #or from smartapi.smartConnect import SmartConnect

import pyotp,time, pytz
from datetime import datetime
import threading
from config import *

#create object of name
obj=SmartConnect(api_key=apikey)

#login api name

knowledge = obj.generateSession(username,pwd,pyotp.TOTP(token).now())
#cls
# print (knowledge)
refreshToken= knowledge['data']['refreshToken']
AUTH_TOKEN = knowledge['data']['jwtToken']

#fetch the feedtoken
FEED_TOKEN =obj.getfeedToken()
#print ("Feed Token: "+FEED_TOKEN)

#fetch Consumer Profile
res= obj.getProfile(refreshToken) 
print(res['data']['exchanges'])


from SmartApi.smartWebSocketV2 import SmartWebSocketV2
from logzero import logger


correlation_id = "ws_test"
motion = 1 #motion = 1, subscribe to the feeds motion = 2 - unsubscribe
mode = 2   #mode = 2 , Fetches quotes

token_list = [
    {
        "exchangeType": 2,
        "tokens": ["57920","57919"]
    }
]


sws = SmartWebSocketV2(AUTH_TOKEN, apikey, username, FEED_TOKEN,max_retry_attempt=5)

def on_data(wsapp, message):
    strive:
        # Assuming 'message' is a dictionary, not a listing
        merchandise = message

        # Changing and formatting the timestamp
        timestamp = datetime.fromtimestamp(merchandise['exchange_timestamp'] / 1000, pytz.timezone('Asia/Kolkata'))

        # Formatting the info
        formatted_item = {
            'Trade Sort': merchandise['exchange_type'],
            'Token': merchandise['token'],
            'Timestamp (IST)': timestamp.strftime('%Y-%m-%d %H:%M:%S'),
            'Open Worth': f"{merchandise['open_price_of_the_day'] / 100:.2f}",
            'Excessive Worth': f"{merchandise['high_price_of_the_day'] / 100:.2f}",
            'Low Worth': f"{merchandise['low_price_of_the_day'] / 100:.2f}",
            'Shut Worth': f"{merchandise['closed_price'] / 100:.2f}",
            'Final Traded Worth': f"{merchandise['last_traded_price'] / 100:.2f}",
        }

        # Logging the formatted knowledge
        logger.data(formatted_item)
    besides Exception as e:
        logger.error(f"Error processing message: {e}")



def on_open(wsapp):
    logger.data("on open")
    sws.subscribe(correlation_id, mode, token_list)
    
    
    # sws.unsubscribe(correlation_id, mode, token_list1)


def on_error(wsapp, error):
    logger.data(error)


def on_close(wsapp):
    logger.data("Shut")



def close_connection():
    sws.close_connection()


# Assign the callbacks.
sws.on_open = on_open
sws.on_data = on_data
sws.on_error = on_error
sws.on_close = on_close

threading.Thread(goal=sws.join).begin()

Pattern Output

[I 231120 14:48:04 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57920', 'Timestamp (IST)': '2023-11-20 14:48:05', 'Open Worth': '19798.90', 'Excessive Worth': '19848.00', 'Low Worth': '19718.00', 'Shut Worth': '19806.50', 'Final Traded Worth': '19771.20'}
[I 231120 14:48:05 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57920', 'Timestamp (IST)': '2023-11-20 14:48:05', 'Open Worth': '19798.90', 'Excessive Worth': '19848.00', 'Low Worth': '19718.00', 'Shut Worth': '19806.50', 'Final Traded Worth': '19771.20'}
[I 231120 14:48:05 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57919', 'Timestamp (IST)': '2023-11-20 14:48:05', 'Open Worth': '43724.60', 'Excessive Worth': '43900.00', 'Low Worth': '43559.80', 'Shut Worth': '43715.45', 'Final Traded Worth': '43800.90'}
[I 231120 14:48:06 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57920', 'Timestamp (IST)': '2023-11-20 14:48:06', 'Open Worth': '19798.90', 'Excessive Worth': '19848.00', 'Low Worth': '19718.00', 'Shut Worth': '19806.50', 'Final Traded Worth': '19771.20'}
[I 231120 14:48:06 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57919', 'Timestamp (IST)': '2023-11-20 14:48:06', 'Open Worth': '43724.60', 'Excessive Worth': '43900.00', 'Low Worth': '43559.80', 'Shut Worth': '43715.45', 'Final Traded Worth': '43800.90'}
[I 231120 14:48:07 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57920', 'Timestamp (IST)': '2023-11-20 14:48:07', 'Open Worth': '19798.90', 'Excessive Worth': '19848.00', 'Low Worth': '19718.00', 'Shut Worth': '19806.50', 'Final Traded Worth': '19771.20'}
[I 231120 14:48:07 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57919', 'Timestamp (IST)': '2023-11-20 14:48:07', 'Open Worth': '43724.60', 'Excessive Worth': '43900.00', 'Low Worth': '43559.80', 'Shut Worth': '43715.45', 'Final Traded Worth': '43800.90'}
[I 231120 14:48:07 smartwebsocket:68] {'Trade Sort': 2, 'Token': '57920', 'Timestamp (IST)': '2023-11-20 14:48:08', 'Open Worth': '19798.90', 'Excessive Worth': '19848.00', 'Low Worth': '19718.00', 'Shut Worth': '19806.50', 'Final Traded Worth': '19771.30'}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles