Convert Tick Data to OHLC in Realtime with Python Pandas? - python

I know how to convert static Tick data to OHLC Candlestick data using resampling with Pandas Module of Python.
But how can I do this in Realtime (Just like a Websocket sends it)?
Let's say I am using this while loop code to prepare Tick Data
import time, requests
ohlc []
while True:
r = requests.get('https://api1.binance.com/api/v3/ticker/price?symbol=ETHUSDT')
resp_dict = r.json()
time.time()
print({'time' : time.time(), 'price' : resp_dict["price"]})
Now, how can I keep resample this data in Realtime with Pandas (Just like a Websocket keeps sending us this OHLC data every second which makes it possible to plot candlestick data in realtime)?
Thanks in Advance

I mean, unless you wanna deploy a data provider business it's all cool to make a standalone autonomous bot.
In realtime you gotta actually aggregate OHLC bars live.
Ticks(trades) via WebSocket (or another streaming API); ->
Queue to hold dem ticks; ->
logic to take em ticks from the queue, send em to an aggregator logic and pop em out of the queue so we won't accidentally process one tick several times; ->
Logic to aggregate OHLCV live;
Logic to tell when to start constructing a new bar.
FTX exchange & Python, 15 sec chart aggregation. FTX has an "official" WebSocket Client, I modified it to process all the ticks correctly;
def _handle_trades_message(self, message: Dict) -> None:
self._trades[message['market']].extend(reversed(message['data']))
After that, that's what I got:
import ftx
import time
import pandas as pd
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime
def process_tick(tick):
global data
global flag
global frontier
if (flag == True) and (tick['time'] >= frontier):
start_time = datetime.utcnow().isoformat() #"almost"
time_ = time.time() * 1000 # with higher precision
op = tick['price']
hi = tick['price']
lo = tick['price']
cl = tick['price']
vol = tick['size' ]
row = {'startTime' : start_time,
'time' : time_ ,
'open' : op ,
'high' : hi ,
'low' : lo ,
'close' : cl ,
'volume' : vol }
data = data.append(row, True)
flag = False
print('Opened')
print(tick)
else:
if (tick['price'] > data['high'].iloc[-1]):
data['high'].iloc[-1] = tick['price']
elif (tick['price'] < data['low' ].iloc[-1]):
data['low' ].iloc[-1] = tick['price']
data['close' ].iloc[-1] = tick['price']
data['volume'].iloc[-1] += tick['size' ]
print(tick)
def on_tick():
while True:
try:
try:
process_tick(trades[-1])
trades.pop()
except IndexError:
pass
time.sleep(0.001)
except KeyboardInterrupt:
client_ws._reset_data()
scheduler.remove_job('onClose')
scheduler.shutdown()
print('Shutdown')
break
def on_close():
global flag
global frontier
flag = True
frontier = pd.Timestamp.utcnow().floor('15S').isoformat() #floor to 15 secs
print('Closed')
ASSET = 'LTC-PERP'
RES = '15'
flag = True
frontier = pd.Timestamp.utcnow().floor('15S').isoformat() #floor to 15 secs
cols = ['startTime', 'time', 'open', 'high', 'low', 'close', 'volume']
data = pd.DataFrame(columns=cols)
client_ws = ftx.FtxClientWs()
client_ws._subscribe({'channel': 'trades', 'market': ASSET})
trades = client_ws._trades[ASSET]
scheduler = BackgroundScheduler()
scheduler.configure(timezone='utc')
scheduler.add_job(on_close, trigger='cron', second='0, 15, 30, 45', id='onClose')
scheduler.start()
on_tick()
On top of my stuff, just make on_tick() run in its own thread, data variable will be constantly updated in the background and hold the OHLCV, so you'll be able to use this data within the same program.

Related

I want build a alert for ema indicator crypto in a special list

