bugfix a zakomentovan IC a podporen format f

This commit is contained in:
David Brazda
2023-04-23 21:21:06 +02:00
parent 83a7bb77da
commit 541aaa4ab8
25 changed files with 185 additions and 175 deletions

6
testy/fformat.py Normal file
View File

@ -0,0 +1,6 @@
d= 1
a = f"neco {d=} a nebo takhle {float(d)}"
print(a)

View File

@ -56,14 +56,14 @@ for day in cal_dates:
#odesíláme do queue #odesíláme do queue
#jinak pass #jinak pass
else: else:
ic("cache not exists") ##"cache not exists")
#denni file není - loadujeme den z Alpacy #denni file není - loadujeme den z Alpacy
#ukládáme do cache s daily_file jako název #ukládáme do cache s daily_file jako název
#pokud jde o dnešní den a nebyl konec trhu tak cache neukládáme #pokud jde o dnešní den a nebyl konec trhu tak cache neukládáme
if datetime.now() < day.close: if datetime.now() < day.close:
print("not saving the cache, market still open today") print("not saving the cache, market still open today")
ic(datetime.now()) #ic(datetime.now())
ic(day.close) #ic(day.close)
else: else:
pass pass
#save to daily cache file curr_dir+'/'+daily_file #save to daily cache file curr_dir+'/'+daily_file

View File

@ -16,10 +16,10 @@ Simple strategie pro test backtesting
def next(data, state: StrategyState): def next(data, state: StrategyState):
print(10*"*","NEXT START",10*"*") print(10*"*","NEXT START",10*"*")
ic(state.avgp, state.positions) #ic(state.avgp, state.positions)
ic(state.vars.limitka) #ic(state.vars.limitka)
ic(state.vars.lastbuyindex) #ic(state.vars.lastbuyindex)
ic(data) #ic(data)
#print("last trade price") #print("last trade price")
#print(state.interface.get_last_price("BAC")) #print(state.interface.get_last_price("BAC"))
#print(state.vars.novaprom) #print(state.vars.novaprom)
@ -35,7 +35,7 @@ def next(data, state: StrategyState):
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne #trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema] state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:]) #ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
except Exception as e: except Exception as e:
print("No data for MA yet", str(e)) print("No data for MA yet", str(e))
@ -57,8 +57,8 @@ def next(data, state: StrategyState):
if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0 if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0
print("BUY MARKET") print("BUY MARKET")
ic(data['updated']) #ic(data['updated'])
ic(state.time) #ic(state.time)
state.buy_l() state.buy_l()

View File

