breezeconnect-patch
Version:
The *UNOFFICIAL* BreezeConnect API patch. This is result of no-response from Offical Support Team
1,069 lines (997 loc) • 89.9 kB
JavaScript
var sha256 = require("crypto-js/sha256");
const io = require("socket.io-client");
const axios = require('axios');
const urls = require("./config").urls;
const responseMessage = require('./config').responseMessage;
const exceptionMessage = require('./config').exceptionMessage;
const tuxToUserMap = require('./config').tuxToUserMap;
const apiRequest = require('./config').apiRequest;
const apiEndpoint = require('./config').apiEndpoint;
const typeList = require('./config').typeList;
const scriptMasterFile = require('./config').scriptMasterFile;
const feedIntervalMap = require('./config').feedIntervalMap;
const channelIntervalMap = require('./config').channelIntervalMap;
const roomName = require('./config').roomName;
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
var BreezeConnect = function(params) {
var self = this;
self.version = "0.1";
self.appKey = params.appKey || "";
self.userId = "";
self.secretKey = "";
self.socket = null;
self.socketOrder = null;
self.socketOHLCV = null;
self.sessionKey = "";
self.apiSession = "";
self.onTicks = null;
self.stockScriptDictList = [];
self.tokenScriptDictList = [];
self.tuxToUserValue = tuxToUserMap;
self.socketConnectionResponse= function(message){
return {"message":message};
}
self.subscribeException = function(message){
throw message;
}
self.validationErrorResponse = function(message){
return {
"Success": "",
"Status": 500,
"Error": message
};
}
self.errorException = function(funcName,error){
var message = `${funcName}() Error`;
throw message + error.stack;
}
String.prototype.format = function () {
var args = arguments;
return this.replace(/{([0-9A-Z]+)}/g, function (match, index) {
return typeof args[index] == 'undefined' ? match : args[index];
});
};
self.connect = function ({isOrder=false,isOHLCV=false}) {
if(isOrder == false && isOHLCV==false)
{
self.socket = io.connect(urls.LIVE_STREAM_URL, {
auth: {
user: self.userId,
token: self.sessionKey
},
extraHeaders:{
"User-Agent": "node-socketio[client]/socket"
},
//reconnectionAttempts: 10,
transports: ["websocket"],
});
}
else if(isOrder == true)
{
self.socketOrder = io.connect(urls.LIVE_FEEDS_URL,{
auth: {
user: self.userId,
token: self.sessionKey,
},
extraHeaders:{
"User-Agent": "node-socketio[client]/socket"
},
//reconnectionAttempts: 10,
transports: ["websocket"],
});
}
else if(isOHLCV == true){
self.socketOHLCV = io.connect(urls.LIVE_OHLC_STREAM_URL,{
path:"/ohlcvstream/",
auth: {
user: self.userId,
token: self.sessionKey,
},
extraHeaders:{
"User-Agent": "node-socketio[client]/socket"
},
transports: ["websocket"],
});
}
};
self.onDisconnect = function() {
self.socket.disconnect();
};
self.generateSession = async function (secretKey,sessionKey) {
self.sessionKey = sessionKey;
self.secretKey = secretKey;
await self.apiUtil();
await self.getStockScriptList();
};
self.apiUtil = async function(){
try {
headers = {
"Content-Type": "application/json"
}
body = {
"SessionToken": self.sessionKey,
"AppKey": self.appKey
}
let response = await self.makeRequest(apiRequest.GET, apiEndpoint.CUST_DETAILS, body, headers);
if(response.data['Status']==500){
self.subscribeException(exceptionMessage.AUTHENICATION_EXCEPTION);
}
else{
self.apiSession = response.data['Success']['session_token'];
decodedKey = Buffer.from(self.apiSession,'base64').toString('ascii');
self.userId = decodedKey.split(':')[0];
self.sessionKey = decodedKey.split(':')[1];
}
} catch (error) {
self.subscribeException(exceptionMessage.AUTHENICATION_EXCEPTION);
}
}
self.watch = function (symbols) {
if (!self.socket) {
return;
}
self.socket.emit("join", symbols);
self.socket.on('stock', self.onMessage);
};
self.watchStrategy = function (symbols) {
if (!self.socketOrder) {
return;
}
self.socketOrder.emit("join", symbols);
self.socketOrder.on('stock', self.onMessageStrategy);
};
self.unwatchStrategy = function(symbols)
{
if(!self.socketOrder)
{
return;
}
self.socketOrder.emit("leave",symbols);
}
self.onOhlcStream = function(data){
let parsedData = self.parseOhlcData(data);
self.onTicks(parsedData);
}
self.watchStreamData = function(symbols,channel){
if (!self.socketOHLCV) {
return;
}
self.socketOHLCV.emit("join", symbols);
self.socketOHLCV.on(channel, self.onOhlcStream);
}
self.unwatchStreamData = function (symbol) {
self.socketOHLCV.emit("leave", symbol);
};
self.on = function (callback) {
self.socket.on("stock", callback);
};
self.onMessage = function(data){
data = self.parseData(data);
self.onTicks(data);
}
self.onMessageStrategy = function(data)
{
data = self.parseStrategyData(data);
self.onTicks(data);
}
self.notify = function(){
self.socketOrder.on('order', self.onMessage)
}
self.unwatch = function (symbol) {
self.socket.emit("leave", symbol);
};
self.wsConnectOrder = function()
{
if(!self.socketOrder)
{
self.connect({isOrder:true});
}
}
self.wsConnect = function(){
if (!self.socket){
self.connect({isOrder:false,isOHLCV:false});
}
}
self.wsDisconnect = function(){
if(self.socket)
self.onDisconnect();
}
self.getDataFromStockTokenValue = function(inputStockToken){
var outputData = {};
var stockToken = inputStockToken.split(".");
var exchangeType= stockToken[0];
var stockToken = stockToken[1].split("!")[1];
var exchangeCodeList={
"1":"BSE",
"4":"NSE",
"13":"NDX",
"6":"MCX",
};
var exchangeCodeName = exchangeCodeList[exchangeType] || false;
if(exchangeCodeName == false)
self.subscribeException(exceptionMessage.WRONG_EXCHANGE_CODE_EXCEPTION);
else if(exchangeCodeName.toLowerCase() == "bse"){
stockData = self.tokenScriptDictList[0][stockToken] || false;
if(stockData == false)
self.subscribeException(exceptionMessage.STOCK_NOT_EXIST_EXCEPTION.format("BSE",inputStockToken));
}
else if(exchangeCodeName.toLowerCase() == "nse"){
stockData = self.tokenScriptDictList[1][stockToken] || false;
if(stockData == false){
stockData = self.tokenScriptDictList[4][stockToken] || false;
if(stockData == false)
self.subscribeException(exceptionMessage.STOCK_NOT_EXIST_EXCEPTION.format("i.e. NSE or NFO",inputStockToken));
else
exchangeCodeName = "NFO";
}
}
else if(exchangeCodeName.toLowerCase() == "ndx"){
stockData = self.tokenScriptDictList[2][stockToken] || false;
if(stockData == false)
self.subscribeException(exceptionMessage.STOCK_NOT_EXIST_EXCEPTION.format("NDX",inputStockToken));
}
else if(exchangeCodeName.toLowerCase() == "mcx"){
stockData = self.tokenScriptDictList[3][stockToken] || false;
if(stockData == false)
self.subscribeException(exceptionMessage.STOCK_NOT_EXIST_EXCEPTION.format("MCX",inputStockToken));
}
outputData["stock_name"] = stockData[1];
var exchCodes = ["nse","bse"];
if (!Boolean(exchCodes.includes(exchangeCode.toLowerCase()))){
var productType = stockData[0].split("-")[0];
if(productType.toLowerCase()=="fut")
outputData["product_type"] = "Futures";
if(productType.toLowerCase()=="opt")
outputData["product_type"] = "Options";
var dateString = ""
for(let date of stockData[0].split("-").slice(2,5))
dateString += date + "-";
outputData["strike_date"] = dateString.slice(0,-1);
if(stockData[0].split("-")>5){
outputData["strike_price"] = stockData[0].split("-")[5];
var right = stockData[0].split("-")[6];
if(right.toUpperCase()=="PE")
outputData["right"] = "Put";
if(righttoUpperCase()=="CE")
outputData["right"] = "Call";
}
}
return outputData
}
self.getStockTokenValue = function ({exchangeCode="", stockCode="", productType="", expiryDate="", strikePrice="", right="", getExchangeQuotes=true, getMarketDepth=true}) {
if (getExchangeQuotes === false && getMarketDepth === false) {
self.subscribeException(exceptionMessage.QUOTE_DEPTH_EXCEPTION);
} else {
var exchangeCodeName = "";
var exchangeCodeList={
"BSE":"1.",
"NSE":"4.",
"NDX":"13.",
"MCX":"6.",
"NFO":"4.",
"BFO":"2.",
};
if (self.interval == "" || self.interval == null) {
exchangeCodeList["BFO"] = "8.";
}
var exchangeCodeName = exchangeCodeList[exchangeCode] || false;
if(exchangeCodeName === false) {
self.subscribeException(exceptionMessage.EXCHANGE_CODE_EXCEPTION);
}
else if(stockCode === "") {
self.subscribeException(exceptionMessage.EMPTY_STOCK_CODE_EXCEPTION);
}
else {
var tokenValue = false;
if(exchangeCode.toLowerCase() === "bse") {
var tokenValue = self.stockScriptDictList[0][stockCode] || false;
}
else if(exchangeCode.toLowerCase() === "nse"){
tokenValue = self.stockScriptDictList[1][stockCode] || false;
}
else {
if(expiryDate === "") {
self.subscribeException(exceptionMessage.EXPIRY_DATE_EXCEPTION);
}
if(productType.toLowerCase() === "futures") {
var contractDetailValue = "FUT"
}
else if(productType.toLowerCase() === "options") {
var contractDetailValue = "OPT"
}
else {
self.subscribeException(exceptionMessage.PRODUCT_TYPE_EXCEPTION);
}
contractDetailValue = contractDetailValue + "-" + stockCode + "-" + expiryDate
if(productType.toLowerCase() === "options") {
if(strikePrice !== "") {
contractDetailValue = contractDetailValue + "-" + strikePrice;
}
else if(strikePrice === "" && productType.toLowerCase() === "options") {
self.subscribeException(exceptionMessage.STRIKE_PRICE_EXCEPTION);
}
if(right.toLowerCase() === "put") {
contractDetailValue = contractDetailValue + "-" + "PE";
}
else if(right.toLowerCase() === "call") {
contractDetailValue = contractDetailValue + "-" + "CE"
}
else if(productType.toLowerCase() === "options") {
self.subscribeException(exceptionMessage.RIGHT_EXCEPTION);
}
}
if(exchangeCode.toLowerCase() === "ndx") {
tokenValue = self.stockScriptDictList[2][contractDetailValue] || false;
}
else if(exchangeCode.toLowerCase() === "mcx") {
tokenValue = self.stockScriptDictList[3][contractDetailValue] || false;
}
else if(exchangeCode.toLowerCase() === "nfo") {
tokenValue = self.stockScriptDictList[4][contractDetailValue] || false;
}
else if(exchangeCode.toLowerCase() === "bfo") {
tokenValue = self.stockScriptDictList[5][contractDetailValue] || false;
}
}
if(tokenValue === false) {
self.subscribeException(exceptionMessage.STOCK_INVALID_EXCEPTION);
}
var exchangeQuotesTokenValue = false;
if(getExchangeQuotes !== false) {
exchangeQuotesTokenValue = exchangeCodeName + "1!" + tokenValue;
}
var marketDepthTokenValue = false;
if(getMarketDepth !== false) {
marketDepthTokenValue = exchangeCodeName + "2!" + tokenValue;
}
return {"exch_quote_token":exchangeQuotesTokenValue,"market_depth_token": marketDepthTokenValue};
}
}
}
self.parseOhlcData = function(data){
let splitData = data.split(",");
let parsedData = {};
if(Boolean(["NSE","BSE"].includes(splitData[0]))){
parsedData = {
"interval":feedIntervalMap[splitData[8]],
"exchange_code":splitData[0],
"stock_code":splitData[1],
"low":splitData[2],
"high":splitData[3],
"open":splitData[4],
"close":splitData[5],
"volume":splitData[6],
"datetime":splitData[7]
}
}
else if(Boolean(["NFO","NDX","MCX","BFO"].includes(splitData[0]))){
if(splitData.length == 13){
parsedData = {
"interval":feedIntervalMap[splitData[12]],
"exchange_code":splitData[0],
"stock_code":splitData[1],
"expiry_date":splitData[2],
"strike_price":splitData[3],
"right_type":splitData[4],
"low":splitData[5],
"high":splitData[6],
"open":splitData[7],
"close":splitData[8],
"volume":splitData[9],
"oi":splitData[10],
"datetime":splitData[11]
}
}
else{
parsedData = {
"interval":feedIntervalMap[splitData[10]],
"exchange_code":splitData[0],
"stock_code":splitData[1],
"expiry_date":splitData[2],
"low":splitData[3],
"high":splitData[4],
"open":splitData[5],
"close":splitData[6],
"volume":splitData[7],
"oi":splitData[8],
"datetime":splitData[9]
}
}
}
return parsedData
}
self.parseMarketDepth = function(data, exchange){
var depth = []
var counter = 0;
for(let lis of data){
counter += 1;
dict = {};
if(exchange == '1'){
dict["BestBuyRate-"+counter.toString()] = lis[0];
dict["BestBuyQty-"+counter.toString()] = lis[1];
dict["BestSellRate-"+counter.toString()] = lis[2];
dict["BestSellQty-"+counter.toString()] = lis[3];
depth.push(dict);
}
else{
dict["BestBuyRate-"+counter.toString()] = lis[0];
dict["BestBuyQty-"+counter.toString()] = lis[1];
dict["BuyNoOfOrders-"+counter.toString()] = lis[2];
dict["BuyFlag-"+counter.toString()] = lis[3];
dict["BestSellRate-"+counter.toString()] = lis[4];
dict["BestSellQty-"+counter.toString()] = lis[5];
dict["SellNoOfOrders-"+counter.toString()] = lis[6];
dict["SellFlag-"+counter.toString()] = lis[7];
depth.push(dict);
}
}
return depth;
}
self.parseStrategyData = function(data)
{
if(data !== null && data !== undefined && data.length == 28)
{
var strategy_dict = {}
strategy_dict['strategy_date'] = data[0]
strategy_dict['modification_date'] = data[1]
strategy_dict['portfolio_id'] = data[2]
strategy_dict['call_action'] = data[3]
strategy_dict['portfolio_name'] = data[4]
strategy_dict['exchange_code'] = data[5]
strategy_dict['product_type'] = data[6]
//strategy_dict['INDEX/STOCK'] = data[7]
strategy_dict['underlying'] = data[8]
strategy_dict['expiry_date'] = data[9]
//strategy_dict['OCR_EXER_TYP'] = data[10]
strategy_dict['option_type'] = data[11]
strategy_dict['strike_price'] = data[12]
strategy_dict['action'] = data[13]
strategy_dict['recommended_price_from'] = data[14]
strategy_dict['recommended_price_to'] = data[15]
strategy_dict['minimum_lot_quantity'] = data[16]
strategy_dict['last_traded_price'] = data[17]
strategy_dict['best_bid_price'] = data[18]
strategy_dict['best_offer_price'] = data[19]
strategy_dict['last_traded_quantity'] = data[20]
strategy_dict['target_price'] = data[21]
strategy_dict['expected_profit_per_lot'] = data[22]
strategy_dict['stop_loss_price'] = data[23]
strategy_dict['expected_loss_per_lot'] = data[24]
strategy_dict['total_margin'] = data[25]
strategy_dict['leg_no'] = data[26]
strategy_dict['status'] = data[27]
return(strategy_dict)
}
if(data !== null && data !== undefined && data.length == 19){
var iclick_data = {}
//iclick_data['sequence_number'] = data[0]
iclick_data['stock_name'] = data[0]
iclick_data['stock_code'] = data[1]
iclick_data['action_type'] = data[2]
iclick_data['expiry_date'] = data[3]
iclick_data['strike_price'] = data[4]
iclick_data['option_type'] = data[5]
iclick_data['stock_description'] = data[6]
iclick_data['recommended_price_and_date'] = data[7]
iclick_data['recommended_price_from'] = data[8]
iclick_data['recommended_price_to'] = data[9]
iclick_data['recommended_date'] = data[10]
iclick_data['target_price'] = data[11]
iclick_data['sltp_price'] = data[12]
iclick_data['part_profit_percentage'] = data[13]
iclick_data['profit_price'] = data[14]
iclick_data['exit_price'] = data[15]
iclick_data['recommended_update'] = data[16]
iclick_data['iclick_status'] = data[17]
iclick_data['subscription_type'] = data[18]
return(iclick_data)
}
}
self.parseData = function(data){
if(data !== null && data !== undefined && typeof(data[0]) !== String && data[0].indexOf('!') < 0){
var order_dict = {}
order_dict["sourceNumber"] = data[0] //Source Number
order_dict["group"] = data[1] //Group
order_dict["userId"] = data[2] //User_id
order_dict["key"] = data[3] //Key
order_dict["messageLength"] = data[4] //Message Length
order_dict["requestType"] = data[5] //Request Type
order_dict["messageSequence"] = data[6] //Message Sequence
order_dict["messageDate"] = data[7] //Date
order_dict["messageTime"] = data[8] //Time
order_dict["messageCategory"] = data[9] //Message Category
order_dict["messagePriority"] = data[10] //Priority
order_dict["messageType"] = data[11] //Message Type
order_dict["orderMatchAccount"] = data[12] //Order Match Account
order_dict["orderExchangeCode"] = data[13] //Exchange Code
if(data[11] == '4' || data[11] == '5'){
order_dict["stockCode"] = data[14] //Stock Code
order_dict["orderFlow"] = self.tuxToUserValue['orderFlow'][data[15].toString().toUpperCase()] || data[15].toString() // Order Flow
order_dict["limitMarketFlag"] = self.tuxToUserValue['limitMarketFlag'][data[16].toString().toUpperCase()] || data[16].toString() //Limit Market Flag
order_dict["orderType"] = self.tuxToUserValue['orderType'][data[17].toString().toUpperCase()] || data[17].toString() //OrderType
order_dict["orderLimitRate"] = data[18] //Limit Rate
order_dict["productType"] = self.tuxToUserValue['productType'][data[19].toString().toUpperCase()] || data[19].toString() //Product Type
order_dict["orderStatus"] = self.tuxToUserValue['orderStatus'][data[20].toString().toUpperCase()] || data[20].toString() // Order Status
order_dict["orderDate"] = data[21] //Order Date
order_dict["orderTradeDate"] = data[22] //Trade Date
order_dict["orderReference"] = data[23] //Order Reference
order_dict["orderQuantity"] = data[24] //Order Quantity
order_dict["openQuantity"] = data[25] //Open Quantity
order_dict["orderExecutedQuantity"] = data[26] //Order Executed Quantity
order_dict["cancelledQuantity"] = data[27] //Cancelled Quantity
order_dict["expiredQuantity"] = data[28] //Expired Quantity
order_dict["orderDisclosedQuantity"] = data[29] // Order Disclosed Quantity
order_dict["orderStopLossTrigger"] = data[30] //Order Stop Loss Triger
order_dict["orderSquareFlag"] = data[31] //Order Square Flag
order_dict["orderAmountBlocked"] = data[32] // Order Amount Blocked
order_dict["orderPipeId"] = data[33] //Order PipeId
order_dict["channel"] = data[34] //Channel
order_dict["exchangeSegmentCode"] = data[35] //Exchange Segment Code
order_dict["exchangeSegmentSettlement"] = data[36] //Exchange Segment Settlement
order_dict["segmentDescription"] = data[37] //Segment Description
order_dict["marginSquareOffMode"] = data[38] //Margin Square Off Mode
order_dict["orderValidDate"] = data[40] //Order Valid Date
order_dict["orderMessageCharacter"] = data[41] //Order Message Character
order_dict["averageExecutedRate"] = data[42] //Average Exited Rate
order_dict["orderPriceImprovementFlag"] = data[43] //Order Price Flag
order_dict["orderMBCFlag"] = data[44] //Order MBC Flag
order_dict["orderLimitOffset"] = data[45] //Order Limit Offset
order_dict["systemPartnerCode"] = data[46] //System Partner Code
}
else if(data[11] == '6' || data[11] == '7'){
order_dict["stockCode"] = data[14] //stock code
order_dict["productType"] = self.tuxToUserValue['productType'][data[15].toString().toUpperCase()] || data[15].toString() //Product Type
order_dict["optionType"] = self.tuxToUserValue['optionType'][data[16].toString().toUpperCase()] || data[16].toString() //Option T
order_dict["exerciseType"] = data[17] //Exercise Type
order_dict["strikePrice"] = data[18] //Strike Price
order_dict["expiryDate"] = data[19] //Expiry Date
order_dict["orderValidDate"] = data[20] //Order Valid Date
order_dict["orderFlow"] = self.tuxToUserValue['orderFlow'][data[21].toString().toUpperCase()] || data[21].toString() //Order Flow
order_dict["limitMarketFlag"] = self.tuxToUserValue['limitMarketFlag'][data[22].toString().toUpperCase()] || data[22].toString() //Limit Market Flag
order_dict["orderType"] = self.tuxToUserValue['orderType'][data[23].toString().toUpperCase()] || data[23].toString() //Order Type
order_dict["limitRate"] = data[24] //Limit Rate
order_dict["orderStatus"] = self.tuxToUserValue['orderStatus'][data[25].toString().toUpperCase()] || data[25].toString() //Order Status
order_dict["orderReference"] = data[26] //Order Reference
order_dict["orderTotalQuantity"] = data[27] //Order Total Quantity
order_dict["executedQuantity"] = data[28] //Executed Quantity
order_dict["cancelledQuantity"] = data[29] //Cancelled Quantity
order_dict["expiredQuantity"] = data[30] //Expired Quantity
order_dict["stopLossTrigger"] = data[31] //Stop Loss Trigger
order_dict["specialFlag"] = data[32] //Special Flag
order_dict["pipeId"] = data[33] //PipeId
order_dict["channel"] = data[34] //Channel
order_dict["modificationOrCancelFlag"] = data[35] //Modification or Cancel Flag
order_dict["tradeDate"] = data[36] //Trade Date
order_dict["acknowledgeNumber"] = data[37] //Acknowledgement Number
order_dict["stopLossOrderReference"] = data[37] //Stop Loss Order Reference
order_dict["totalAmountBlocked"] = data[38] // Total Amount Blocked
order_dict["averageExecutedRate"] = data[39] //Average Executed Rate
order_dict["cancelFlag"] = data[40] //Cancel Flag
order_dict["squareOffMarket"] = data[41] //SquareOff Market
order_dict["quickExitFlag"] = data[42] //Quick Exit Flag
order_dict["stopValidTillDateFlag"] = data[43] //Stop Valid till Date Flag
order_dict["priceImprovementFlag"] = data[44] //Price Improvement Flag
order_dict["conversionImprovementFlag"] = data[45] //Conversion Improvement Flag
order_dict["trailUpdateCondition"] = data[45] //Trail Update Condition
order_dict["systemPartnerCode"] = data[46] //System Partner Code
}
return order_dict;
}
var exchange = data[0].split('!')[0].split('.')[0]
var dataType = data[0].split('!')[0].split('.')[1];
if(exchange == '6'){
var dataDict = {};
dataDict["Symbol"] = data[0];
dataDict["AndiOPVolume"] = data[1];
dataDict["Reserved"] = data[2];
dataDict["IndexFlag"] = data[3];
dataDict["ttq"] = data[4];
dataDict["last"] = data[5];
dataDict["ltq"] = data[6];
dataDict["ltt"] = (new Date(data[7]*1000)).toString().replace(" GMT+0530 (India Standard Time)",'');
dataDict["AvgTradedPrice"] = data[8];
dataDict["TotalBuyQnt"] = data[9];
dataDict["TotalSellQnt"] = data[10];
dataDict["ReservedStr"] = data[11];
dataDict["ClosePrice"] = data[12];
dataDict["OpenPrice"] = data[13];
dataDict["HighPrice"] = data[14];
dataDict["LowPrice"] = data[15];
dataDict["ReservedShort"] = data[16];
dataDict["CurrOpenInterest"] = data[17];
dataDict["TotalTrades"] = data[18];
dataDict["HightestPriceEver"] = data[19];
dataDict["LowestPriceEver"] = data[20];
dataDict["TotalTradedValue"] = data[21];
marketDepthIndex = 0
let i=0;
for(i=22;i<data.length;i++){
dataDict["Quantity-"+marketDepthIndex.toString()] = data[i][0]
dataDict["OrderPrice-"+marketDepthIndex.toString()] = data[i][1]
dataDict["TotalOrders-"+marketDepthIndex.toString()] = data[i][2]
dataDict["Reserved-"+marketDepthIndex.toString()] = data[i][3]
dataDict["SellQuantity-"+marketDepthIndex.toString()] = data[i][4]
dataDict["SellOrderPrice-"+marketDepthIndex.toString()] = data[i][5]
dataDict["SellTotalOrders-"+marketDepthIndex.toString()] = data[i][6]
dataDict["SellReserved-"+marketDepthIndex.toString()] = data[i][7]
marketDepthIndex += 1
}
}
else if(dataType == '1'){
var dataDict = {
"symbol": data[0],
"open": data[1],
"last": data[2],
"high": data[3],
"low": data[4],
"change": data[5],
"bPrice": data[6],
"bQty": data[7],
"sPrice": data[8],
"sQty": data[9],
"ltq": data[10],
"avgPrice": data[11],
"quotes": "Quotes Data"
}
// For NSE & BSE conversion
if(data.length == 21){
dataDict["ttq"] = data[12]
dataDict["totalBuyQt"] = data[13]
dataDict["totalSellQ"] = data[14]
dataDict["ttv"] = data[15]
dataDict["trend"] = data[16]
dataDict["lowerCktLm"] = data[17]
dataDict["upperCktLm"] = data[18]
dataDict["ltt"] = (new Date(data[19]*1000)).toString().replace(" GMT+0530 (India Standard Time)",'')
dataDict["close"] = data[20]
}
// For FONSE & CDNSE conversion
else if(data.length == 23){
dataDict["OI"] = data[12]
dataDict["CHNGOI"] = data[13]
dataDict["ttq"] = data[14]
dataDict["totalBuyQt"] = data[15]
dataDict["totalSellQ"] = data[16]
dataDict["ttv"] = data[17]
dataDict["trend"] = data[18]
dataDict["lowerCktLm"] = data[19]
dataDict["upperCktLm"] = data[20]
dataDict["ltt"] = (new Date(data[21]*1000)).toString().replace(" GMT+0530 (India Standard Time)",'')
dataDict["close"] = data[22]
}
}
else{
var dataDict = {
"symbol": data[0],
"time": (new Date(data[1]*1000)).toString().replace(" GMT+0530 (India Standard Time)",''),
"depth": self.parseMarketDepth(data[2], exchange),
"quotes": "Market Depth"
}
}
if(exchange == '4' && data.length == 21)
dataDict['exchange'] = 'NSE Equity'
else if(exchange == '1')
dataDict['exchange'] = 'BSE'
else if(exchange == '13')
dataDict['exchange'] = 'NSE Currency'
else if(exchange == '4' && data.length == 23)
dataDict['exchange'] = 'NSE Futures & Options'
else if(exchange == '6')
dataDict['exchange'] = 'Commodity'
return dataDict
}
self.getStockScriptList= async function(){
try{
self.stockScriptDictList = [{},{},{},{},{},{}]
self.tokenScriptDictList = [{},{},{},{},{},{}]
var download = await axios.get(url=urls.STOCK_SCRIPT_CSV_URL)
.then(function(resp){return resp});
var my_list = download.data.replaceAll('\r','').split('\n');
for (let row_string of my_list){
var row = row_string.split(',')
if(row[2] == "BSE"){
self.stockScriptDictList[0][row[3]]=row[5]
self.tokenScriptDictList[0][row[5]]=[row[3],row[1]]
}
else if(row[2] == "NSE"){
self.stockScriptDictList[1][row[3]]=row[5]
self.tokenScriptDictList[1][row[5]]=[row[3],row[1]]
}
else if(row[2] == "NDX"){
self.stockScriptDictList[2][row[7]]=row[5]
self.tokenScriptDictList[2][row[5]]=[row[7],row[1]]
}
else if(row[2] == "MCX"){
self.stockScriptDictList[3][row[7]]=row[5]
self.tokenScriptDictList[3][row[5]]=[row[7],row[1]]
}
else if(row[2] == "NFO"){
self.stockScriptDictList[4][row[7]]=row[5]
self.tokenScriptDictList[4][row[5]]=[row[7],row[1]]
}
else if(row[2] == "BFO"){
self.stockScriptDictList[5][row[7]]=row[5]
self.tokenScriptDictList[5][row[5]]=[row[7],row[1]]
}
}
}catch(error){
throw error.toString();
}
}
self.subscribeFeeds = async function({stockToken="", exchangeCode="", stockCode="", productType="", expiryDate="", strikePrice="", right="", getExchangeQuotes=true, getMarketDepth=true, getOrderNotification=false,interval=""}){
if(interval != ""){
if(!Boolean(typeList.INTERVAL_TYPES_STREAM_OHLC.includes(interval.toLowerCase())))
self.socketConnectionResponse(exceptionMessage.STREAM_OHLC_INTERVAL_ERROR);
else
interval = channelIntervalMap[interval];
}
if(self.socket){
var return_object = {}
if(getOrderNotification == true){
self.wsConnectOrder();
self.notify()
return_object = self.socketConnectionResponse(responseMessage.ORDER_NOTIFICATION_SUBSCRIBED)
}
if(stockToken === roomName.ONE_CLICK_ROOM || stockToken === roomName.I_CLICK_2_GAIN)
{
if(self.socketOrder == null)
{
self.connect({isOrder:true}); //for strategy streaming order socket would be used ie livefeeds.icicidirect.com
}
self.watchStrategy(stockToken);
return_object = self.socketConnectionResponse(responseMessage.ONE_CLICK_STRATEGY_SUBSCRIBED);
return return_object;
}
if(stockToken != ""){
if(interval!=""){
if(self.socketOHLCV==null){
self.connect({isOHLCV:true})
}
self.watchStreamData(stockToken,interval)
}
else
self.watch(stockToken)
return_object = self.socketConnectionResponse(responseMessage.STOCK_SUBSCRIBE_MESSAGE.format(stockToken));
}
else if(getOrderNotification == true && exchangeCode == ""){
return return_object
}
else{
var tokenDict = self.getStockTokenValue({exchangeCode:exchangeCode, stockCode:stockCode, productType:productType, expiryDate:expiryDate, strikePrice:strikePrice, right:right, getExchangeQuotes:getExchangeQuotes, getMarketDepth:getMarketDepth});
if(interval!=""){
if(self.socketOHLCV==null){
self.connect({isOHLCV:true});
}
self.watchStreamData(tokenDict["exch_quote_token"],interval);
}
else{
if(tokenDict["exch_quote_token"] != false)
self.watch(tokenDict["exch_quote_token"]);
if( tokenDict["market_depth_token"] != false)
self.watch(tokenDict["market_depth_token"]);
}
return_object = self.socketConnectionResponse(responseMessage.STOCK_SUBSCRIBE_MESSAGE.format(stockCode));
}
return return_object
}
}
self.unsubscribeFeeds = async function({stockToken="", exchangeCode="", stockCode="", productType="", expiryDate="", strikePrice="", right="", interval="",getExchangeQuotes=true, getMarketDepth=true, getOrderNotification=false}){
if(interval != ""){
if(!Boolean(typeList.INTERVAL_TYPES_STREAM_OHLC.includes(interval.toLowerCase())))
self.socketConnectionResponse(exceptionMessage.STREAM_OHLC_INTERVAL_ERROR);
else
interval = channelIntervalMap[interval];
}
if(getOrderNotification==true)
{
if(self.socketOrder)
{
self.socketOrder = null;
return self.socketConnectionResponse(responseMessage.ORDER_REFRESH_DISCONNECTED);
}
else{
return self.socketConnectionResponse(responseMessage.ORDER_REFRESH_NOT_CONNECTED);
}
}
if(stockToken === "one_click_fno")
{
if(self.socketOrder)
{
self.socketOrder.unwatchStrategy(stockToken);
}
return self.socketConnectionResponse(responseMessage.ONE_CLICK_STRATEGY_UNSUBSCRIBED);
}
else if(self.socket){
if(stockToken!=""){
if(interval!="")
self.unwatchStreamData(stockToken);
else
self.unwatch(stockToken);
return self.socketConnectionResponse(responseMessage.STOCK_UNSUBSCRIBE_MESSAGE.format(stockToken));
}
else{
var tokenDict = self.getStockTokenValue({exchangeCode:exchangeCode, stockCode:stockCode, productType:productType, expiryDate:expiryDate, strikePrice:strikePrice, right:right, getExchangeQuotes:getExchangeQuotes, getMarketDepth:getMarketDepth})
if(interval!="")
self.unwatchStreamData(stockToken["exch_quote_token"],interval);
else{
if(tokenDict["exch_quote_token"] != false)
self.unwatch(tokenDict["exch_quote_token"])
if( tokenDict["market_depth_token"] != false)
self.unwatch(tokenDict["market_depth_token"])
}
return self.socketConnectionResponse(responseMessage.STOCK_UNSUBSCRIBE_MESSAGE.format(stockCode));
}
}
}
self.generateHeaders = function(body) {
try {
var currentDate = new Date().toISOString().split(".")[0] + '.000Z';
let checksum = sha256(currentDate+JSON.stringify(body)+self.secretKey);
headers = {
"Content-Type": "application/json",
'X-Checksum': "token "+checksum,
'X-Timestamp': currentDate,
'X-AppKey': self.appKey,
'X-SessionToken': self.apiSession
}
return headers;
} catch (error) {
self.errorException("generateHeaders", error);
}
};
self.makeRequest = async function(method, endpoint, body, header) {
try {
let url = urls.API_URL + endpoint;
let res = null;
if(method === apiRequest.GET) {
res = await axios(
{
method:'get',
url:url,
data:body,
headers:header
}
).then((resp)=>{return resp})
return res;
}
else if(method === apiRequest.POST) {
res = await axios.post(url=url, data=body, {headers:header})
.then((resp)=>{return resp});
return res;
}
else if(method === apiRequest.PUT) {
res = axios.put(url=url, data=body, {headers:header})
.then((resp)=>{return resp});
return res;
}
else if(method === apiRequest.DELETE) {
res = axios.delete(url=url, data=body, {headers:header})
.then((resp)=>{return resp});
return res;
}
} catch (error) {
self.errorException(exceptionMessage.API_REQUEST_EXCEPTION.format(method,url), error);
}
};
self.getCustomerDetails = async function(session_token="") {
try {
let response = self.validationErrorResponse("");
if(session_token === "" || session_token === null) {
return self.validationErrorResponse(responseMessage.API_SESSION_ERROR);
}
headers = {
"Content-Type": "application/json"
}
body = {
"SessionToken": session_token,
"AppKey": self.appKey,
}
response = await self.makeRequest(apiRequest.GET, apiEndpoint.CUST_DETAILS, body, headers);
delete response.data['Success']['session_token'];
return(response.data);
} catch (error) {
self.errorException("getCustomerDetails", error);
}
};
self.getDematHoldings = async function() {
try {
let body = {}
headers = self.generateHeaders(body);
let response = await self.makeRequest(apiRequest.GET, apiEndpoint.DEMAT_HOLDING, body, headers);
return response.data;
} catch (error) {
self.errorException("getDematHoldings", error);
}
};
self.getFunds = async function() {
try {
let body = {}
headers = self.generateHeaders(body);
let response = await self.makeRequest(apiRequest.GET, apiEndpoint.FUND, body, headers);
return response.data;
} catch (error) {
self.errorException("getFunds", error);
}
};
self.setFunds = async function({transactionType="", amount="", segment=""}) {
try {
if(transactionType === "" || transactionType === null || amount === "" || amount === null || segment === "" || segment === null) {
if(transactionType === "" || transactionType === null) {
return self.validationErrorResponse(responseMessage.BLANK_TRANSACTION_TYPE);
}
else if(amount === "" || amount === null) {
return self.validationErrorResponse(responseMessage.BLANK_AMOUNT);
}
else if(segment === "" || segment === null) {
return self.validationErrorResponse(responseMessage.BLANK_SEGMENT);
}
}
else if(transactionType.toLowerCase() !=="debit" && transactionType.toLowerCase() !== "credit") {
return self.validationErrorResponse(responseMessage.TRANSACTION_TYPE_ERROR);
}
else if(parseInt(amount) <= 0) {
return self.validationErrorResponse(responseMessage.ZERO_AMOUNT_ERROR);
}
let body = {
"transaction_type": transactionType,
"amount": amount,
"segment": segment
}
let headers = self.generateHeaders(body);
let response = await self.makeRequest(apiRequest.POST, apiEndpoint.FUND, body, headers);
return response.data;
} catch (error) {
self.errorException("setFunds", error);
}
};
self.getHistoricalData = async function({interval="", fromDate="", toDate="", stockCode="", exchangeCode="", productType="", expiryDate="", right="", strikePrice=""}) {
try {
if(interval === "" || interval === null) {
return self.validationErrorResponse(responseMessage.BLANK_INTERVAL);
}
else if(!Boolean(typeList.INTERVAL_TYPES.includes(interval.toLowerCase()))) {
return self.validationErrorResponse(responseMessage.INTERVAL_TYPE_ERROR);
}
else if(exchangeCode === "" || exchangeCode === null) {
return self.validationErrorResponse(responseMessage.BLANK_EXCHANGE_CODE);
}
else if(exchangeCode.toLowerCase() !== "nse" && exchangeCode.toLowerCase() !== "nfo" && exchangeCode.toLowerCase() !== "bse") {
return self.validationErrorResponse(responseMessage.EXCHANGE_CODE_ERROR);
}
else if(fromDate === "" || fromDate === null) {
return self.validationErrorResponse(responseMessage.BLANK_FROM_DATE);
}
else if(toDate === "" || toDate === null) {
return self.validationErrorResponse(responseMessage.BLANK_TO_DATE);
}
else if(stockCode === "" || stockCode === null) {
return self.validationErrorResponse(responseMessage.BLANK_STOCK_CODE);
}
else if(exchangeCode.toLowerCase() === "nfo") {
if(productType === "" || productType === null) {
return self.validationErrorResponse(responseMessage.BLANK_PRODUCT_TYPE_NFO);
}
else if(!Boolean(typeList.PRODUCT_TYPES_HIST.includes(productType.toLowerCase()))) {
return self.validationErrorResponse(responseMessage.PRODUCT_TYPE_ERROR);
}
else if(productType.toLowerCase() === "options" && (strikePrice === "" || strikePrice === null)) {
return self.validationErrorResponse(responseMessage.BLANK_STRIKE_PRICE);
}
else if(expiryDate === "" || expiryDate === null) {
return self.validationErrorResponse(responseMessage.BLANK_EXPIRY_DATE);
}
}
if(interval === "1minute") {
interval = "minute";
}
else if(interval === "1day") {
interval = "day";
}
let body = {
"interval": interval,
"from_date": fromDate,
"to_date": toDate,
"stock_code": stockCode,
"exchange_code": exchangeCode
}
if(productType !==