From d04b11fb2de5d7ac80bc92a7db738f749f02b0a6 Mon Sep 17 00:00:00 2001 From: ASHUTOSH SHUKLA Date: Wed, 27 Nov 2024 23:12:32 +0530 Subject: [PATCH 1/2] Update config.py Modified the Stockcode mapping dictionary to access file for FOBSE instruments. --- breeze_connect/config.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/breeze_connect/config.py b/breeze_connect/config.py index ac6ea2a..e4fb72f 100644 --- a/breeze_connect/config.py +++ b/breeze_connect/config.py @@ -235,12 +235,13 @@ def __str__(self): FNO_EXCHANGE_TYPES = ["nfo","mcx","ndx","bfo"] STRATEGY_SUBSCRIPTION = ["one_click_fno","i_click_2_gain"] -#Isec NSE Stockcode mapping file +#Isec NSE, BSE, CDNSE, FONSE, FOBSE Stockcode mapping file ISEC_NSE_CODE_MAP_FILE = { 'nse':'NSEScripMaster.txt', 'bse':'BSEScripMaster.txt', 'cdnse':'CDNSEScripMaster.txt', - 'fonse':'FONSEScripMaster.txt' + 'fonse':'FONSEScripMaster.txt', + 'fobse': 'FOBSEScripMaster.txt' } feed_interval_map = { @@ -255,4 +256,4 @@ def __str__(self): '5minute':'5MIN', '30minute':'30MIN', '1second':'1SEC' -} \ No newline at end of file +} From bea48a6de264f64f2e8eb803becb71ed72a02196 Mon Sep 17 00:00:00 2001 From: ASHUTOSH SHUKLA Date: Wed, 27 Nov 2024 23:22:05 +0530 Subject: [PATCH 2/2] Update breeze_connect.py Upgraded get_names function to handle and return values for all the available exchange codes and also for all the available instruments in all the exchanges. This was done because get_names function was only working for NSE and not other exchanges and instruments. --- breeze_connect/breeze_connect.py | 135 +++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 26 deletions(-) diff --git a/breeze_connect/breeze_connect.py b/breeze_connect/breeze_connect.py index 50929de..88e3a6d 100644 --- a/breeze_connect/breeze_connect.py +++ b/breeze_connect/breeze_connect.py @@ -939,9 +939,9 @@ def get_trade_detail(self, exchange_code="", order_id=""): if self.api_handler: return self.api_handler.get_trade_detail(exchange_code, order_id) - def get_names(self, exchange_code="",stock_code=""): + def get_names(self, exchange_code="",stock_code="", instrument_name=None, expiry_date=None, strike_price=None, option_type=None): if self.api_handler: - return self.api_handler.get_names(exchange_code, stock_code) + return self.api_handler.get_names(exchange_code, stock_code, instrument_name, expiry_date, strike_price, option_type) def preview_order(self, stock_code="",exchange_code="",product="",order_type="",price="",action="",quantity="",expiry_date="",right="",strike_price="",specialflag="",stoploss="",order_rate_fresh=""): if self.api_handler: @@ -1630,40 +1630,123 @@ def get_trade_detail(self, exchange_code, order_id): except Exception as e: self.error_exception(self.get_trade_detail.__name__,e) - def get_names(self, exchange_code, stock_code): + def get_names(self, exchange_code, stock_code, instrument_name=None, expiry_date=None, strike_price=None, option_type=None): + """Function to handle multiple naming conventions and resolve ambiguities for FONSE, FOBSE, and CDNSE""" try: lexchange_code = exchange_code.lower() stock_code = stock_code.upper() mapper_exchangecode_to_file = config.ISEC_NSE_CODE_MAP_FILE required_file = zipfile.open(mapper_exchangecode_to_file.get(lexchange_code)) - + dataframe = pd.read_csv(required_file, sep=',', engine='python') - - df2 = dataframe[(dataframe[' "ExchangeCode"'] == stock_code) | (dataframe[' "ShortName"'] == stock_code)] - if(len(df2)==0): - return self.validation_error_response(except_message.ISEC_NSE_STOCK_MAP_EXCEPTION.value) - requiredresult = df2[[' "ShortName"',' "ExchangeCode"','Token',' "CompanyName"']] - - isec_stock = requiredresult[' "ShortName"'].to_string().split()[1] - token = " ".join(requiredresult['Token'].to_string().split()[1:]) - exchange = requiredresult[' "ExchangeCode"'].to_string() - compname = " ".join(requiredresult[' "CompanyName"'].to_string().split()[1:]) - if(" " in exchange): + + # Function to filter dataframe based on additional parameters + def filter_dataframe(df, _exchange_code, _stock_code, _instrument_name=None, _expiry_date=None, _strike_price=None, _option_type=None): + if _exchange_code.upper() in ["FONSE", "FOBSE", "CDNSE"]: + # For FOBSE + if _instrument_name in ["OPTSTK", "OPTIDX", "OPTIND", "OPTCUR"]: + return df[ + ((df["ExchangeCode"] == _stock_code) | + (df["ShortName"] == _stock_code)) & + (df["InstrumentName"] == _instrument_name) & + (df["ExpiryDate"] == _expiry_date) & + (df["StrikePrice"] == _strike_price) & + (df["OptionType"] == _option_type) + ] + elif _instrument_name in ["FUTSTK", "FUTIDX", "FUTIND", "FUTCUR", "UNDCUR"]: + return df[ + ((df["ExchangeCode"] == _stock_code) | + (df["ShortName"] == _stock_code)) & + (df["InstrumentName"] == _instrument_name) & + (df["ExpiryDate"] == _expiry_date) + ] + else: + return + else: + # Default behavior for NSE and BSE + return df[ + (df[' "ExchangeCode"'] == _stock_code) | (df[' "ShortName"'] == _stock_code) + ] if _exchange_code.upper() == "NSE" else df[ + (df["ExchangeCode"] == _stock_code) | (df["ShortName"] == _stock_code) + ] + + # Filter the dataframe based on exchange_code + df2 = filter_dataframe(dataframe, exchange_code, stock_code, _instrument_name=instrument_name, + _expiry_date=expiry_date, _strike_price=strike_price, _option_type=option_type) + + if df2 is None or len(df2) == 0: + return self.validation_error_response("No matching data found for the given stock_code with this parameters") + + # Select required columns based on exchange_code + if exchange_code.upper() in ["FONSE", "FOBSE", "CDNSE"]: + # For FONSE, FOBSE, CDNSE, decide columns dynamically based on instrument_name + if instrument_name in ["OPTSTK", "OPTIDX", "OPTIND", "OPTCUR"]: + requiredresult = df2[[ + "ShortName", "ExchangeCode", "Token", "CompanyName", + "InstrumentName", "ExpiryDate", "StrikePrice", "OptionType" + ]] + elif instrument_name in ["FUTSTK", "FUTIDX", "FUTIND", "FUTCUR", "UNDCUR"]: + requiredresult = df2[[ + "ShortName", "ExchangeCode", "Token", "CompanyName", + "InstrumentName", "ExpiryDate" + ]] + else: + requiredresult = df2[["ShortName", "ExchangeCode", "Token", "CompanyName"]] + elif exchange_code.upper() == "NSE": + # For NSE, use the alternative naming convention + requiredresult = df2[[' "ShortName"', ' "ExchangeCode"', 'Token', ' "CompanyName"']] + else: # Default case for BSE + requiredresult = df2[["ShortName", "ExchangeCode", "Token", "CompanyName"]] + + # Extract values from the filtered dataframe + isec_stock = requiredresult.iloc[0]["ShortName"] if "ShortName" in requiredresult else \ + requiredresult.iloc[0][' "ShortName"'] + token = str(requiredresult.iloc[0]['Token']) + exchange = str( + requiredresult.iloc[0]["ExchangeCode"] if "ExchangeCode" in requiredresult else requiredresult.iloc[0][ + ' "ExchangeCode"'] + ) + compname = str( + requiredresult.iloc[0]["CompanyName"] if "CompanyName" in requiredresult else requiredresult.iloc[0][ + ' "CompanyName"'] + ) + + # Common logic for processing exchange value + if " " in exchange: exchange = " ".join(exchange.split()[1:]) + # Initialize the result dictionary with common fields result = { - 'exchange_code':exchange_code, - 'exchange_stock_code': exchange, - 'isec_stock_code':isec_stock, - 'isec_token': token, - 'company name':compname, - 'isec_token_level1':str('4.1!') + str(token), - 'isec_token_level2':str('4.2!') + str(token) - } - + 'exchange_code': exchange_code, + 'exchange_stock_code': exchange, + 'isec_stock_code': isec_stock, + 'isec_token': token, + 'company name': compname, + 'isec_token_level1': str('4.1!') + str(token), + 'isec_token_level2': str('4.2!') + str(token) + } + + # Add optional fields dynamically based on instrument type + if instrument_name in ["OPTSTK", "OPTIDX", "OPTIND", "OPTCUR"]: + result["instrument_name"] = instrument_name + result["expiry_date"] = str( + requiredresult.iloc[0]["ExpiryDate"]) if "ExpiryDate" in requiredresult else None + result["strike_price"] = ( + requiredresult.iloc[0]["StrikePrice"]) if "StrikePrice" in requiredresult else None + result["option_type"] = str( + requiredresult.iloc[0]["OptionType"]) if "OptionType" in requiredresult else None + elif instrument_name in ["FUTSTK", "FUTIDX", "FUTIND", "FUTCUR", "UNDCUR"]: + result["instrument_name"] = instrument_name + result["expiry_date"] = str( + requiredresult.iloc[0]["ExpiryDate"]) if "ExpiryDate" in requiredresult else None + else: + # No additional fields for other instruments + pass + return result + except Exception as e: - self.error_exception(self.get_names.__name__,e) + self.error_exception(self.get_names.__name__, e) def limit_calculator(self,strike_price,product_type,expiry_date,underlying,exchange_code,order_flow,stop_loss_trigger,option_type,source_flag,limit_rate,order_reference,available_quantity,market_type,fresh_order_limit): try: @@ -1768,4 +1851,4 @@ def preview_order(self,stock_code="",exchange_code="",product="",order_type="",p except Exception as e: self.error_exception(self.preview_order.__name__,e) - \ No newline at end of file +