@ -32,10 +32,10 @@ stratvars = AttributeDict(maxpozic = 250,
def next(data, state: StrategyState): def next(data, state: StrategyState):
print(10*"*","NEXT START",10*"*") print(10*"*","NEXT START",10*"*")
ic(state.avgp, state.positions) #ic(state.avgp, state.positions)
ic(state.vars.limitka) #ic(state.vars.limitka)
ic(state.vars.lastbuyindex) #ic(state.vars.lastbuyindex)
ic(data) #ic(data)
#print("last trade price") #print("last trade price")
#print(state.interface.get_last_price("BAC")) #print(state.interface.get_last_price("BAC"))
#print(state.vars.novaprom) #print(state.vars.novaprom)
@ -51,7 +51,7 @@ def next(data, state: StrategyState):
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne #trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema] state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:]) #ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
except Exception as e: except Exception as e:
print("No data for MA yet", str(e)) print("No data for MA yet", str(e))
@ -65,8 +65,8 @@ def next(data, state: StrategyState):
#proto dodělat LTP pro BT, neco jako get_last_price(self.state.time) #proto dodělat LTP pro BT, neco jako get_last_price(self.state.time)
if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0 if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0
print("BUY MARKET") print("BUY MARKET")
ic(data['updated']) #ic(data['updated'])
ic(state.time) #ic(state.time)
state.buy_l() state.buy_l()

View File

@ -89,9 +89,9 @@ exthours=false
def next(data, state: StrategyState): def next(data, state: StrategyState):
print(10*"*","NEXT START",10*"*") print(10*"*","NEXT START",10*"*")
ic(state.avgp, state.positions) #ic(state.avgp, state.positions)
ic(state.vars) #ic(state.vars)
ic(data) #ic(data)
#mozna presunout o level vys #mozna presunout o level vys
def vyloz(): def vyloz():
@ -128,7 +128,7 @@ def next(data, state: StrategyState):
last_price = price2dec(state.interface.get_last_price(state.symbol)) last_price = price2dec(state.interface.get_last_price(state.symbol))
#profit = float(state.vars.profit) #profit = float(state.vars.profit)
price = last_price price = last_price
state.ilog(e="BUY Vykladame", msg="first price"+str(price) + "pozic:"+str(vykladka), curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka) state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci ##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET ##VAR - na zaklade conf. muzeme jako prvni posilat MARKET
@ -176,7 +176,7 @@ def next(data, state: StrategyState):
state.indicators.ema = ema(state.bars.close, state.vars.MA) #state.bars.vwap state.indicators.ema = ema(state.bars.close, state.vars.MA) #state.bars.vwap
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne #trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema] state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:]) #ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
slope_lookback = int(state.vars.slope_lookback) slope_lookback = int(state.vars.slope_lookback)
minimum_slope = float(state.vars.minimum_slope) minimum_slope = float(state.vars.minimum_slope)
@ -192,17 +192,18 @@ def next(data, state: StrategyState):
array_do = slope_lookback array_do = slope_lookback
lookbackprice_array = state.bars.vwap[-array_od:-array_do] lookbackprice_array = state.bars.vwap[-array_od:-array_do]
#obycejný prumer hodnot #obycejný prumer hodnot
lookbackprice = sum(lookbackprice_array)/lookback_offset lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
#výpočet úhlu #výpočet úhlu
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
slope = round(slope, 4)
state.indicators.slope.append(slope) state.indicators.slope.append(slope)
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope) state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope)
#state.indicators.roc.append(roc) #state.indicators.roc.append(roc)
#print("slope", state.indicators.slope[-5:]) #print("slope", state.indicators.slope[-5:])
state.ilog(e="Slope "+str(slope), msg="lookback price:"+str(lookbackprice), lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:]) state.ilog(e=f"{slope=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:])
#slope MA - cílem je identifikovat táhlá klesání, vypnout nákupy, až budou zase růsty #slope MA - cílem je identifikovat táhlá klesání, vypnout nákupy, až budou zase růsty
@ -262,18 +263,18 @@ def next(data, state: StrategyState):
if o.side == OrderSide.BUY: if o.side == OrderSide.BUY:
pendingbuys_new[str(o.id)]=float(o.limit_price) pendingbuys_new[str(o.id)]=float(o.limit_price)
state.ilog(e="Konzolidace limitky", msg="limitka stejna?:"+str((str(limitka_old)==str(state.vars.limitka))), limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty) state.ilog(e="Konzolidace limitky", msg=f"stejna:{(str(limitka_old)==str(state.vars.limitka))}", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty)
#pokud mame #pokud mame
#neni limitka, ale mela by byt - vytváříme ji #neni limitka, ale mela by byt - vytváříme ji
if int(state.positions) > 0 and state.vars.limitka is None: if int(state.positions) > 0 and state.vars.limitka is None:
state.ilog(e="Limitka neni, ale mela by být.", msg="počet pozic aktualnich" + str(int(state.positions))) state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
price=price2dec(float(state.avgp)+state.vars.profit) price=price2dec(float(state.avgp)+state.vars.profit)
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions))) state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
state.vars.limitka_price = price state.vars.limitka_price = price
if state.vars.limitka == -1: if state.vars.limitka == -1:
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=str(state.vars.limitka)) state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
state.vars.limitka = None state.vars.limitka = None
state.vars.limitka_price = None state.vars.limitka_price = None
else: else:
@ -281,13 +282,13 @@ def next(data, state: StrategyState):
elif state.vars.limitka is not None and int(state.positions) > 0 and (int(state.positions) != int(limitka_qty)): elif state.vars.limitka is not None and int(state.positions) > 0 and (int(state.positions) != int(limitka_qty)):
#limitka existuje, ale spatne mnostvi - updatujeme #limitka existuje, ale spatne mnostvi - updatujeme
state.ilog(e="Limitka existuje, ale spatne mnozstvi - updatujeme", msg="POS"+str(int(state.positions))+" lim_qty:"+str(limitka_qty), pos=state.positions, limitka_qty=limitka_qty) state.ilog(e=f"Limitka existuje, ale spatne mnozstvi - updatujeme", msg=f"{state.positions=} {limitka_qty=}", pos=state.positions, limitka_qty=limitka_qty)
#snad to nespadne, kdyztak pridat exception handling #snad to nespadne, kdyztak pridat exception handling
puvodni = state.vars.limitka puvodni = state.vars.limitka
state.vars.limitka = asyncio.run(state.interface.repl(price=state.vars.limitka_price, orderid=state.vars.limitka, size=int(state.positions))) state.vars.limitka = asyncio.run(state.interface.repl(price=state.vars.limitka_price, orderid=state.vars.limitka, size=int(state.positions)))
if state.vars.limitka == -1: if state.vars.limitka == -1:
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=str(state.vars.limitka), puvodni=puvodni) state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
state.vars.limitka = puvodni state.vars.limitka = puvodni
else: else:
limitka_qty = int(state.positions) limitka_qty = int(state.positions)
@ -326,7 +327,7 @@ def next(data, state: StrategyState):
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru #HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
lp = state.interface.get_last_price(symbol=state.symbol) lp = state.interface.get_last_price(symbol=state.symbol)
state.ilog(e="ENTRY", msg="AVGP:"+str(round(float(state.avgp),2))+ "POS:" +str(state.positions)+" PROFIT:"+str(round(float(state.profit),2)), last_price=lp, stratvars=state.vars) state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),2)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)}", last_price=lp, stratvars=state.vars)
#maxSlopeMA = -0.03 #maxSlopeMA = -0.03
#SLOPE ANGLE PROTECTIONs #SLOPE ANGLE PROTECTIONs
@ -341,23 +342,21 @@ def next(data, state: StrategyState):
print("OCHRANA SLOPE TOO HIGH") print("OCHRANA SLOPE TOO HIGH")
# if slopeMA<maxSlopeMA: # if slopeMA<maxSlopeMA:
# state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA)) # state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA))
state.ilog(e="Slope too high "+str(slope)) state.ilog(e=f"Slope too high {slope}")
if len(state.vars.pendingbuys)>0: if len(state.vars.pendingbuys)>0:
print("CANCEL PENDINGBUYS") print("CANCEL PENDINGBUYS")
ic(state.vars.pendingbuys) #ic(state.vars.pendingbuys)
res = asyncio.run(state.cancel_pending_buys()) res = asyncio.run(state.cancel_pending_buys())
ic(state.vars.pendingbuys) #ic(state.vars.pendingbuys)
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res) state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
print("slope", slope) print("slope", slope)
print("min slope", minimum_slope) print("min slope", minimum_slope)
if ic(state.vars.jevylozeno) == 0: if state.vars.jevylozeno == 0:
print("Neni vylozeno, muzeme testovat nakup") print("Neni vylozeno, muzeme testovat nakup")
if isfalling(state.indicators.ema,state.vars.Trend) and slope > minimum_slope: if isfalling(state.indicators.ema,state.vars.Trend) and slope > minimum_slope:
print("BUY MARKET") print("BUY MARKET")
ic(data['updated'])
ic(state.time)
#zatim vykladame full #zatim vykladame full
#positions = int(int(state.vars.maxpozic)/int(state.vars.chunk)) #positions = int(int(state.vars.maxpozic)/int(state.vars.chunk))
vyloz() vyloz()
@ -378,8 +377,7 @@ def next(data, state: StrategyState):
if state.interface.get_last_price(state.symbol) > float(maxprice) + float(state.vars.ticks2reset): if state.interface.get_last_price(state.symbol) > float(maxprice) + float(state.vars.ticks2reset):
##TODO toto nejak vymyslet - duplikovat? ##TODO toto nejak vymyslet - duplikovat?
res = asyncio.run(state.cancel_pending_buys()) res = asyncio.run(state.cancel_pending_buys())
state.ilog(e="UJELO to o více " + str(state.vars.ticks2reset), msg="zrusene pb buye", pb=state.vars.pendingbuys) state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
#PENDING BUYS SPENT - PART #PENDING BUYS SPENT - PART
#pokud mame vylozeno a pendingbuys se vyklepou a #pokud mame vylozeno a pendingbuys se vyklepou a
@ -435,15 +433,11 @@ def init(state: StrategyState):
state.statinds['angle'] = {} state.statinds['angle'] = {}
state.vars["ticks2reset_backup"] = state.vars.ticks2reset state.vars["ticks2reset_backup"] = state.vars.ticks2reset
#state.indicators['roc'] = []
#state.ilog(e="INIT", stratvars=state.vars)
def main(): def main():
# try:
try: # strat_settings = tomli.loads("]] this is invalid TOML [[")
strat_settings = tomli.loads("]] this is invalid TOML [[") # except tomli.TOMLDecodeError:
except tomli.TOMLDecodeError: # print("Yep, definitely not valid.")
print("Yep, definitely not valid.")
#strat_settings = dict_replace_value(strat_settings, "None", None) #strat_settings = dict_replace_value(strat_settings, "None", None)

View File