First one:
### configuration details
TELEGRAM_TOKEN = '' # telegram bot token
TELEGRAM_CHANNEL ='' # channel id
INTERVAL = '1m' # binance time interval
SHORT_EMA = 7 # short interval for ema
LONG_EMA = 21 # long interval for ema
Here is my second code:
import requests
import talib
import time
import numpy as np
import websocket
from config import TELEGRAM_TOKEN, TELEGRAM_CHANNEL , INTERVAL, SHORT_EMA , LONG_EMA
def streamKline(currency, interval):
websocket.enableTrace(False)
socket = f'wss://stream.binance.com:9443/ws/{currency}#kline_{interval}'
ws = websocket.WebSocketApp(socket)
ws.run_forever()
#SYMBOLS TO LOOK FOR ALERTS
SYMBOLS = [
"ETHUSDT",
"BTCUSDT",
"ATOMUSDT",
"BNBUSDT",
"FTMBUSD",
"ENJUSDT",
"WAXPUSDT"
]
#sending alerts to telegram
def send_message(message):
url = "https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=markdown".format(TELEGRAM_TOKEN,TELEGRAM_CHANNEL,message)
res = requests.get(url);print(url);
return res
# getting klines data to process
def streamKline(symbol):
data = socket.streamKline(symbol=symbol,interval=INTERVAL,limit=300) # more data means more precision but at the trade off between speed and time
return_data = []
# taking closing data for each kline
for each in data:
return_data.append(float(each[4])) # 4 is the index of the closing data in each kline
return np.array(return_data) # returning as numpy array for better precision and performance
def main():
# making a infinite loop that keeps checking for condition
while True:
#looping through each coin
for each in SYMBOLS:
data = streamKline(each)
ema_short = talib.EMA(data,int(SHORT_EMA))
ema_long = talib.EMA(data,int(LONG_EMA))
last_ema_short = ema_short[-2]
last_ema_long = ema_long[-2]
ema_short = ema_short[-1]
ema_long = ema_long[-1]
# conditions for alerts
if(ema_short > ema_long and last_ema_short < last_ema_long):
message = each + "bullcoming "+ str(SHORT_EMA) + " over "+str(LONG_EMA);print(each ,"alert came");
send_message(message);
time.sleep(0.5);
# calling the function
if __name__ == "__main__":
main()
The part of config is all settle done, just second for the kline data, the error mention lot like this.
data = socket.streamKline(symbol=symbol,interval=INTERVAL,limit=300) # more data means more precision but at the
trade off between speed and time
NameError: name 'socket' is not defined
I just don't know how to do it, I want build a ema alert that can give me a message when I am not watching chart, through this way seems not work, I have tried many times, and also find many video but still, I am just an beginner, nothing improving at all.

How can i create a live chart with the help of Live streaming data?

I'm receiving live streaming data from the kite every second, and now I want to create a Chart with the help of that data.
Any Chart can work, I don't need any specific chart type. but I don't understand how can I create a chart which is automatically changing every second.
I want that chart to change like the stock market chart changes every second.
I'm getting this type of values data in each second.
And This is my code-
from kiteconnect import KiteConnect
import time
from kiteconnect import KiteTicker
kws = KiteTicker(zerodha_api_key,acc_tkn)
tokens=[ 60702215, 60700167, 60701191]
# dict={9410818:'BANKNIFTY22MAR27000CE',9411074:'BANKNIFTY22MAR27000PE'}
def on_ticks(ws, ticks):
ticks = (ticks)
bid_price_1 = ticks[0]['depth']['buy'][0]['price']
ask_price_1 = ticks[1]['depth']['sell'][0]['price']
combination_1 = bid_price_1 - ask_price_1
print(combination_1)
def on_connect(ws, response):
ws.subscribe(tokens)
ws.set_mode(ws.MODE_FULL,tokens)
kws.on_ticks = on_ticks
kws.on_connect = on_connect
kws.connect(threaded=True)
count=0
while True:
count+=1
if(count%2==0):
if kws.is_connected():
kws.set_mode(kws.MODE_FULL,tokens)
else:
if kws.is_connected():
kws.set_mode(kws.MODE_FULL,tokens)
time.sleep(1)

Bloomberg API FX Forwards NDFs not returning prices

