Yes @rakeshr - Is this not correct? How should I go about it?
No, you shouldn't be putting any logic inside on_tick thread.You need to pass on the tick on another method asynchronically without blocking on_tick thread.You can look to this thread for examples.
@mnabhishek There are two ways to pass tick data from on_tick thread to perform any operation without blocking the main on_ticks thread. 1> You can push tick data to Queue(use celery,rq,etc) as task queue manager and have another method that reads these Queue data and perform the tasks. eg:
def on_ticks(ws,ticks): #Pass the tick data to Queue using celery,rq,etc #Using celery delay method here to call helper_method task helper_method.delay(ticks)
def helper_method(ticks): #Perform require operation using tick data
2>Create another thread and perform the required operation in the daemon or main thread. Daemon thread can be created by setting threaded=True mode while establishing a websocket connection. In order to keep the daemon thread running, you need to keep the main thread alive, so you will have to block the main thread somehow. We have used here the While loop as a representation. You can try anything from static sleep to threading wait event loop to block the main thread. P.S: Don't forget to assign ticker callback.
@rakeshr I have tried your above sugggested logic to offload on_ticks and my new code looks like below. my issue here is, the lines after "while True:" are not getting executed.
you may also note there is a compiler error for repeating the " def on_ticks(ws, ticks):" line. my main thread is given below for your reference.
could you please look in to this and advise me what is wrong in my code? I am really stuck at this point on my journey of learning and desperately need help
lines after "while True:" are not getting executed.
You are assigning ticker call back kws.on_ticks=on_ticks out side the while loop scope. It should be inside the while loop scope. Eg:
while True: ...... ticker methods ..... #It should be within the scope of while loop (correct) kws.on_ticks=on_ticks #You are assigning it here,outside the scope(incorrect) kws.on_ticks=on_ticks
@rakeshr I have tried your suggestion, and the call back is working perfectly fine when i have changed the indent of "kws.on_ticks=on_ticks". My updated code looks like below
while True: def on_ticks(ws, ticks): feed_data(ticks) print("i am from while True -> on ticks: feed_data module called!")
def feed_data(ticks): for tick in ticks: token = tick['instrument_token'] row = trd_portfolio[token]['row'] sht.range('C'+str(row)).value = tick['last_price'] sht.range('D'+str(row)).value = tick['ohlc']['open'] sht.range('E'+str(row)).value = tick['ohlc']['high'] sht.range('F'+str(row)).value = tick['ohlc']['low'] sht.range('G'+str(row)).value = tick['ohlc']['close'] sht.range('H'+str(row)).value = tick['volume'] sht.range('I'+str(row)).value = datetime.datetime.now() print(datetime.datetime.now()) print("i am from -> feed_data function")
print("i am from main -> after kws.connect(threaded=True)") kws.on_ticks=on_ticks
How ever the purpose is still not served here, it is not calling the on_ticks(ws, ticks): function under while loop, instead, only below two lines under the while loop are getting executed. print("i am from main -> after kws.connect(threaded=True)") kws.on_ticks=on_ticks
could you please suggest the required changes in my code to trigger on_ticks(ws, ticks) function under while loop, else some logic to pass the ticks data to my "feed_data(ticks)" function.. would also work here
Thanks a lot for your patience and time to support me.
hello @rakeshr, please be kind enough to provide me a solution, I am stuck at this point and need your help. continuously print("i am from main -> after kws.connect(threaded=True)") line is getting printed but excel sheet is not updating. (i suspect the on_ticks(ws, ticks): line inside while loop is not triggering)
@renjitharajan84, Kite Connect is purely an execution platform. We don't provide support or assistance for writing code or strategies. It is outside the scope of this forum.
If someone is willing they will answer if they are not willing to do so please don't force them. You can hire someone as well, there are many freelancers on the forum who write strategies.
My apologies if you have mistaken my humble request to @rakeshr as a compulsion/forcing, I am very well aware that was a voluntary act from rakeshr and was trying to help me. I have approached him again only because, that was his code suggestions and getting unexpected results when tried.
Also I could see from other threads that he has been very supportive and willing to help beginners always.
@renjitharajan84 Your code looks correct. on_ticks ticker method should be called properly. But,we feel as it's continous while loop print("i am from main -> after kws.connect(threaded=True)") is printed much more times than print statement inside on_ticks, and feed_data methods. So, you can try removing all print statement outside of above two methods and then check. Something like below:
while True: def on_ticks(ws, ticks): feed_data(ticks) print("i am from while True -> on ticks: feed_data module called!")
def feed_data(ticks): ...... Computaion ..... print(datetime.datetime.now()) print("i am from -> feed_data function") #comment out or remove any print statement outside of above two methods #print("i am from main -> after kws.connect(threaded=True)") kws.on_ticks=on_ticks
@rakeshr you were right, the on_ticks(ws, ticks) function inside while loop was perfectly triggering. thank you so much for the patience & support once again.
@rakeshr, I am able to stream the data now flawlessly with some minor errors, that I can handle alone. my main hurdle was to handle the overload of on_ticks event.
#get dump of all NSE instruments instrument_dump = kite.instruments("MCX") instrument_df = pd.DataFrame(instrument_dump)
def tokenLookup(instrument_df,symbol_list): ###looks up instrument token for a given script from instrument dump### token_list = [] for symbol in symbol_list: token_list.append(int(instrument_df[instrument_df.tradingsymbol==symbol].instrument_token.values[0])) return token_list
def on_connect(ws,response): # Callback on successful connect. # Subscribe to a list of instrument_tokens (RELIANCE and ACC here). ws.subscribe(tokens) ws.set_mode(ws.MODE_QUOTE,[tokens[0]])
Are you placing order inside on_tick method?
Some pointers will be really helpful.
I hope such a structure is fine.
def on_ticks(ws, ticks):
calculation(ticks)
There are two ways to pass tick data from on_tick thread to perform any operation without blocking the main on_ticks thread.
1> You can push tick data to Queue(use celery,rq,etc) as task queue manager and have another method that reads these Queue data and perform the tasks.
eg: 2>Create another thread and perform the required operation in the daemon or main thread. Daemon thread can be created by setting
threaded=True
mode while establishing a websocket connection. In order to keep the daemon thread running, you need to keep the main thread alive, so you will have to block the main thread somehow. We have used here the While loop as a representation. You can try anything from static sleep to threading wait event loop to block the main thread.P.S: Don't forget to assign ticker callback.
you may also note there is a compiler error for repeating the " def on_ticks(ws, ticks):" line. my main thread is given below for your reference.
could you please look in to this and advise me what is wrong in my code? I am really stuck at this point on my journey of learning and desperately need help
Thanks.
kws.on_ticks=on_ticks
out side thewhile
loop scope. It should be inside thewhile
loop scope.Eg:
"kws.on_ticks=on_ticks"
. My updated code looks like below How ever the purpose is still not served here, it is not calling theon_ticks(ws, ticks):
function underwhile loop
, instead, only below two lines under thewhile loop
are getting executed.print("i am from main -> after kws.connect(threaded=True)")
kws.on_ticks=on_ticks
could you please suggest the required changes in my code to trigger
on_ticks(ws, ticks)
function underwhile loop
, else some logic to pass the ticks data to my "feed_data(ticks)
" function.. would also work hereThanks a lot for your patience and time to support me.
Regards,
ACR
print("i am from main -> after kws.connect(threaded=True)")
line is getting printed but excel sheet is not updating. (i suspect theon_ticks(ws, ticks):
line insidewhile loop
is not triggering)Kite Connect is purely an execution platform. We don't provide support or assistance for writing code or strategies. It is outside the scope of this forum.
If someone is willing they will answer if they are not willing to do so please don't force them. You can hire someone as well, there are many freelancers on the forum who write strategies.
My apologies if you have mistaken my humble request to @rakeshr as a compulsion/forcing, I am very well aware that was a voluntary act from rakeshr and was trying to help me. I have approached him again only because, that was his code suggestions and getting unexpected results when tried.
Also I could see from other threads that he has been very supportive and willing to help beginners always.
Thanks.
Your code looks correct.
on_ticks
ticker method should be called properly. But,we feel as it's continous while loopprint("i am from main -> after kws.connect(threaded=True)")
is printed much more times than print statement insideon_ticks
, andfeed_data
methods. So, you can try removing all print statement outside of above two methods and then check. Something like below:on_ticks(ws, ticks) function inside while loop
was perfectly triggering. thank you so much for the patience & support once again.on_ticks
event.Connection closed: 1006 - connection was closed uncleanly (WebSocket connection upgrade failed (403 - Forbidden))
May be can you paste complete WebSocket code? we will take look at it.
from kiteconnect import KiteConnect
from kiteconnect import KiteTicker
import pandas as pd
import datetime
import pdb
kws = ""
kite = ""
api_k = "" # api_key
api_s = "" # api_secret
def get_login(api_k, api_s): # log in to zerodha API panel
global kws, kite
kite = KiteConnect(api_key=api_k)
print("[*] Generate access Token : ", kite.login_url())
request_tkn = input("[*] Enter Your Request Token Here : ")
data = kite.generate_session(request_tkn, api_secret=api_s)
kite.set_access_token(data["access_token"])
kws = KiteTicker(api_k, data["access_token"])
print(data['access_token'])
get_login(api_k, api_s)
#using the below to stream live ticks
from kiteconnect import KiteConnect
from kiteconnect import KiteTicker
import logging
import datetime as dt
import pandas as pd
#generate kite session
api_key = ""
api_secret = ""
#request_token = ""
access_token = ""
kite = KiteConnect(api_key=api_key)
#data = kite.generate_session( request_token, api_secret=api_secret)
kite.set_access_token(access_token)
#get dump of all NSE instruments
instrument_dump = kite.instruments("MCX")
instrument_df = pd.DataFrame(instrument_dump)
def tokenLookup(instrument_df,symbol_list):
###looks up instrument token for a given script from instrument dump###
token_list = []
for symbol in symbol_list:
token_list.append(int(instrument_df[instrument_df.tradingsymbol==symbol].instrument_token.values[0]))
return token_list
tickers= ["CRUDEOIL20JULFUT"]
#create KiteTicker object
kws = KiteTicker(api_secret,access_token)
tokens=tokenLookup(instrument_df,tickers)
def on_ticks(ws, ticks):
# Callback to receive ticks.
#logging.debug("Ticks: {}".format(ticks))
print(ticks)
def on_connect(ws,response):
# Callback on successful connect.
# Subscribe to a list of instrument_tokens (RELIANCE and ACC here).
ws.subscribe(tokens)
ws.set_mode(ws.MODE_QUOTE,[tokens[0]])
# Assign the callbacks.
kws.on_ticks = on_ticks
kws.on_connect = on_connect
kws.connect()
kws
instance assignment seems to be wrong. Instead ofapi_secret
, it should beapi_key
. Check Websocket example here.