@ -15,18 +15,18 @@ Simple strategie pro test backtesting
def next(data, state: StrategyState): def next(data, state: StrategyState):
print(10*"*","NEXT START",10*"*") print(10*"*","NEXT START",10*"*")
ic(state.avgp, state.positions) #ic(state.avgp, state.positions)
ic(state.vars.lastbuyindex) #ic(state.vars.lastbuyindex)
ic(data) #ic(data)
ic(state.positions) #ic(state.positions)
ic(state.vars.watched) #ic(state.vars.watched)
ic(state.vars.wait) #ic(state.vars.wait)
try: try:
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne #trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema] state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:]) #ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
except Exception as e: except Exception as e:
print("No data for MA yet", str(e)) print("No data for MA yet", str(e))
@ -49,26 +49,26 @@ def next(data, state: StrategyState):
datetime.fromtimestamp(state.last_trade_time) datetime.fromtimestamp(state.last_trade_time)
casbaru = datetime.fromtimestamp(state.last_trade_time)-data['time'] casbaru = datetime.fromtimestamp(state.last_trade_time)-data['time']
kupuj = casbaru.seconds > int(int(data['resolution']) * 0.4) kupuj = casbaru.seconds > int(int(data['resolution']) * 0.4)
ic(kupuj) #ic(kupuj)
ic(casbaru.seconds) #ic(casbaru.seconds)
#kupujeme kdyz v druhe polovine baru je aktualni cena=low (nejnizsi) #kupujeme kdyz v druhe polovine baru je aktualni cena=low (nejnizsi)
#isrising(state.indicators.ema,state.vars.Trend) #isrising(state.indicators.ema,state.vars.Trend)
#kdyz se v jednom baru pohneme o 2 #kdyz se v jednom baru pohneme o 2
if kupuj and data['confirmed'] != 1 and data['close'] == data['low'] and float(data['close']) + 0.01 < data['open'] and state.vars.wait is False and state.vars.watched is None: if kupuj and data['confirmed'] != 1 and data['close'] == data['low'] and float(data['close']) + 0.01 < data['open'] and state.vars.wait is False and state.vars.watched is None:
print("BUY MARKET") print("BUY MARKET")
ic(data['updated']) #ic(data['updated'])
ic(state.time) #ic(state.time)
##updatneme realnou cenou po fillu ##updatneme realnou cenou po fillu
state.buy() state.buy()
state.vars.wait = True state.vars.wait = True
if state.vars.watched and state.vars.wait is False: if state.vars.watched and state.vars.wait is False:
currprice = state.interface.get_last_price(symbol = state.symbol) currprice = state.interface.get_last_price(symbol = state.symbol)
ic(currprice) #ic(currprice)
if float(currprice) > (float(state.vars.watched) + float(state.vars.profit)): if float(currprice) > (float(state.vars.watched) + float(state.vars.profit)):
ic(state.time) #ic(state.time)
ic("prodavame", currprice) #ic("prodavame", currprice)
print("PRODAVAME") print("PRODAVAME")
##vymyslet jak odchytavat obecne chyby a vracet cislo objednavky ##vymyslet jak odchytavat obecne chyby a vracet cislo objednavky
state.interface.sell(size=1) state.interface.sell(size=1)

View File

@ -126,7 +126,7 @@ class Backtester:
# print("list before execution", self.open_orders) # print("list before execution", self.open_orders)
if len(self.open_orders) == 0: if len(self.open_orders) == 0:
ic("no pend orders") #ic("no pend orders")
return 0 return 0
changes = 0 changes = 0
@ -155,10 +155,10 @@ class Backtester:
# break # break
#pracovni list #pracovni list
ic("work_range 0:index_end") #ic("work_range 0:index_end")
ic(index_end) #ic(index_end)
work_range = self.btdata[0:index_end] work_range = self.btdata[0:index_end]
ic(len(work_range)) #ic(len(work_range))
#print("index_end", i) #print("index_end", i)
#print("oriznuto",self.btdata[0:i+1]) #print("oriznuto",self.btdata[0:i+1])
@ -166,36 +166,37 @@ class Backtester:
#pokud je vyplneny symbol, tak jedeme jen tyto, jinak vsechny #pokud je vyplneny symbol, tak jedeme jen tyto, jinak vsechny
print(order.id, datetime.timestamp(order.submitted_at), order.symbol, order.side, order.order_type, order.qty, order.limit_price, order.submitted_at) print(order.id, datetime.timestamp(order.submitted_at), order.symbol, order.side, order.order_type, order.qty, order.limit_price, order.submitted_at)
if order.canceled_at: if order.canceled_at:
ic("deleting canceled order",order.id) #ic("deleting canceled order",order.id)
todel.append(order) todel.append(order)
elif not self.symbol or order.symbol == self.symbol: elif not self.symbol or order.symbol == self.symbol:
#pricteme mininimalni latency od submittu k fillu #pricteme mininimalni latency od submittu k fillu
if order.submitted_at.timestamp() + BT_DELAYS.sub_to_fill > float(intime): if order.submitted_at.timestamp() + BT_DELAYS.sub_to_fill > float(intime):
ic("too soon for",order.id) print(f"too soon for {order.id}")
#try to execute #try to execute
else: else:
#try to execute specific order #try to execute specific order
a = self._execute_order(o = order, intime=intime, work_range=work_range) a = self._execute_order(o = order, intime=intime, work_range=work_range)
if a == 1: if a == 1:
ic("EXECUTED") #ic("EXECUTED")
todel.append(order) todel.append(order)
changes = 1 changes = 1
else: else:
ic("NOT EXECUTED",a) print("NOT EXECUTED {a}")
#ic("istodel",todel) #ic("NOT EXECUTED",a)
##ic("istodel",todel)
#vymazu z pending orderu vschny zprocesovane nebo ty na výmaz #vymazu z pending orderu vschny zprocesovane nebo ty na výmaz
for i in todel: for i in todel:
self.open_orders.remove(i) self.open_orders.remove(i)
todel = {} todel = {}
#tady udelat pripadny ořez self.btdata - priste zaciname od zacatku #tady udelat pripadny ořez self.btdata - priste zaciname od zacatku
#ic("before delete", len(self.btdata)) ##ic("before delete", len(self.btdata))
#TEST zkusime to nemazat, jak ovlivni performance #TEST zkusime to nemazat, jak ovlivni performance
#Mazeme, jinak je to hruza #Mazeme, jinak je to hruza
#nechavame na konci trady, které muzeme potrebovat pro consekutivni pravidlo #nechavame na konci trady, které muzeme potrebovat pro consekutivni pravidlo
del self.btdata[0:index_end-2-BT_FILL_CONS_TRADES_REQUIRED] del self.btdata[0:index_end-2-BT_FILL_CONS_TRADES_REQUIRED]
#ic("after delete",len(self.btdata[0:index_end])) ##ic("after delete",len(self.btdata[0:index_end]))
if changes: return 1 if changes: return 1
else: return 0 else: return 0
@ -214,8 +215,8 @@ class Backtester:
fill_time = None fill_time = None
fill_price = None fill_price = None
order_min_fill_time = o.submitted_at.timestamp() + BT_DELAYS.sub_to_fill order_min_fill_time = o.submitted_at.timestamp() + BT_DELAYS.sub_to_fill
ic(order_min_fill_time) #ic(order_min_fill_time)
ic(len(work_range)) #ic(len(work_range))
if o.order_type == OrderType.LIMIT: if o.order_type == OrderType.LIMIT:
if o.side == OrderSide.BUY: if o.side == OrderSide.BUY:
@ -248,7 +249,7 @@ class Backtester:
if consec_cnt == BT_FILL_CONS_TRADES_REQUIRED: if consec_cnt == BT_FILL_CONS_TRADES_REQUIRED:
#(1679081919.381649, 27.88) #(1679081919.381649, 27.88)
ic(i) #ic(i)
fill_time = i[0] fill_time = i[0]
fill_price = i[1] fill_price = i[1]
print("FILL LIMIT BUY at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1]) print("FILL LIMIT BUY at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1])
@ -278,7 +279,7 @@ class Backtester:
consec_cnt += 1 consec_cnt += 1
if consec_cnt == BT_FILL_CONS_TRADES_REQUIRED: if consec_cnt == BT_FILL_CONS_TRADES_REQUIRED:
#(1679081919.381649, 27.88) #(1679081919.381649, 27.88)
ic(i) #ic(i)
fill_time = i[0] fill_time = i[0]
fill_price = i[1] fill_price = i[1]
print("FILL LIMIT SELL at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1]) print("FILL LIMIT SELL at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1])
@ -296,7 +297,7 @@ class Backtester:
#najde prvni nejvetsi čas vetsi nez minfill #najde prvni nejvetsi čas vetsi nez minfill
if i[0] > float(order_min_fill_time): if i[0] > float(order_min_fill_time):
#(1679081919.381649, 27.88) #(1679081919.381649, 27.88)
ic(i) #ic(i)
fill_time = i[0] fill_time = i[0]
fill_price = i[1] fill_price = i[1]
print("FILL ",o.side,"MARKET at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "cena", i[1]) print("FILL ",o.side,"MARKET at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "cena", i[1])
@ -306,7 +307,7 @@ class Backtester:
return -1 return -1
if not fill_time: if not fill_time:
ic("not FILLED") #ic("not FILLED")
return 0 return 0
else: else:
@ -316,7 +317,7 @@ class Backtester:
o.filled_avg_price = float(fill_price) o.filled_avg_price = float(fill_price)
o.status = OrderStatus.FILLED o.status = OrderStatus.FILLED
ic(o.filled_at, o.filled_avg_price) #ic(o.filled_at, o.filled_avg_price)
a = self.update_account(o = o) a = self.update_account(o = o)
if a < 0: if a < 0:
@ -396,13 +397,13 @@ class Backtester:
optimalized as bisect left optimalized as bisect left
""""" """""
pos = bisect_left(self.btdata, (time,)) pos = bisect_left(self.btdata, (time,))
ic("vracime last price") #ic("vracime last price")
ic(time) #ic(time)
if pos == 0: if pos == 0:
ic(self.btdata[0][1]) #ic(self.btdata[0][1])
return self.btdata[0][1] return self.btdata[0][1]
afterTime, afterPrice = self.btdata[pos-1] afterTime, afterPrice = self.btdata[pos-1]
ic(afterPrice) #ic(afterPrice)
return afterPrice return afterPrice
@ -412,8 +413,8 @@ class Backtester:
# #print(i) # #print(i)
# if self.btdata[i][0] >= time: # if self.btdata[i][0] >= time:
# break # break
# ic(time, self.btdata[i-1][1]) # #ic(time, self.btdata[i-1][1])
# ic("get last price") # #ic("get last price")
# return self.btdata[i-1][1] # return self.btdata[i-1][1]
def submit_order(self, time: float, symbol: str, side: OrderSide, size: int, order_type: OrderType, price: float = None): def submit_order(self, time: float, symbol: str, side: OrderSide, size: int, order_type: OrderType, price: float = None):
@ -493,7 +494,7 @@ class Backtester:
limit_price=(float(price) if price else None)) limit_price=(float(price) if price else None))
self.open_orders.append(order) self.open_orders.append(order)
ic("order SUBMITTED", order) #ic("order SUBMITTED", order)
return id return id