Please can anyone advise how I may retrieve FX Forwards NDF's outright bid / outright ask or indeed any price data for USD/KRW for the 1W, 1M, 3M etc tenors.
I have attempted to follow the DAPI instructions as well as attempting to find answers via Stackoverflow to no avail. I can however succesfully retrieve live bid asks for SPOT USD KRW or even Equities such as AAPL no problem
I have tried using different combinations of the tickers, although I see no error codes no actual live prices come back? Please does anyone have any ideas to get live ticking NDF outright prices:
Any & all help is greatly appreciated :) as Bloomberg seemingly don't provide any assistance
['USD/KRW N 2M Curncy'], ['USD/KRW N 3M Curncy'] , ['USD/KRW N 3M ICAP Curncy']
p.s the Excel Bloomberg formula such as =BFxForward("USDKRW","3M","BidOutright") is essentially what I'm trying to replicate via python, attempting to follow the DAPI instructions seems to not work.
I have used the C++ BLPAPI pdf examples to attempt to get this working however no NDF examples seemingly exist.
def main_subscribe():
tickers = ['USD/KRW N 2M Curncy', 'USD/KRW N 6M Curncy', 'USD/KRW N 9M Curncy']
fields = ['BID', 'LAST_BID_TIME_TODAY_REALTIME', 'ASK','MID']
interval = 2
options = parseCmdLine()
# Fill SessionOptions
sessionOptions = blpapi.SessionOptions()
sessionOptions.setServerHost(options.host)
sessionOptions.setServerPort(options.port)
print("Connecting to %s:%s" % (options.host, options.port))
# Create a Session
session = blpapi.Session(sessionOptions)
# Start a Session
if not session.start():
print("Failed to start session.")
return
try:
# Open service to get subscription data from
if not session.openService('//blp/mktdata'):
print("Failed to open '//blp/mktdata")
return
# init subscriptions
subs = blpapi.SubscriptionList()
flds = ','.join(fields)
istr = interval and 'interval=%.1f' % interval or ''
for ticker in tickers:
subs.add(ticker, flds, istr, blpapi.CorrelationId(ticker))
session.subscribe(subs)
# Process received events
while(True):
# We provide timeout to give the chance for Ctrl+C handling:
ev = session.nextEvent(900)
for msg in ev:
print(msg)
# if ev.eventType() == blpapi.Event.SUBSCRIPTION_DATA:
# try:
# for msg in ev:
# #print(msg)
# print(f"{fields[0]}:{msg.getElementAsString(fields[0])} , {fields[3]}:{msg.getElementAsString(fields[3])} , {fields[2]}:{msg.getElementAsString(fields[2])} , {fields[1]}:{msg.getElementAsString(fields[1])}")
# except Exception as e:
# print(e)
# #print(msg)
# None
finally:
# Stop the session
session.stop()
This is the output when main-subscribe is run:
CID: {[ valueType=POINTER classId=0 value=0000024DBF510CB0 ]}
RequestId: -----------------------------
MarketDataEvents = {
MKTDATA_EVENT_TYPE = SUMMARY
MKTDATA_EVENT_SUBTYPE = INITPAINT
API_RULES_VERSION = 201411210
SIMP_LAST_PX_ALL_SESS_DIR_RT = 1
SMART_FIELDS_METADATA_VERSION_RT = "21.10.08.02 "
IS_DELAYED_STREAM = false
MID = 1.000000
RT_API_MACHINE = "apipubx0#----------"
RT_YLD_CHG_NET_1D = 0.000000
IND_BID_FLAG = false
IND_ASK_FLAG = false
BASE_PRICE_ENABLED_RT = false
EVT_DELTA_TIMES_RT = 0
ALL_PRICE_COND_CODE = ""}
This is the KRW <Curncy> FRD <Go> screen in the Bloomi Terminal:
If you hover the mouse over the 3M outright Bid (in the circle), the pop-up shows the underlying ticker to be KWN+3M BGN Curncy.
When I put this ticker in Excel as:
=BDP("KWN+3M BGN Curncy","BID","UpdateFrequency",500) then I get updating bid side pricing which matches the Terminal screen.
Since the underlying DAPI for Excel and Python is the same, I would guess that this ticker will work with the blpapi too. I usually find it is quicker to test tickers and fields in Excel.

Why is the ATR Indicator of TA-Lib not working?

