0% found this document useful (0 votes)
18 views6 pages

BSESEN Options Trading with PnL Calculation

The document outlines a Python script that interacts with the BreezeConnect API to trade options for the stock 'BSESEN'. It includes functionalities for fetching quotes, placing orders, tracking executed prices, and calculating profit and loss (PnL) for call and put options. Additionally, it demonstrates how to subscribe to WebSocket feeds for real-time updates on option prices.

Uploaded by

dhanesh kumar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views6 pages

BSESEN Options Trading with PnL Calculation

The document outlines a Python script that interacts with the BreezeConnect API to trade options for the stock 'BSESEN'. It includes functionalities for fetching quotes, placing orders, tracking executed prices, and calculating profit and loss (PnL) for call and put options. Additionally, it demonstrates how to subscribe to WebSocket feeds for real-time updates on option prices.

Uploaded by

dhanesh kumar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import pandas as pd

import numpy as np
import [Link] as plt
from breeze_connect import BreezeConnect
import urllib
import zipfile
import io
import os
import threading
import time

import warnings
[Link]('ignore')

breeze = BreezeConnect(api_key=str(app_key))

breeze.generate_session(api_secret=str(secret_key),session_token=str(session_key))

#Atm Strike price


Quotes = breeze.get_quotes(stock_code="BSESEN",
exchange_code="BSE",
expiry_date="",
product_type="cash",
right="",
strike_price="0")
Ltp = Quotes["Success"][0]["ltp"]
ATM = round((Quotes["Success"][1]["ltp"])/100)*100
print(ATM)

# How to Find Strike price of particular Premium

#Call

df =breeze.get_option_chain_quotes(stock_code="BSESEN",
exchange_code="BFO",
product_type="options",
expiry_date="2025-02-04T06:00:00.000Z",
right="call")["Success"]
df = [Link](df)
#print(df)

strike_price_call = [Link][(df["ltp"] >= 70) & (df["ltp"] <= 100),


"strike_price"].astype(int).tolist()[0]
print(strike_price_call)

print(type(strike_price_call))

#Put

df =breeze.get_option_chain_quotes(stock_code="BSESEN",
exchange_code="BFO",
product_type="options",
expiry_date="2025-02-04T06:00:00.000Z",
right="put")["Success"]
df = [Link](df)
#print(df)

strike_price_put = [Link][(df["ltp"] >= 70) & (df["ltp"] <= 100),


"strike_price"].astype(int).tolist()[0]
print(strike_price_put)
print(type(strike_price_put))

#Find LTP through Get_Quotes

#Call
premium_call = breeze.get_quotes(stock_code="BSESEN",
exchange_code="BFO",
expiry_date="2025-02-04T06:00:00.000Z",
product_type="options",
right="call",
strike_price = str(strike_price_call))["Success"][0]["ltp"]

print(f"Premium_call_{strike_price_call} :{premium_call}")
#Put
premium_put = breeze.get_quotes(stock_code="BSESEN",
exchange_code="BFO",
expiry_date="2025-02-04T06:00:00.000Z",
product_type="options",
right="put",
strike_price = str(strike_price_put))["Success"][0]["ltp"]

print(f"Premium_put_{strike_price_put} :{premium_put}")

#Strangle Place Order

#Call
call_placeorder = breeze.place_order(stock_code="BSESEN",
exchange_code="BFO",
product="options",
action="buy",
order_type="market",
stoploss="",
quantity="20",
price="",
validity="day",
validity_date="2022-08-30T06:00:00.000Z",
disclosed_quantity="0",
expiry_date="2025-02-04T06:00:00.000Z",
right="call",
strike_price=str(strike_price_call))
print(call_placeorder)

call_orderID = call_placeorder["Success"]["order_id"]
print(f"call_orderID : {call_orderID}")

#Put
put_placeorder = breeze.place_order(stock_code="BSESEN",
exchange_code="BFO",
product="options",
action="buy",
order_type="market",
stoploss="",
quantity="20",
price="",
validity="day",
validity_date="2022-08-30T06:00:00.000Z",
disclosed_quantity="0",
expiry_date="2025-02-04T06:00:00.000Z",
right="put",
strike_price=str(strike_price_put))
print(put_placeorder)

put_orderID = put_placeorder["Success"]["order_id"]
print(f"put_orderID : {put_orderID}")