View File

@ -222,7 +222,7 @@ def save_history(id: UUID, st: object, runner: Runner, reason: str = None):
#zkousime precist profit z objektu #zkousime precist profit z objektu
try: try:
profit = st.state.profit profit = st.state.profit
trade_count = len(st.tradeList) trade_count = len(st.state.tradeList)
except Exception as e: except Exception as e:
profit = str(e) profit = str(e)

View File

@ -93,8 +93,8 @@ class TradeAggregator:
#pokud projde TRADE s cenou 0.33% rozdilna oproti predchozi, pak vyhazujeme v ramci cisteni dat (cca 10ticku na 30USD) #pokud projde TRADE s cenou 0.33% rozdilna oproti predchozi, pak vyhazujeme v ramci cisteni dat (cca 10ticku na 30USD)
pct_off = 0.33 pct_off = 0.33
#ic(ltp.price) ##ic(ltp.price)
#ic(ltp.price[symbol]) ##ic(ltp.price[symbol])
try: try:
ltp.price[symbol] ltp.price[symbol]

View File

@ -63,7 +63,7 @@ class Trade_Offline_Streamer(Thread):
for i in self.streams: for i in self.streams:
self.uniquesymbols.add(i.symbol) self.uniquesymbols.add(i.symbol)
ic(self.uniquesymbols) #ic(self.uniquesymbols)
##z unikatnich symbolu naplnime keys pro dictionary ##z unikatnich symbolu naplnime keys pro dictionary
# for i in self.uniquesymbols: # for i in self.uniquesymbols:
# self.to_run # self.to_run
@ -77,14 +77,14 @@ class Trade_Offline_Streamer(Thread):
for i in self.streams: for i in self.streams:
self.to_run[i.symbol].append(i) self.to_run[i.symbol].append(i)
ic(self.to_run) #ic(self.to_run)
#prepare data #prepare data
symbpole = [] symbpole = []
for key in self.uniquesymbols: for key in self.uniquesymbols:
symbpole.append(key) symbpole.append(key)
#print(symbpole)) #print(symbpole))
ic(self.time_from.astimezone(tz=zoneNY)) #ic(self.time_from.astimezone(tz=zoneNY))
ic(self.time_to.astimezone(tz=zoneNY)) #ic(self.time_to.astimezone(tz=zoneNY))
##PREPSAT jednoduse tak, aby podporovalo jen jeden symbol ##PREPSAT jednoduse tak, aby podporovalo jen jeden symbol
#agregator2list bude mit vstup list #agregator2list bude mit vstup list
@ -92,7 +92,7 @@ class Trade_Offline_Streamer(Thread):
#REFACTOR STARTS HERE #REFACTOR STARTS HERE
calendar_request = GetCalendarRequest(start=self.time_from,end=self.time_to) calendar_request = GetCalendarRequest(start=self.time_from,end=self.time_to)
cal_dates = self.clientTrading.get_calendar(calendar_request) cal_dates = self.clientTrading.get_calendar(calendar_request)
ic(cal_dates) #ic(cal_dates)
#zatim podpora pouze main session #zatim podpora pouze main session
#zatim podpora pouze 1 symbolu, predelat na froloop vsech symbolu ze symbpole #zatim podpora pouze 1 symbolu, predelat na froloop vsech symbolu ze symbpole
@ -134,8 +134,8 @@ class Trade_Offline_Streamer(Thread):
#pokud jde o dnešní den a nebyl konec trhu tak cache neukládáme #pokud jde o dnešní den a nebyl konec trhu tak cache neukládáme
if day.open < datetime.now().astimezone(zoneNY) < day.close: if day.open < datetime.now().astimezone(zoneNY) < day.close:
print("not saving the cache, market still open today") print("not saving the cache, market still open today")
ic(datetime.now().astimezone(zoneNY)) #ic(datetime.now().astimezone(zoneNY))
ic(day.open, day.close) #ic(day.open, day.close)
else: else:
with open(file_path, 'wb') as fp: with open(file_path, 'wb') as fp:
pickle.dump(tradesResponse, fp) pickle.dump(tradesResponse, fp)
@ -157,13 +157,13 @@ class Trade_Offline_Streamer(Thread):
wait_for_q = False wait_for_q = False
else: else:
wait_for_q = True wait_for_q = True
ic(wait_for_q) #ic(wait_for_q)
# v tradesResponse je dict = Trades identifikovane symbolem # v tradesResponse je dict = Trades identifikovane symbolem
for symbol in tradesResponse: for symbol in tradesResponse:
#print(tradesResponse[symbol]) #print(tradesResponse[symbol])
celkem = len(tradesResponse[symbol]) celkem = len(tradesResponse[symbol])
ic(symbol, celkem) #ic(symbol, celkem)
#print("POCET: ", celkem) #print("POCET: ", celkem)
cnt = 1 cnt = 1
@ -173,13 +173,13 @@ class Trade_Offline_Streamer(Thread):
#protoze je zde cely den, poustime dal, jen ty relevantni #protoze je zde cely den, poustime dal, jen ty relevantni
#pokud je start_time < trade < end_time #pokud je start_time < trade < end_time
#datetime.fromtimestamp(parse_alpaca_timestamp(t['t'])) #datetime.fromtimestamp(parse_alpaca_timestamp(t['t']))
#ic(t['t']) ##ic(t['t'])
if self.time_from < to_datetime(t['t']) < self.time_to: if self.time_from < to_datetime(t['t']) < self.time_to:
#poustime dal, jinak ne #poustime dal, jinak ne
if wait_for_q: if wait_for_q:
if 'Q' not in t['c']: continue if 'Q' not in t['c']: continue
else: else:
ic("Q found poustime dal") #ic("Q found poustime dal")
wait_for_q = False wait_for_q = False
#homogenizace timestampu s online streamem #homogenizace timestampu s online streamem