I'm having some problems using the ATR-Indicator in the TA-Lib library. Every other indicator seems to work just fine.
Here's the code in python:
import json
import numpy
import talib
import websocket
# *******PARAMETERS
# Name of Socket for BTC in USDT 1min Candle
SOCKET = "wss://stream.binance.com:9443/ws/btcusdt#kline_1m"
# Arrays
closes = []
highs = []
lows = []
# ***Websocket definition***
def on_open_ws(ws):
print('opened connection')
def on_close_ws(ws):
print('closed connection')
def on_message_ws(ws, message):
json_message = json.loads(message)
# only watching the candle infos in received message
candle = json_message['k']
# getting close, high and low values
is_candle_closed = candle['x']
close = float(candle['c'])
high = float(candle['h'])
low = float(candle['l'])
if is_candle_closed:
closes.append(close) # add close price to closes-array
np_closes = numpy.array(closes) # convert closes-array in numpy
c_close = np_closes[-1] # current close
p_close = np_closes[-2] # previous close
print(len(closes))
highs.append(high)
np_highs = numpy.array(highs)
last_high = np_highs[-1]
lows.append(low)
np_lows = numpy.array(lows)
last_low = np_lows[-1]
# Set ATR
atr = talib.ATR(np_highs, np_lows, np_closes, timeperiod=14)
last_atr = atr[-1]
print('last atr')
print(last_atr)
ws = websocket.WebSocketApp(SOCKET, on_open=on_open_ws, on_close=on_close_ws, on_message=on_message_ws)
# Run websocket app
ws.run_forever()
The last commands "print('last atr') and print(last_atr) do not print, suggesting that the atr isnt working.
Does somehow have any idea what could be the problem?
I tried using just the last values of high, low and close as well as the non-numpied values, but this doesn't change anything. I'm not even getting the "nan" answer for the first few values...
Your first call of on_message_ws() with is_candle_closed == true crashes at line p_close = np_closes[-2] # previous close as there is only 1 element in closes yet.
After this crash the next call of on_message_ws() with is_candle_closed == true will continue with len(closes) == 2 and len(lows) == len(highs) == 1 and then crash at talib.ATR() with Exception: input array lengths are different.
And so on.
P.S. I would also suggest to use numpy.array(closes, dtype='double') instead of numpy.array(closes) as talib.ATR() is able to crash with Exception: input array type is not double. That's not happening with current data received from binance, but just to be safe I would ensure the arrays are converted to double.
So i solved my problem by coding my own ATR, which was a much easier solution then i thought. If it can help anyone heres the code
def true_range(high, low, p_close):
high_low = high - low
high_close = numpy.abs(high - p_close)
low_close = numpy.abs(low - p_close)
trange = max(high_low, high_close, low_close)
return trange
# Set TR
last_tr = true_range(last_high, last_low, p_close)
tr.append(last_tr)
if len(tr) > ATR_PERIOD:
del tr[0]
# Set ATR (SMA smoothing but need RMA)
atr = sum(tr) / ATR_PERIOD
print('atr ', atr)
ATR_PERIOD is the period you want to set.
For the length of ATR_PERIOD you will obviously get wrong numbers, but afterwards you should be fine

Alice blue api module problem with Strategy Creation

from alice_blue import *
import pdb
import datetime
import time
import pandas as pd
access_token = '1JekMg.ezoSy4HW8rn3zjUzpRWR2fA2P9c6yQLjGWHdnCvXtOs'
alice = AliceBlue(username='', password='', access_token= '5ENG1JekMg.ezoSy4HW8rn3zjUzpRWR2fA2P9c6yQLjGWHdnCvXtOs', master_contracts_to_download=['NSE', 'NFO'])
traded_stocks = []
socket_opened = False
def event_handler_quote_update(message):
print(f"quote update {message}")
name = message['instrument'].symbol
openx = message['open']
high = message['high']
low = message['low']
close = message['close']
ltp = message['ltp']
cap = 100000
curr_time=datetime.datetime.now()
crt_time=curr_time.time()
breakout=datetime.time(18, 30)
if (crt_time >= breakout) and (name not in traded_stocks) and (ltp >= high):
print(f"buy: {name} , ltp: {ltp}")
traded_stocks.append(name)
message = alice.place_order(transaction_type = TransactionType.Buy, instrument = alice.get_instrument_by_symbol('NSE', name), quantity = 1 , order_type = OrderType.Limit, product_type = ProductType.BracketOrder, price = high, trigger_price = None, stop_loss =low, square_off =float(format((high-low), ".1f")), trailing_sl = None, is_amo = False)
sleep(10)
else :
print(f"time not satisfied is {curr_time}")
def open_callback():
global socket_opened
socket_opened = True
alice.start_websocket(subscribe_callback=event_handler_quote_update,
socket_open_callback=open_callback,
run_in_background=True)
while(socket_opened==False):
pass
instrument = [alice.get_instrument_by_symbol('NSE', 'ICICIBANK')]
while True:
alice.subscribe(instrument, LiveFeedType.MARKET_DATA)
Im trying to code a Open Range Breakout Strategy with this alice(https://pypi.org/project/alice-blue/)
But i cant breakthrough what concept to use
Can anyone Suggest a CODE based on provided link to alice-blue data and code please
I tried of placing order on specific time alone but the code runs and fires orders continously
Want a Suggestion with Function and the Order must be placed only once for a certain script
Step 1: Create a cron job at 9:30 AM and Store the Highest Price in DB.
Step 2: Create another cron job for every 15 mins --> Compare LTP > High
Step 3: If the condition is true --> Place an order and store the order ID & instrument
Step 4: Create one more cron job for exit signal --> compare with Target or SL price ---> Place Exit Order

Categories