#Find the executed price using tradebook


#call
Call_executedprice = float(breeze.get_trade_detail(exchange_code="BFO",
order_id=call_orderID)["Success"][0]["execution_price"])

#put
Put_executedprice = float(breeze.get_trade_detail(exchange_code="BFO",
order_id=put_orderID)["Success"][0]["execution_price"])

print(f"Call_executedprice: {Call_executedprice}")
print(f"Put_executedprice: {Put_executedprice}")

#Find Stock Token using security master file


# Step 1: Download and Extract the Data
url = "[Link]
response = [Link](url, stream=True)

if response.status_code == 200:
print("Downloading ZIP file...")
# Open the ZIP file from the response content
zip_data = [Link]([Link]([Link]))
# Extract to a folder
extract_folder = "extracted_data"
zip_data.extractall(extract_folder)
print(f"Extracted files to: {extract_folder}")
else:
print(f"Failed to download ZIP file. HTTP Status: {response.status_code}")
exit()

# Step 2: Load the [Link] File into a DataFrame


txt_file_path = [Link](extract_folder, "[Link]")
if not [Link](txt_file_path):
print("[Link] not found in the extracted files.")
exit()

print("Loading data into DataFrame...")


df = pd.read_csv(txt_file_path, delimiter=',', engine='python')

# Step 3: Ensure Proper Data Types for Filtering


df['StrikePrice'] = pd.to_numeric(df['StrikePrice'], errors='coerce')
df['ExpiryDate'] = pd.to_datetime(df['ExpiryDate'], format='%d-%b-
%Y').[Link]('%d-%b-%Y')

# Step 4: Define the Function to Fetch Token


def get_token(df, instrument_name, short_name, expiry_date, strike_price, series,
option_type):
"""
Filters the FONSEScripMaster DataFrame based on the input criteria and returns
the Token.
"""
# Filter the DataFrame
filtered_df = df[
(df['InstrumentName'].[Link]() == instrument_name.strip()) &
(df['ShortName'].[Link]() == short_name.strip()) &
(df['ExpiryDate'].[Link]() == expiry_date.strip()) &
(df['StrikePrice'] == float(strike_price)) &
(df['Series'].[Link]() == [Link]()) &
(df['OptionType'].[Link]() == option_type.strip())
]

# Return the Token if a match is found


if not filtered_df.empty:
return filtered_df['Token'].iloc[0]
else:
return None

# Step 5: Input Parameters


instrument_name = "OPTIND"
short_name = "BSESEN"
expiry_date = "04-Feb-2025"
strike_price = str(strike_price_call)
series = "OPTION"
option_type = "CE"

# Step 6: Fetch the Token


token_call = get_token(df, instrument_name, short_name, expiry_date, strike_price,
series, option_type)

# Step 7: Output the Result


if token_call:
print(f"Token found: {token_call}")
else:
print("No matching Token found.")

instrument_name = "OPTIND"
short_name = "BSESEN"
expiry_date = "04-Feb-2025"
strike_price = str(strike_price_put)
series = "OPTION"
option_type = "PE"

# Step 6: Fetch the Token


token_put = get_token(df, instrument_name, short_name, expiry_date, strike_price,
series, option_type)

# Step 7: Output the Result


if token_put:
print(f"Token_put found: {token_put}")
else:
print("No matching Token_put found.")

#converting token into subscription model


call_token= "8.1!"+str(token_call)
put_token= "8.1!"+str(token_put)

print(f"call_token_websocket :{call_token}")
print(f"put_token_websocket :{put_token}")

# Websocket subscribtion and pnl calculation

# Connect to WebSocket
breeze.ws_connect()

# Global dictionary to track PnL values


pnl_tracker = {"pnl_call": None, "pnl_put": None}
lock = [Link]() # Ensure thread-safe operations

# Function to calculate Call PnL


def calculate_pnl_call(last):
pnl_call = last - Call_executedprice # Adjust premium logic if needed
with lock:
pnl_tracker["pnl_call"] = pnl_call
#print(f"✅ pnl_call calculated: {pnl_call}")

# Function to calculate Put PnL


def calculate_pnl_put(last):
pnl_put = last - Put_executedprice # Adjust premium logic if needed
with lock:
pnl_tracker["pnl_put"] = pnl_put
#print(f"✅ pnl_put calculated: {pnl_put}")

# Callback function to receive ticks


def on_ticks(ticks):
global pnl_tracker

symbol = [Link]("symbol")
last = [Link]("last")

if symbol == call_token: # Call option


[Link](target=calculate_pnl_call, args=(int(last),)).start()

if symbol == put_token: # Put option


[Link](target=calculate_pnl_put, args=(int(last),)).start()

# Wait for both threads to complete (simulate real-time processing)


[Link](2) # Small delay to ensure both threads complete

with lock:
if pnl_tracker["pnl_call"] is not None and pnl_tracker["pnl_put"] is not
None:
total_pnl = (pnl_tracker["pnl_call"] + pnl_tracker["pnl_put"])*20
print(f"✅ Combined total_pnl: {total_pnl}")
else:
print("⏳ Waiting for both PnL values to update...")

# Assign the callback function


breeze.on_ticks = on_ticks
breeze.subscribe_feeds(stock_token=[call_token,put_token])

Response:

{'message': "Stock ['8.1!839069', '8.1!839861'] subscribed successfully"}


⏳ Waiting for both PnL values to update...
✅ Combined total_pnl: -76.99999999999989
✅ Combined total_pnl: -76.99999999999989
✅ Combined total_pnl: -76.99999999999989
✅ Combined total_pnl: -76.99999999999989
✅ Combined total_pnl: -76.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -96.99999999999989
✅ Combined total_pnl: -116.99999999999989
✅ Combined total_pnl: -116.99999999999989
✅ Combined total_pnl: -116.99999999999989

Common questions

Powered by AI

Automated option trading systems manage risk by using precise data-driven strategies to select optimal strike prices and execute trades with market orders. By calculating real-time PnL and receiving continuous data updates through WebSockets, these systems provide traders with timely insights, thus allowing for dynamic risk adjustments and decision-making based on current market conditions .

To determine the strike price for call and put options, you filter the option chain quotes data for the specific range of premium (LTP) values. For call options, you select quotes with an LTP between 70 and 100 to get the strike price. Similarly, the same range is used for put options, ensuring the selection of strike prices within specified premium limits .

WebSocket technology enables streaming real-time data by establishing a persistent connection between the client and the server. In automated trading systems, it is used to subscribe to live feeds (e.g., stock tokens) and receive data updates instantaneously. This is crucial for making timely trading decisions based on the most current market conditions, such as calculating live PnL values for stock options .

Threading is employed to handle multiple calculations of PnL for different options concurrently, ensuring efficient data processing and real-time updates. The use of locks ensures thread-safe operations while updating shared resources, preventing race conditions and maintaining data integrity in the client-server setup .

The trading strategy involves placing buy market orders for both call and put options using the BreezeConnect API, with specified parameters like product type, expiry date, right (option type), and strike price obtained from previous data retrieval steps. The system records order IDs after successful order placement, which are later used to fetch trade details such as executed prices necessary for calculating PnL .

The process begins by downloading and extracting the FONSEScripMaster data file containing various stock details. The extracted data file is loaded into a DataFrame, ensuring proper data types for filtering. A specific function, get_token, is defined to filter the DataFrame by instrument name, short name, expiry date, strike price, series, and option type to match specified criteria. Once filtered, the function returns the token if a match is found .

The method involves calculating individual PnL values for call and put options by subtracting executed prices from the latest prices. These individual PnL values are aggregated to compute the total PnL, reflecting overall trading performance in real-time. This aggregation allows traders to gauge the net impact of market movements on their options portfolio .

The BreezeConnect API is primarily used to retrieve financial data, such as stock quotes and option chains, execute trades, and track trade details like executed prices. It facilitates making complex data operations, like obtaining live trading prices and calculating potential profits and losses (PnL) for stock options .

The steps include downloading the SecurityMaster ZIP file, extracting its contents using the zipfile module, and loading the FONSEScripMaster.txt file into a Pandas DataFrame. Proper data formatting is applied, and a filtering function is defined to fetch specific tokens based on the provided criteria, such as instrument and option type .

The multi-threaded approach allows for efficient real-time calculation of PnL by simultaneously processing data streams for multiple options (call and put), enhancing processing speed and responsiveness. However, the complexity of maintaining thread safety with mechanisms like locks can introduce potential bottlenecks and risks of race conditions, which can complicate the implementation and reliability of the trading system .

You might also like