View File

@ -3,7 +3,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from v2realbot.enums.enums import Mode, Account from v2realbot.enums.enums import Mode, Account
from v2realbot.config import WEB_API_KEY from v2realbot.config import WEB_API_KEY
from datetime import datetime from datetime import datetime
from icecream import install, ic #from icecream import install, ic
import os import os
from rich import print from rich import print
from threading import current_thread from threading import current_thread
@ -26,12 +26,12 @@ from threading import Thread
import asyncio import asyncio
#from async io import Queue, QueueEmpty #from async io import Queue, QueueEmpty
install() # install()
ic.configureOutput(includeContext=True) # ic.configureOutput(includeContext=True)
def threadName(): # def threadName():
return '%s |> ' % str(current_thread().name) # return '%s |> ' % str(current_thread().name)
ic.configureOutput(prefix=threadName) # ic.configureOutput(prefix=threadName)
ic.disable() # ic.disable()
""""" """""
Main entry point of the bot. Starts strategies according to config file, each Main entry point of the bot. Starts strategies according to config file, each
in separate thread. in separate thread.

View File

@ -82,7 +82,7 @@ function connect(event) {
logcnt++; logcnt++;
row = '<div data-toggle="collapse" data-target="#rec'+logcnt+'">'+logLine.time + " " + logLine.event + ' - '+ logLine.message+'</div>' row = '<div data-toggle="collapse" data-target="#rec'+logcnt+'">'+logLine.time + " " + logLine.event + ' - '+ (logLine.message == undefined ? "" : logLine.message) +'</div>'
str_row = JSON.stringify(logLine.details, null, 2) str_row = JSON.stringify(logLine.details, null, 2)
row_detail = '<div id="rec'+logcnt+'" data-toggle="collapse" data-target="#rec'+logcnt+'"class="collapse pidi"><pre>' + str_row + '</pre></div>' row_detail = '<div id="rec'+logcnt+'" data-toggle="collapse" data-target="#rec'+logcnt+'"class="collapse pidi"><pre>' + str_row + '</pre></div>'

View File

@ -16,7 +16,7 @@ class StrategyOrderLimitKOKA(Strategy):
async def orderUpdateBuy(self, data: TradeUpdate): async def orderUpdateBuy(self, data: TradeUpdate):
if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL:
ic("vstupujeme do orderupdatebuy") #ic("vstupujeme do orderupdatebuy")
print(data) print(data)
o: Order = data.order o: Order = data.order
#dostavame zde i celkové akutální množství - ukládáme #dostavame zde i celkové akutální množství - ukládáme
@ -39,18 +39,18 @@ class StrategyOrderLimitKOKA(Strategy):
async def orderUpdateSell(self, data: TradeUpdate): async def orderUpdateSell(self, data: TradeUpdate):
if data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.PARTIAL_FILL:
ic("partial fill udpatujeme pozice") #ic("partial fill udpatujeme pozice")
self.state.avgp, self.state.positions = self.interface.pos() self.state.avgp, self.state.positions = self.interface.pos()
elif data.event == TradeEvent.FILL: elif data.event == TradeEvent.FILL:
#muzeme znovu nakupovat, mazeme limitku #muzeme znovu nakupovat, mazeme limitku
#self.state.blockbuy = 0 #self.state.blockbuy = 0
ic("notifikace sell mazeme limitku") #ic("notifikace sell mazeme limitku")
self.state.vars.limitka = None self.state.vars.limitka = None
self.state.vars.lastbuyindex = -5 self.state.vars.lastbuyindex = -5
#this parent method is called by strategy just once before waiting for first data #this parent method is called by strategy just once before waiting for first data
def strat_init(self): def strat_init(self):
ic("strat INI function") #ic("strat INI function")
#lets connect method overrides #lets connect method overrides
self.state.buy = self.buy self.state.buy = self.buy
self.state.buy_l = self.buy_l self.state.buy_l = self.buy_l
@ -67,8 +67,8 @@ class StrategyOrderLimitKOKA(Strategy):
sizer = size sizer = size
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy(size=sizer) return self.state.interface.buy(size=sizer)
#pro experiment - nemame zde max mnozstvi #pro experiment - nemame zde max mnozstvi
@ -78,9 +78,9 @@ class StrategyOrderLimitKOKA(Strategy):
#TODO pokud je cena 2 decimals, nechavam. pokud je 3 mistne delam round(x,2) #TODO pokud je cena 2 decimals, nechavam. pokud je 3 mistne delam round(x,2)
if price is None: price=trunc(self.state.interface.get_last_price(self.symbol),2) if price is None: price=trunc(self.state.interface.get_last_price(self.symbol),2)
ic(price) #ic(price)
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy_l(price=price, size=size) return self.state.interface.buy_l(price=price, size=size)

View File

@ -21,17 +21,17 @@ class StrategyOrderLimitVykladaci(Strategy):
async def orderUpdateBuy(self, data: TradeUpdate): async def orderUpdateBuy(self, data: TradeUpdate):
o: Order = data.order o: Order = data.order
##nejak to vymyslet, aby se dal poslat cely Trade a serializoval se ##nejak to vymyslet, aby se dal poslat cely Trade a serializoval se
self.state.ilog(e="Příchozí BUY notifikace", msg="order status:"+o.status, trade=json.loads(json.dumps(data, default=json_serial))) self.state.ilog(e="Příchozí BUY notif", msg=f"{o.status=}", trade=json.loads(json.dumps(data, default=json_serial)))
if o.status == OrderStatus.FILLED or o.status == OrderStatus.CANCELED: if o.status == OrderStatus.FILLED or o.status == OrderStatus.CANCELED:
#pokud existuje objednavka v pendingbuys - vyhodime ji #pokud existuje objednavka v pendingbuys - vyhodime ji
if self.state.vars.pendingbuys.pop(str(o.id), False): if self.state.vars.pendingbuys.pop(str(o.id), False):
self.state.ilog(e="Příchozí BUY notifikace - mazeme ji z pb", msg="order status:"+o.status, orderid=str(o.id), pb=self.state.vars.pendingbuys) self.state.ilog(e="Příchozí BUY notif - mazeme ji z pb", msg=f"{o.status=}", orderid=str(o.id), pb=self.state.vars.pendingbuys)
print("limit buy filled or cancelled. Vyhazujeme z pendingbuys.") print("limit buy filled or cancelled. Vyhazujeme z pendingbuys.")
ic(self.state.vars.pendingbuys) #ic(self.state.vars.pendingbuys)
if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL:
ic("vstupujeme do orderupdatebuy") #ic("vstupujeme do orderupdatebuy")
print(data) print(data)
#dostavame zde i celkové akutální množství - ukládáme #dostavame zde i celkové akutální množství - ukládáme
self.state.positions = data.position_qty self.state.positions = data.position_qty
@ -59,7 +59,7 @@ class StrategyOrderLimitVykladaci(Strategy):
self.state.vars.limitka = puvodni self.state.vars.limitka = puvodni
else: else:
self.state.vars.limitka_price = cena self.state.vars.limitka_price = cena
self.state.ilog(e="Příchozí BUY notif - menime limitku", msg="order status:"+o.status, orderid=str(o.id), limitka=str(self.state.vars.limitka), limtka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni)) self.state.ilog(e="Příchozí BUY notif - menime limitku", msg=f"{o.status=}", orderid=str(o.id), limitka=str(self.state.vars.limitka), limtka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni))
except APIError as e: except APIError as e:
self.state.ilog(e="API ERROR pri zmene limitky", msg=str(e), orderid=str(o.id), limitka=str(self.state.vars.limitka), limitka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni)) self.state.ilog(e="API ERROR pri zmene limitky", msg=str(e), orderid=str(o.id), limitka=str(self.state.vars.limitka), limitka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni))
@ -71,7 +71,7 @@ class StrategyOrderLimitVykladaci(Strategy):
async def orderUpdateSell(self, data: TradeUpdate): async def orderUpdateSell(self, data: TradeUpdate):
self.state.ilog(e="Příchozí SELL notifikace", msg="order status:"+data.order.status, trade=json.loads(json.dumps(data, default=json_serial))) self.state.ilog(e="Příchozí SELL notif", msg=f"{data.order.status=}", trade=json.loads(json.dumps(data, default=json_serial)))
#PROFIT #PROFIT
#profit pocitame z TradeUpdate.price a TradeUpdate.qty - aktualne provedene mnozstvi a cena #profit pocitame z TradeUpdate.price a TradeUpdate.qty - aktualne provedene mnozstvi a cena
#naklady vypocteme z prumerne ceny, kterou mame v pozicich #naklady vypocteme z prumerne ceny, kterou mame v pozicich
@ -85,11 +85,11 @@ class StrategyOrderLimitVykladaci(Strategy):
trade_profit = (sold_amount - avg_costs) trade_profit = (sold_amount - avg_costs)
self.state.profit += trade_profit self.state.profit += trade_profit
self.state.ilog(e="SELL not - PROFIT: "+str(round(float(trade_profit),3))+" celkem: "+str(round(float(self.state.profit),3)), msg=str(data.event), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id)) self.state.ilog(e=f"SELL not - PROFIT:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)}", msg=str(data.event), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id))
if data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.PARTIAL_FILL:
self.state.ilog(e="SELL notifikace - Partial fill", msg="pouze update pozic", orderid=str(data.order.id)) self.state.ilog(e="SELL notifikace - Partial fill", msg="pouze update pozic", orderid=str(data.order.id))
ic("partial fill jen udpatujeme pozice") #ic("partial fill jen udpatujeme pozice")
#TODO tento update mozna vyhodit a pockat vzdy na plny fill - otestovat az bude cas #TODO tento update mozna vyhodit a pockat vzdy na plny fill - otestovat az bude cas
self.state.avgp, self.state.positions = self.interface.pos() self.state.avgp, self.state.positions = self.interface.pos()
elif data.event == TradeEvent.FILL or data.event == TradeEvent.CANCELED: elif data.event == TradeEvent.FILL or data.event == TradeEvent.CANCELED:
@ -97,20 +97,20 @@ class StrategyOrderLimitVykladaci(Strategy):
#muzeme znovu nakupovat, mazeme limitku, blockbuy a pendingbuys #muzeme znovu nakupovat, mazeme limitku, blockbuy a pendingbuys
#self.state.blockbuy = 0 #self.state.blockbuy = 0
ic("notifikace sell mazeme limitku a update pozic") #ic("notifikace sell mazeme limitku a update pozic")
#updatujeme pozice #updatujeme pozice
self.state.avgp, self.state.positions = self.interface.pos() self.state.avgp, self.state.positions = self.interface.pos()
ic(self.state.avgp, self.state.positions) #ic(self.state.avgp, self.state.positions)
self.state.vars.limitka = None self.state.vars.limitka = None
self.state.vars.limitka_price = None self.state.vars.limitka_price = None
self.state.vars.lastbuyindex = -5 self.state.vars.lastbuyindex = -5
self.state.vars.jevylozeno = 0 self.state.vars.jevylozeno = 0
await self.state.cancel_pending_buys() await self.state.cancel_pending_buys()
self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg="order status:"+ data.order.status, orderid=str(data.order.id), pb=self.state.vars.pendingbuys) self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg=f"{data.order.status=}", orderid=str(data.order.id), pb=self.state.vars.pendingbuys)
#this parent method is called by strategy just once before waiting for first data #this parent method is called by strategy just once before waiting for first data
def strat_init(self): def strat_init(self):
ic("strat INI function") #ic("strat INI function")
#lets connect method overrides #lets connect method overrides
self.state.buy = self.buy self.state.buy = self.buy
self.state.buy_l = self.buy_l self.state.buy_l = self.buy_l
@ -141,7 +141,7 @@ class StrategyOrderLimitVykladaci(Strategy):
return 0 return 0
if size is None: size=self.state.vars.chunk if size is None: size=self.state.vars.chunk
if price is None: price=price2dec((self.state.interface.get_last_price(self.symbol))) if price is None: price=price2dec((self.state.interface.get_last_price(self.symbol)))
ic(price) #ic(price)
print("odesilame LIMIT s cenou/qty", price, size) print("odesilame LIMIT s cenou/qty", price, size)
self.state.ilog(e="send LIMIT buy to if", msg="S:"+str(size)+" P:"+str(price), price=price, size=size) self.state.ilog(e="send LIMIT buy to if", msg="S:"+str(size)+" P:"+str(price), price=price, size=size)
order = self.state.interface.buy_l(price=price, size=size) order = self.state.interface.buy_l(price=price, size=size)
@ -149,9 +149,9 @@ class StrategyOrderLimitVykladaci(Strategy):
self.state.vars.pendingbuys[str(order)]=price self.state.vars.pendingbuys[str(order)]=price
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
self.state.ilog(e="Odslano a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys) self.state.ilog(e="Odeslan buy_l a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
async def cancel_pending_buys(self): async def cancel_pending_buys(self):
print("cancel pending buys called.") print("cancel pending buys called.")
@ -161,11 +161,11 @@ class StrategyOrderLimitVykladaci(Strategy):
if len(self.state.vars.pendingbuys)>0: if len(self.state.vars.pendingbuys)>0:
tmp = copy.deepcopy(self.state.vars.pendingbuys) tmp = copy.deepcopy(self.state.vars.pendingbuys)
for key in tmp: for key in tmp:
ic(key) #ic(key)
#nejprve vyhodime z pendingbuys #nejprve vyhodime z pendingbuys
self.state.vars.pendingbuys.pop(key, False) self.state.vars.pendingbuys.pop(key, False)
res = self.interface.cancel(key) res = self.interface.cancel(key)
self.state.ilog(e="Pendingy zrusen pro"+str(key), orderid=str(key), res=str(res)) self.state.ilog(e=f"Pendingy zrusen pro{key=}", orderid=str(key), res=str(res))
print("CANCEL PENDING BUYS RETURN", res) print("CANCEL PENDING BUYS RETURN", res)
self.state.vars.pendingbuys={} self.state.vars.pendingbuys={}
self.state.vars.jevylozeno = 0 self.state.vars.jevylozeno = 0

View File

@ -50,7 +50,6 @@ class Strategy:
self.account = account self.account = account
self.key = get_key(mode=self.mode, account=self.account) self.key = get_key(mode=self.mode, account=self.account)
self.rtqueue = None self.rtqueue = None
self.tradeList = []
#TODO predelat na dynamické queues #TODO predelat na dynamické queues
@ -89,7 +88,7 @@ class Strategy:
"""Allow client to set LIVE or BACKTEST mode""" """Allow client to set LIVE or BACKTEST mode"""
def set_mode(self, mode: Mode, start: datetime = None, end: datetime = None, cash = None, debug: bool = False): def set_mode(self, mode: Mode, start: datetime = None, end: datetime = None, cash = None, debug: bool = False):
ic(f"mode {mode} selected") #ic(f"mode {mode} selected")
if mode == Mode.BT and (not start or not end): if mode == Mode.BT and (not start or not end):
print("start/end required") print("start/end required")
@ -171,7 +170,7 @@ class Strategy:
self.state.time = self.state.last_trade_time + BT_DELAYS.trigger_to_strat self.state.time = self.state.last_trade_time + BT_DELAYS.trigger_to_strat
elif self.mode == Mode.LIVE or self.mode == Mode.PAPER: elif self.mode == Mode.LIVE or self.mode == Mode.PAPER:
self.state.time = datetime.now().timestamp() self.state.time = datetime.now().timestamp()
ic('time updated') #ic('time updated')
def strat_loop(self, item): def strat_loop(self, item):
##TODO do samostatne funkce ##TODO do samostatne funkce
@ -191,24 +190,25 @@ class Strategy:
## BT - execute orders that should have been filled until this time ## BT - execute orders that should have been filled until this time
##do objektu backtest controller? ##do objektu backtest controller?
ic(self.state.time) #ic(self.state.time)
if self.mode == Mode.BT: if self.mode == Mode.BT:
ic(self.bt.time) self.state.ilog(e="Before BT iter", msg=f"{self.bt.time=}")
#pozor backtester muze volat order_updates na minuly cas - nastavi si bt.time #pozor backtester muze volat order_updates na minuly cas - nastavi si bt.time
self.bt.execute_orders_and_callbacks(self.state.time) self.bt.execute_orders_and_callbacks(self.state.time)
ic(self.bt.time) #ic(self.bt.time)
ic(self.state.time) #ic(self.state.time)
#volame jeste jednou update_times, kdyby si BT nastavil interfaces na jiny cas (v ramci callbacku notifikací) #volame jeste jednou update_times, kdyby si BT nastavil interfaces na jiny cas (v ramci callbacku notifikací)
self.update_times(item) self.update_times(item)
ic(self.state.time) #ic(self.state.time)
if self.mode == Mode.BT: if self.mode == Mode.BT:
ic(self.bt.time) self.state.ilog(e="After BT iter", msg=f"{self.bt.time=}")
ic(len(self.btdata)) #ic(self.bt.time)
ic(self.bt.cash) #ic(len(self.btdata))
#ic(self.bt.cash)
self.save_item_history(item) self.save_item_history(item)
#nevyhodit ten refresh do TypeLimit? asi ANO #nevyhodit ten refresh do TypeLimit? asi ANO
@ -321,7 +321,7 @@ class Strategy:
#pokud jde o FILL zapisujeme do self.trades a notifikujeme #pokud jde o FILL zapisujeme do self.trades a notifikujeme
if data.event == TradeEvent.FILL: if data.event == TradeEvent.FILL:
self.tradeList.append(data) self.state.tradeList.append(data)
##TradeUpdate objekt better? ##TradeUpdate objekt better?
order: Order = data.order order: Order = data.order
@ -342,9 +342,16 @@ class Strategy:
##kroky po iteraci ##kroky po iteraci
def after_iteration(self, item): def after_iteration(self, item):
#sends real time updates to frontend if requested
self.send_rt_updates(item)
#DAT DO VNORENE FUNKCE
##check if real time chart is requested # inicializace poplatna typu strategie (např. u LIMITu dotažení existující limitky)
def strat_init(self):
pass
def send_rt_updates(self, item):
##if real time chart is requested
##posilame dict s objekty: bars, trades podle cbaru, a dale indicators naplnene time a pripadnymi identifikatory (EMA) ##posilame dict s objekty: bars, trades podle cbaru, a dale indicators naplnene time a pripadnymi identifikatory (EMA)
if self.rtqueue is not None: if self.rtqueue is not None:
rt_out = dict() rt_out = dict()
@ -403,10 +410,6 @@ class Strategy:
#mazeme logy pokud neni na ws pozadovano #mazeme logy pokud neni na ws pozadovano
self.state.iter_log_list = [] self.state.iter_log_list = []
# inicializace poplatna typu strategie (např. u LIMITu dotažení existující limitky)
def strat_init(self):
pass
@staticmethod @staticmethod
def append_bar(history_reference, new_bar: dict): def append_bar(history_reference, new_bar: dict):
history_reference['open'].append(new_bar['open']) history_reference['open'].append(new_bar['open'])
@ -507,13 +510,20 @@ class StrategyState:
self.cancel_pending_buys = None self.cancel_pending_buys = None
self.iter_log_list = [] self.iter_log_list = []
self.profit = 0 self.profit = 0
self.tradeList = []
def ilog(self, e: str = None, msg: str = None, **kwargs): def ilog(self, e: str = None, msg: str = None, **kwargs):
if e is None: if e is None:
row = dict(time=self.time, message=msg, details=kwargs) if msg is None:
row = dict(time=self.time, details=kwargs)
else:
row = dict(time=self.time, message=msg, details=kwargs)
else: else:
row = dict(time=self.time, event=e, message=msg, details=kwargs) if msg is None:
row = dict(time=self.time, event=e, details=kwargs)
else:
row = dict(time=self.time, event=e, message=msg, details=kwargs)
self.iter_log_list.append(row) self.iter_log_list.append(row)
row["name"] = self.name row["name"] = self.name
print(row) print(row)
#TBD mozna odsud to posilat do nejakeho struct logger jako napr. structlog #TBD mozna odsud to posilat do nejakeho struct logger jako napr. structlog nebo loguru, separatni file podle name

View File

@ -31,7 +31,7 @@ class StrategyOrderLimit(Strategy):
async def orderUpdateBuy(self, data: TradeUpdate): async def orderUpdateBuy(self, data: TradeUpdate):
if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL:
ic("vstupujeme do orderupdatebuy") #ic("vstupujeme do orderupdatebuy")
print(data) print(data)
o: Order = data.order o: Order = data.order
#dostavame zde i celkové akutální množství - ukládáme #dostavame zde i celkové akutální množství - ukládáme
@ -54,18 +54,18 @@ class StrategyOrderLimit(Strategy):
async def orderUpdateSell(self, data: TradeUpdate): async def orderUpdateSell(self, data: TradeUpdate):
if data.event == TradeEvent.PARTIAL_FILL: if data.event == TradeEvent.PARTIAL_FILL:
ic("partial fill udpatujeme pozice") #ic("partial fill udpatujeme pozice")
self.state.avgp, self.state.positions = self.interface.pos() self.state.avgp, self.state.positions = self.interface.pos()
elif data.event == TradeEvent.FILL: elif data.event == TradeEvent.FILL:
#muzeme znovu nakupovat, mazeme limitku #muzeme znovu nakupovat, mazeme limitku
#self.state.blockbuy = 0 #self.state.blockbuy = 0
ic("notifikace sell mazeme limitku") #ic("notifikace sell mazeme limitku")
self.state.vars.limitka = None self.state.vars.limitka = None
self.state.vars.lastbuyindex = -5 self.state.vars.lastbuyindex = -5
#this parent method is called by strategy just once before waiting for first data #this parent method is called by strategy just once before waiting for first data
def strat_init(self): def strat_init(self):
ic("strat INI function") #ic("strat INI function")
#lets connect method overrides #lets connect method overrides
self.state.buy = self.buy self.state.buy = self.buy
self.state.buy_l = self.buy_l self.state.buy_l = self.buy_l
@ -82,8 +82,8 @@ class StrategyOrderLimit(Strategy):
sizer = size sizer = size
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy(size=sizer) return self.state.interface.buy(size=sizer)
#pro experiment - nemame zde max mnozstvi #pro experiment - nemame zde max mnozstvi
@ -91,9 +91,9 @@ class StrategyOrderLimit(Strategy):
print("overriden buy limitka") print("overriden buy limitka")
if size is None: size=self.state.vars.chunk if size is None: size=self.state.vars.chunk
if price is None: price=trunc(self.state.interface.get_last_price(self.symbol)-0.01,2) if price is None: price=trunc(self.state.interface.get_last_price(self.symbol)-0.01,2)
ic(price) #ic(price)
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy_l(price=price, size=size) return self.state.interface.buy_l(price=price, size=size)

View File

@ -15,7 +15,7 @@ class StrategyOrderLimitWatched(Strategy):
async def orderUpdateBuy(self, data: TradeUpdate): async def orderUpdateBuy(self, data: TradeUpdate):
if data.event == TradeEvent.FILL: if data.event == TradeEvent.FILL:
ic("orderbuyfill callback") #ic("orderbuyfill callback")
print(data) print(data)
o: Order = data.order o: Order = data.order
#dostavame zde i celkové akutální množství - ukládáme #dostavame zde i celkové akutální množství - ukládáme
@ -30,11 +30,11 @@ class StrategyOrderLimitWatched(Strategy):
self.state.positions = data.position_qty self.state.positions = data.position_qty
self.state.vars.watched = None self.state.vars.watched = None
self.state.vars.wait = False self.state.vars.wait = False
ic("SELL notifikace callback - prodano - muzeme znovu nakupovat") #ic("SELL notifikace callback - prodano - muzeme znovu nakupovat")
#this parent method is called by strategy just once before waiting for first data #this parent method is called by strategy just once before waiting for first data
def strat_init(self): def strat_init(self):
ic("strat INI function") #ic("strat INI function")
#lets connect method overrides #lets connect method overrides
self.state.buy = self.buy self.state.buy = self.buy
self.state.buy_l = self.buy_l self.state.buy_l = self.buy_l
@ -51,8 +51,8 @@ class StrategyOrderLimitWatched(Strategy):
sizer = size sizer = size
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy(size=sizer) return self.state.interface.buy(size=sizer)
#pro experiment - nemame zde max mnozstvi #pro experiment - nemame zde max mnozstvi
@ -60,9 +60,9 @@ class StrategyOrderLimitWatched(Strategy):
print("overriden buy limitka") print("overriden buy limitka")
if size is None: size=self.state.vars.chunk if size is None: size=self.state.vars.chunk
if price is None: price=trunc(self.state.interface.get_last_price(self.symbol)-0.01,2) if price is None: price=trunc(self.state.interface.get_last_price(self.symbol)-0.01,2)
ic(price) #ic(price)
self.state.blockbuy = 1 self.state.blockbuy = 1
self.state.vars.lastbuyindex = self.state.bars['index'][-1] self.state.vars.lastbuyindex = self.state.bars['index'][-1]
ic(self.state.blockbuy) #ic(self.state.blockbuy)
ic(self.state.vars.lastbuyindex) #ic(self.state.vars.lastbuyindex)
return self.state.interface.buy_l(price=price, size=size) return self.state.interface.buy_l(price=price, size=size)

View File

@ -6,7 +6,6 @@ import pytz
from dateutil import tz from dateutil import tz
from rich import print as richprint from rich import print as richprint
import decimal import decimal
from icecream import ic
from v2realbot.enums.enums import RecordType, Mode, StartBarAlign from v2realbot.enums.enums import RecordType, Mode, StartBarAlign
import pickle import pickle
import os import os
@ -94,7 +93,7 @@ def print(*args, **kwargs):
if QUIET_MODE: if QUIET_MODE:
pass pass
else: else:
#ic(*args, **kwargs) ####ic(*args, **kwargs)
richprint(*args, **kwargs) richprint(*args, **kwargs)
def price2dec(price: float) -> float: def price2dec(price: float) -> float: