From 8cf29567203e9b7880f530e32e05b4d354d98174 Mon Sep 17 00:00:00 2001 From: David Brazda Date: Mon, 22 May 2023 18:53:26 +0200 Subject: [PATCH] refactor plneni time u indikatoru, v next upd --- v2realbot/ENTRY_VykladaciTest.py | 20 +- v2realbot/ENTRY_Vykladaci_RSI.py | 16 +- v2realbot/ENTRY_Vykladaci_RSI_MYSELL.py | 525 ++++++++++++++++++ v2realbot/ENTRY_Vykladaci_RSI_Normalized.py | 16 +- v2realbot/ENTRY_backtest_strategyVykladaci.py | 12 +- v2realbot/__pycache__/config.cpython-310.pyc | Bin 2847 -> 2847 bytes .../enums/__pycache__/enums.cpython-310.pyc | Bin 2324 -> 2316 bytes v2realbot/enums/enums.py | 2 +- .../__pycache__/aggregator.cpython-310.pyc | Bin 6493 -> 6561 bytes v2realbot/loader/aggregator.py | 15 +- v2realbot/static/js/archivechart.js | 65 ++- v2realbot/static/js/archivetables.js | 2 +- v2realbot/static/js/livewebsocket.js | 36 +- v2realbot/static/js/utils.js | 4 +- ...tegyOrderLimitVykladaciNormalizedMYSELL.py | 173 ++++++ .../strategy/__pycache__/base.cpython-310.pyc | Bin 14010 -> 13978 bytes v2realbot/strategy/base.py | 30 +- .../utils/__pycache__/utils.cpython-310.pyc | Bin 9116 -> 9144 bytes v2realbot/utils/utils.py | 4 +- 19 files changed, 846 insertions(+), 74 deletions(-) create mode 100644 v2realbot/ENTRY_Vykladaci_RSI_MYSELL.py create mode 100644 v2realbot/strategy/StrategyOrderLimitVykladaciNormalizedMYSELL.py diff --git a/v2realbot/ENTRY_VykladaciTest.py b/v2realbot/ENTRY_VykladaciTest.py index 4e97c81..5c1dd00 100644 --- a/v2realbot/ENTRY_VykladaciTest.py +++ b/v2realbot/ENTRY_VykladaciTest.py @@ -237,10 +237,10 @@ def next(data, state: StrategyState): #poslednich ma hodnot source = state.bars.close[-ma:] #state.bars.vwap ema_value = ema(source, ma) - state.indicators.ema.append(trunc(ema_value[-1],3)) + state.indicators.ema[-1]=trunc(ema_value[-1],3) except Exception as e: state.ilog(e="EMA ukladame 0", message=str(e)+format_exc()) - state.indicators.ema.append(0) + #state.indicators.ema[-1]=0 #EMA SLOW try: @@ -249,11 +249,11 @@ def next(data, state: StrategyState): source = state.bars.hlcc4[-ma:] #state.bars.vwap emaSlow_value = ema(source, ma) emaSlow = trunc(emaSlow_value[-1],3) - state.indicators.emaSlow.append(emaSlow) + state.indicators.emaSlow[-1]=emaSlow state.ilog(e=f"emaSlow {emaSlow=}", emaSlow=state.indicators.emaSlow[-5:]) except Exception as e: state.ilog(e=f"emaSlow {ma=} ukladame 0", message=str(e)+format_exc()) - state.indicators.emaSlow.append(0) + #state.indicators.emaSlow.append(0) #EMA FAST @@ -263,11 +263,11 @@ def next(data, state: StrategyState): source = state.bars.hlcc4[-ma:] #state.bars.vwap emaFast_value = ema(source, ma) emaFast = trunc(emaFast_value[-1],3) - state.indicators.emaFast.append(emaFast) + state.indicators.emaFast[-1]=emaFast state.ilog(e=f"emaFast {emaFast=}", emaFast=state.indicators.emaFast[-5:]) except Exception as e: state.ilog(e=f"emaFast {ma=} ukladame 0", message=str(e)+format_exc()) - state.indicators.emaFast.append(0) + #state.indicators.emaFast.append(0) #RSI14 @@ -352,7 +352,7 @@ def next(data, state: StrategyState): #výpočet úhlu slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 slope = round(slope, 4) - state.indicators.slope.append(slope) + state.indicators.slope[-1]=slope #angle je ze 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) @@ -362,7 +362,7 @@ def next(data, state: StrategyState): source = state.indicators.slope[-slope_MA_length:] slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap slopeMA = slopeMAseries[-1] - state.indicators.slopeMA.append(slopeMA) + state.indicators.slopeMA[-1]=slopeMA state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:]) @@ -371,8 +371,8 @@ def next(data, state: StrategyState): else: #pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time #kvuli spravnemu zobrazovani na gui - state.indicators.slope.append(0) - state.indicators.slopeMA.append(0) + #state.indicators.slopeMA[-1]=0 + #state.indicators.slopeMA.append(0) state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA) except Exception as e: print("Exception in NEXT Slope Indicator section", str(e)) diff --git a/v2realbot/ENTRY_Vykladaci_RSI.py b/v2realbot/ENTRY_Vykladaci_RSI.py index ae39f3a..015ec74 100644 --- a/v2realbot/ENTRY_Vykladaci_RSI.py +++ b/v2realbot/ENTRY_Vykladaci_RSI.py @@ -303,10 +303,10 @@ def next(data, state: StrategyState): #poslednich ma hodnot source = state.bars.close[-ma:] #state.bars.vwap ema_value = ema(source, ma) - state.indicators.ema.append(trunc(ema_value[-1],3)) + state.indicators.ema[-1]=trunc(ema_value[-1],3) except Exception as e: state.ilog(e="EMA ukladame 0", message=str(e)+format_exc()) - state.indicators.ema.append(0) + state.indicators.ema[-1]=0 #RSI14 INDICATOR try: @@ -320,13 +320,13 @@ def next(data, state: StrategyState): source = state.bars.close #[-rsi_length:] #state.bars.vwap rsi_res = rsi(source, rsi_length) rsi_value = trunc(rsi_res[-1],3) - state.indicators.RSI14.append(rsi_value) + state.indicators.RSI14[-1]=rsi_value rsi_dont_buy = rsi_value > rsi_dont_buy_above rsi_buy_signal = rsi_value < 40 state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:]) except Exception as e: state.ilog(e=f"RSI {rsi_length=} ukladame 0", message=str(e)+format_exc()) - state.indicators.RSI14.append(0) + #state.indicators.RSI14.append(0) #SLOPE INDICATOR @@ -349,7 +349,7 @@ def next(data, state: StrategyState): #výpočet úhlu slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 slope = round(slope, 4) - state.indicators.slope.append(slope) + state.indicators.slope[-1]=slope #angle je ze 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) @@ -359,7 +359,7 @@ def next(data, state: StrategyState): source = state.indicators.slope[-slope_MA_length:] slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap slopeMA = slopeMAseries[-1] - state.indicators.slopeMA.append(slopeMA) + state.indicators.slopeMA[-1]=slopeMA state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:]) @@ -368,8 +368,8 @@ def next(data, state: StrategyState): else: #pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time #kvuli spravnemu zobrazovani na gui - state.indicators.slope.append(0) - state.indicators.slopeMA.append(0) + #state.indicators.slopeMA[-1]=0 + #state.indicators.slopeMA.append(0) state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA) except Exception as e: print("Exception in NEXT Slope Indicator section", str(e)) diff --git a/v2realbot/ENTRY_Vykladaci_RSI_MYSELL.py b/v2realbot/ENTRY_Vykladaci_RSI_MYSELL.py new file mode 100644 index 0000000..8e91b18 --- /dev/null +++ b/v2realbot/ENTRY_Vykladaci_RSI_MYSELL.py @@ -0,0 +1,525 @@ +import os,sys +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from v2realbot.strategy.base import StrategyState +from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL +from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType +from v2realbot.indicators.indicators import ema +from v2realbot.indicators.oscillators import rsi +from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick +from datetime import datetime +#from icecream import install, ic +#from rich import print +from threading import Event +from msgpack import packb, unpackb +import asyncio +import os +from traceback import format_exc + +print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +"""" +Využívá: StrategyOrderLimitVykladaciNormalizedMYSELL + +Kopie RSI Normalizovane Vykladaci navíc s řízením prodeje. +Nepoužíváme LIMITKU. + +Required CBAR. (pouze se změnou ceny) + +nepotvrzený CBAR bez minticku (pouze se změnou ceny) +- se používá pro žízení prodeje + +potvrzený CBAR +- se používá pro BUY + + +""" +stratvars = AttributeDict(maxpozic = 400, + def_mode_from = 200, + chunk = 10, + MA = 2, + Trend = 2, + profit = 0.02, + def_profit = 0.01, + lastbuyindex=-6, + pendingbuys={}, + limitka = None, + limitka_price = None, + jevylozeno=0, + vykladka=5, + curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01], + curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02], + blockbuy = 0, + ticks2reset = 0.04, + consolidation_bar_count = 10, + slope_lookback = 300, + lookback_offset = 20, + minimum_slope = -0.05, + first_buy_market = False + ) +##toto rozparsovat a strategii spustit stejne jako v main +toml_string = """ +[[strategies]] +name = "V1 na BAC" +symbol = "BAC" +script = "ENTRY_backtest_strategyVykladaci" +class = "StrategyOrderLimitVykladaci" +open_rush = 0 +close_rush = 0 +[strategies.stratvars] +maxpozic = 200 +chunk = 10 +MA = 6 +Trend = 5 +profit = 0.02 +lastbuyindex=-6 +pendingbuys={} +limitka = "None" +jevylozeno=0 +vykladka=5 +curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01] +blockbuy = 0 +ticks2reset = 0.04 +[[strategies.add_data]] +symbol="BAC" +rectype="bar" +timeframe=5 +update_ltp=true +align="round" +mintick=0 +minsize=100 +exthours=false +""" + +def next(data, state: StrategyState): + print(10*"*","NEXT START",10*"*") + #ic(state.avgp, state.positions) + #ic(state.vars) + #ic(data) + + # + def is_defensive_mode(): + akt_pozic = int(state.positions) + max_pozic = int(state.vars.maxpozic) + def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2) + if akt_pozic >= int(def_mode_from): + state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions) + return True + else: + state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions) + return False + + def get_limitka_price(): + def_profit = safe_get(state.vars, "def_profit",state.vars.profit) + cena = float(state.avgp) + #v MYSELL hrajeme i na 3 desetinna cisla - TBD mozna hrat jen na 5ky (0.125, 0.130, 0.135 atp.) + if is_defensive_mode(): + return price2dec(cena+get_tick(cena,float(def_profit)),3) + else: + return price2dec(cena+get_tick(cena,float(state.vars.profit)),3) + + def consolidation(): + ##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys + #docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich) + if state.vars.jevylozeno == 1 or 1==1: + ##CONSOLIDATION PART kazdy Nty bar dle nastaveni + if int(data["index"])%int(state.vars.consolidation_bar_count) == 0: + print("***CONSOLIDATION ENTRY***") + state.ilog(e="CONSOLIDATION ENTRY ***") + + orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None) + #pro jistotu jeste dotahneme aktualni pozice + state.avgp, state.positions = state.interface.pos() + + #print(orderlist) + pendingbuys_new = {} + #zaciname s cistym stitem + state.vars.limitka = None + state.vars.limitka_price = None + for o in orderlist: + if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT: + pendingbuys_new[str(o.id)]=float(o.limit_price) + + if pendingbuys_new != state.vars.pendingbuys: + state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys) + print("ROZDILNA PENDINGBUYS přepsána") + print("OLD",state.vars.pendingbuys) + state.vars.pendingbuys = unpackb(packb(pendingbuys_new)) + print("NEW", state.vars.pendingbuys) + else: + print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys) + state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys) + print("OLD jevylozeno", state.vars.jevylozeno) + if len(state.vars.pendingbuys) > 0: + state.vars.jevylozeno = 1 + else: + state.vars.jevylozeno = 0 + print("NEW jevylozeno", state.vars.jevylozeno) + state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno) + + print("***CONSOLIDATION EXIT***") + state.ilog(e="CONSOLIDATION EXIT ***") + else: + state.ilog(e="No time for consolidation", msg=data["index"]) + print("no time for consolidation", data["index"]) + + #mozna presunout o level vys + def vyloz(): + ##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci + #curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02] + curve = state.vars.curve + ##defenzivni krivka pro + curve_def = state.vars.curve_def + #vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad + vykladka = state.vars.vykladka + #kolik muzu max vylozit + kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk)) + akt_pozic = int(state.positions) + max_pozic = int(state.vars.maxpozic) + + #mame polovinu a vic vylozeno, pouzivame defenzicni krivku + if is_defensive_mode(): + state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def) + curve = curve_def + #zaroven docasne menime ticks2reset na defenzivni 0.06 + state.vars.ticks2reset = 0.06 + state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup) + else: + #vracime zpet, pokud bylo zmeneno + if state.vars.ticks2reset != state.vars.ticks2reset_backup: + state.vars.ticks2reset = state.vars.ticks2reset_backup + state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup) + + if kolikmuzu < vykladka: vykladka = kolikmuzu + + if len(curve) < vykladka: + vykladka = len(curve) + qty = int(state.vars.chunk) + last_price = price2dec(state.interface.get_last_price(state.symbol)) + #profit = float(state.vars.profit) + price = last_price + 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 + + ##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order + if safe_get(state.vars, "first_buy_market") == True: + #pri defenzivnim rezimu pouzivame vzdy LIMIT order + if is_defensive_mode(): + state.ilog(e="DEF mode on, odesilame jako prvni limitku") + state.buy_l(price=price, size=qty) + else: + state.ilog(e="Posilame jako prvni MARKET order") + state.buy(size=qty) + else: + state.buy_l(price=price, size=qty) + print("prvni limitka na aktuální cenu. Další podle křivky", price, qty) + for i in range(0,vykladka-1): + price = price2dec(float(price - get_tick(price, curve[i]))) + if price == last_price: + qty = qty + int(state.vars.chunk) + else: + state.buy_l(price=price, size=qty) + #print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty) + qty = int(state.vars.chunk) + last_price = price + state.vars.blockbuy = 1 + state.vars.jevylozeno = 1 + + def eval_sell(): + """" + TBD + Když je RSI nahoře tak neprodávat, dokud 1) RSI neprestane stoupat 2)nedosahne to nad im not greedy limit + """ + ##mame pozice + ##aktualni cena je vetsi nebo rovna cene limitky + #muzeme zde jet i na pulcenty + curr_price = float(data['close']) + state.ilog(e="Eval SELL", price=curr_price, pos=state.positions, sell_in_progress=state.vars.sell_in_progress) + if int(state.positions) > 0 and state.vars.sell_in_progress is False: + goal_price = get_limitka_price() + state.ilog(e=f"Goal price {goal_price}") + if curr_price>=goal_price: + state.interface.sell(size=state.positions) + state.vars.sell_in_progress = True + state.ilog(e=f"market SELL was sent {curr_price=}", positions=state.positions, avgp=state.avgp, sellinprogress=state.vars.sell_in_progress) + + #na urovni CBARU mame zajisteno, ze update prichazi pri zmene ceny + #v kazde iteraci testujeme sell + #pri confirmed tesutjeme i buy + state.ilog(e="-----") + eval_sell() + + + conf_bar = data['confirmed'] + #for CBAR TICK and VOLUME change info + #price change vs Volume + tick_price = data['close'] + tick_volume = data['volume'] - state.vars.last_tick_volume + + #pouze potvrzovací BAR CBARu, mozna id confirmed = 1, pak ignorovat + if tick_volume == 0: + pass + + ##naplneni indikatoru vnitrniho CBAR tick price + ##pozor CBAR identifikatory jsou ukladane do historie az pro konfirmnuty bar + try: + state.indicators.tick_price[-1] = tick_price + state.indicators.tick_volume[-1] = tick_volume + except: + pass + + state.ilog(e=f"TICK PRICE {tick_price} VOLUME {tick_volume} {conf_bar=}", last_price=state.vars.last_tick_price, last_volume=state.vars.last_tick_volume) + + + state.vars.last_tick_price = tick_price + state.vars.last_tick_volume = data['volume'] + #pri potvrzem CBARu nulujeme counter volume + if conf_bar == 1: + state.vars.last_tick_volume = 0 + state.vars.next_new = 1 + + + + # if data['confirmed'] == 0: + # state.ilog(e="CBAR unconfirmed - returned", msg=str(data)) + # #TBD zde muzeme i nakupovat + # #indikatory pocitat, ale neukladat do historie + # return 0 + # #confirmed + # else: + # state.ilog(e="CBAR confirmed - continue", msg=str(data)) + + #EMA INDICATOR - + #plnime MAcko - nyni posilame jen N poslednich hodnot + #zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu + try: + ma = int(state.vars.MA) + #poslednich ma hodnot + source = state.bars.close[-ma:] #state.bars.vwap + ema_value = ema(source, ma) + state.indicators.ema[-1]=trunc(ema_value[-1],3) + except Exception as e: + state.ilog(e="EMA nechavame 0", message=str(e)+format_exc()) + #state.indicators.ema[-1]=(0) + + #RSI14 INDICATOR + try: + ##mame v atributech nastaveni? + rsi_dont_buy_above = safe_get(state.vars, "rsi_dont_buy_above",50) + rsi_buy_signal_conf = safe_get(state.vars, "rsi_buy_signal_below",40) + rsi_buy_signal = False + rsi_dont_buy = False + rsi_length = 2 + source = state.bars.close #[-rsi_length:] #state.bars.vwap + rsi_res = rsi(source, rsi_length) + rsi_value = trunc(rsi_res[-1],3) + state.indicators.RSI14[-1]=rsi_value + rsi_dont_buy = rsi_value > rsi_dont_buy_above + rsi_buy_signal = rsi_value < rsi_buy_signal_conf + state.ilog(e=f"RSI{rsi_value} {rsi_length=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:]) + except Exception as e: + state.ilog(e=f"RSI {rsi_length=} nechavame 0", message=str(e)+format_exc()) + #state.indicators.RSI14.append(0) + + + #SLOPE INDICATOR + #úhel stoupání a klesání vyjádřený mezi -1 až 1 + #pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback. + #obsahuje statický indikátor (angle) pro vizualizaci + try: + slope = 99 + slope_lookback = int(state.vars.slope_lookback) + minimum_slope = float(state.vars.minimum_slope) + lookback_offset = int(state.vars.lookback_offset) + + if len(state.bars.close) > (slope_lookback + lookback_offset): + array_od = slope_lookback + lookback_offset + array_do = slope_lookback + lookbackprice_array = state.bars.vwap[-array_od:-array_do] + #obycejný prumer hodnot + lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3) + + #výpočet úhlu - a jeho normalizace + slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 + slope = round(slope, 4) + state.indicators.slope[-1]=slope + + #angle je ze 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) + + #slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA + slope_MA_length = 5 + source = state.indicators.slope[-slope_MA_length:] + slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap + slopeMA = slopeMAseries[-1] + state.indicators.slopeMA[-1]=slopeMA + + state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:]) + + #dale pracujeme s timto MAckovanym slope + slope = slopeMA + else: + #pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time + #kvuli spravnemu zobrazovani na gui + #state.indicators.slopeMA[-1]=0 + #state.indicators.slopeMA.append(0) + state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA) + except Exception as e: + print("Exception in NEXT Slope Indicator section", str(e)) + state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc()) + + print("is falling",isfalling(state.indicators.ema,state.vars.Trend)) + print("is rising",isrising(state.indicators.ema,state.vars.Trend)) + + consolidation() + + if int(state.positions) >= state.vars.maxpozic: + state.ilog(e="Max pos reached") + return 0 + + + #HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru + #TODO sem pridat aktualni hodnoty vsech indikatoru + lp = state.interface.get_last_price(symbol=state.symbol) + state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars) + + #SLOPE ANGLE PROTECTIONs + #slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky + if slope < minimum_slope or rsi_dont_buy: # or slopeMA0: + print("CANCEL PENDINGBUYS") + #ic(state.vars.pendingbuys) + res = asyncio.run(state.cancel_pending_buys()) + #ic(state.vars.pendingbuys) + state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res) + print("slope", slope) + print("min slope", minimum_slope) + + if state.vars.jevylozeno == 0: + print("Neni vylozeno, muzeme testovat nakup") + + #pokud je defenziva, buy triggeruje defenzivni def_trend + #TBD + + #NOVY BUY SIGNAL z RSI < 35 + #buy_signal = isfalling(state.indicators.ema,state.vars.Trend) + buy_signal = rsi_buy_signal + + if buy_signal and slope > minimum_slope and not rsi_dont_buy: + state.ilog(e="BUY SIGNAL") + vyloz() + + ## testuje aktualni cenu od nejvyssi visici limitky + ##toto spoustet jednou za X iterací - ted to jede pokazdé + #pokud to ujede o vic, rusime limitky + #TODO: zvazit jestli nechat i pri otevrenych pozicich, zatim nechavame + #TODO int(int(state.oa.poz)/int(state.variables.chunk)) > X + + #TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou + #TODO spoustet 1x za X iteraci nebo cas + if state.vars.jevylozeno == 1: + #pokud mame vylozeno a cena je vetsi nez tick2reset + if len(state.vars.pendingbuys)>0: + maxprice = max(state.vars.pendingbuys.values()) + print("max cena v orderbuys", maxprice) + if state.interface.get_last_price(state.symbol) > float(maxprice) + get_tick(maxprice, float(state.vars.ticks2reset)): + ##TODO toto nejak vymyslet - duplikovat? + res = asyncio.run(state.cancel_pending_buys()) + state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys) + + #PENDING BUYS SPENT - PART + #pokud mame vylozeno a pendingbuys se vyklepou a + # 1 vykladame idned znovu + # vyloz() + # 2 nebo - počkat zase na signál a pokračovat dál + # state.vars.blockbuy = 0 + # state.vars.jevylozeno = 0 + # 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů) + #podle BT vyhodnejsi vylozit ihned + if len(state.vars.pendingbuys) == 0: + state.vars.blockbuy = 0 + state.vars.jevylozeno = 0 + state.ilog(e="PB se vyklepaly nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno) + + #TODO toto dodelat konzolidaci a mozna lock na limitku a pendingbuys a jevylozeno ?? + + #kdykoliv se muze notifikace ztratit + # - pendingbuys - vsechny open orders buy + # - limitka - open order sell + + + + + + + #pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim + # if int(state.oe.poz)>0 and state.oe.limitka == 0: + # #pro jistotu updatujeme pozice + # state.oe.avgp, state.oe.poz = state.oe.pos() + # if int(state.oe.poz) > 0: + # cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2) + # print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz) + # print("aktuzalni ltp",ltp.price[state.oe.symbol]) + + # try: + # state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz) + # print("vytvorena limitka", state.oe.limitka) + # except Exception as e: + # print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e)) + # pass + # ##raise Exception(e) + + print(10*"*","NEXT STOP",10*"*") + +def init(state: StrategyState): + #place to declare new vars + print("INIT v main",state.name) + + state.vars['sell_in_progress'] = False + state.vars.last_tick_price = 0 + state.vars.last_tick_volume = 0 + state.vars.next_new = 0 + state.indicators['tick_price'] = [] + state.indicators['tick_volume'] = [] + state.indicators['ema'] = [] + state.indicators['slope'] = [] + state.indicators['slopeMA'] = [] + state.indicators['RSI14'] = [] + #static indicators - those not series based + state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"]) + state.vars["ticks2reset_backup"] = state.vars.ticks2reset + +def main(): + # try: + # strat_settings = tomli.loads("]] this is invalid TOML [[") + # except tomli.TOMLDecodeError: + # print("Yep, definitely not valid.") + + #strat_settings = dict_replace_value(strat_settings, "None", None) + + name = os.path.basename(__file__) + se = Event() + pe = Event() + s = StrategyOrderLimitVykladaciNormalizedMYSELL(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True) + s.set_mode(mode = Mode.BT, + debug = False, + start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY), + end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY), + cash=100000) + + #na sekundovem baru nezaokrouhlovat MAcko + s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False) + #s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0) + + s.start() + print("zastavujeme") + +if __name__ == "__main__": + main() + + + + + \ No newline at end of file diff --git a/v2realbot/ENTRY_Vykladaci_RSI_Normalized.py b/v2realbot/ENTRY_Vykladaci_RSI_Normalized.py index e56a679..e5e58a5 100644 --- a/v2realbot/ENTRY_Vykladaci_RSI_Normalized.py +++ b/v2realbot/ENTRY_Vykladaci_RSI_Normalized.py @@ -302,10 +302,10 @@ def next(data, state: StrategyState): #poslednich ma hodnot source = state.bars.close[-ma:] #state.bars.vwap ema_value = ema(source, ma) - state.indicators.ema.append(trunc(ema_value[-1],3)) + state.indicators.ema[-1]=trunc(ema_value[-1],3) except Exception as e: state.ilog(e="EMA ukladame 0", message=str(e)+format_exc()) - state.indicators.ema.append(0) + #state.indicators.ema[-1]=0 #RSI14 INDICATOR try: @@ -318,13 +318,13 @@ def next(data, state: StrategyState): source = state.bars.close #[-rsi_length:] #state.bars.vwap rsi_res = rsi(source, rsi_length) rsi_value = trunc(rsi_res[-1],3) - state.indicators.RSI14.append(rsi_value) + state.indicators.RSI14[-1]=rsi_value rsi_dont_buy = rsi_value > rsi_dont_buy_above rsi_buy_signal = rsi_value < rsi_buy_signal_conf state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:]) except Exception as e: state.ilog(e=f"RSI {rsi_length=} ukladame 0", message=str(e)+format_exc()) - state.indicators.RSI14.append(0) + #state.indicators.RSI14[-1]=0 #SLOPE INDICATOR @@ -347,7 +347,7 @@ def next(data, state: StrategyState): #výpočet úhlu slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 slope = round(slope, 4) - state.indicators.slope.append(slope) + state.indicators.slope[-1]=slope #angle je ze 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) @@ -357,7 +357,7 @@ def next(data, state: StrategyState): source = state.indicators.slope[-slope_MA_length:] slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap slopeMA = slopeMAseries[-1] - state.indicators.slopeMA.append(slopeMA) + state.indicators.slopeMA[-1]=slopeMA state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:]) @@ -366,8 +366,8 @@ def next(data, state: StrategyState): else: #pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time #kvuli spravnemu zobrazovani na gui - state.indicators.slope.append(0) - state.indicators.slopeMA.append(0) + state.indicators.slopeMA[-1]=0 + #state.indicators.slopeMA.append(0) state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA) except Exception as e: print("Exception in NEXT Slope Indicator section", str(e)) diff --git a/v2realbot/ENTRY_backtest_strategyVykladaci.py b/v2realbot/ENTRY_backtest_strategyVykladaci.py index 62719bd..08b74d0 100644 --- a/v2realbot/ENTRY_backtest_strategyVykladaci.py +++ b/v2realbot/ENTRY_backtest_strategyVykladaci.py @@ -310,10 +310,10 @@ def next(data, state: StrategyState): #poslednich ma hodnot source = state.bars.close[-ma:] #state.bars.vwap ema_value = ema(source, ma) - state.indicators.ema.append(trunc(ema_value[-1],3)) + state.indicators.ema[-1]=trunc(ema_value[-1],3) except Exception as e: state.ilog(e="EMA ukladame 0", message=str(e)+format_exc()) - state.indicators.ema.append(0) + state.indicators.ema[-1]=0 #SLOPE INDICATOR #úhel stoupání a klesání vyjádřený mezi -1 až 1 @@ -335,7 +335,7 @@ def next(data, state: StrategyState): #výpočet úhlu slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100 slope = round(slope, 4) - state.indicators.slope.append(slope) + state.indicators.slope[-1]=slope #angle je ze 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) @@ -345,7 +345,7 @@ def next(data, state: StrategyState): source = state.indicators.slope[-slope_MA_length:] slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap slopeMA = slopeMAseries[-1] - state.indicators.slopeMA.append(slopeMA) + state.indicators.slopeMA[-1]=slopeMA state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:]) @@ -354,8 +354,8 @@ def next(data, state: StrategyState): else: #pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time #kvuli spravnemu zobrazovani na gui - state.indicators.slope.append(0) - state.indicators.slopeMA.append(0) + #state.indicators.slopeMA[-1]=0 + #state.indicators.slopeMA.append(0) state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA) except Exception as e: print("Exception in NEXT Slope Indicator section", str(e)) diff --git a/v2realbot/__pycache__/config.cpython-310.pyc b/v2realbot/__pycache__/config.cpython-310.pyc index 927dc9dfb8584ad23e69a60b239bc5ef622bfcf8..85a2755785563bb224b385570e8e182a7a979b3c 100644 GIT binary patch delta 20 acmbO)HeZZ8pO=@50SI|3oCG$Cg@qAlm=e%1Sw_Xl>(~^5?z+IHX%2E%6l;KEfNM|` zi;riRYZQ}H2v+B*099%Lagj2RnB2!EKiQxCHqaDp4khrIyEk3}HY6@iQ^Qk{H@!wLW}R5yMA delta 281 zcmeAXnj*xP&&$ij00hA?Q7KGp8~M6e7;jCU$)dw{izV2{KYVfkhv?)7Ed6|PKs7~* zAVLX9fP}>rfDB0>F6ICd91JXsEX*8?MGBL(*kvXkWsMTK#hjE_6vdOApI4HZSDIf8 zj6Ez%jrz=+@-FY;yb> zKmiagQU?(lK+}K7++r(A%uC77_0wc45(Np1fe3LBAvf8MLtRb>$TR|Cgwt4oP6LVh fY4YBh+{|GwtN`Q`selNu=^#0vuS6!lSP3Odf60rq*anh#>SKR8+LKw6;*NC@MtSvCSl!v?lRpx~L>5 zxGE@A&O+R1tGFn-uy!wkOMifHp+1)W0e6DuBvxtFf&1NazwbQeelt6R8$(7V5b!Ga zxF!qsmlIpY4{mty=)?6MSM9=f!V^{#N~yE1**u{vs%uPyZGXdER_#E;4M%)m$3L{R zx>AbS$x{mM2QcfU<6ZZm;!7wStikKt>8bP5K~y8{3Pvfr`+*u)8XWTu)j7=g6DD`m zR>eJ5SFA9yxBcVn8@%(UVri^Q+xnumriw7e9kj!De;*4%GLSOec3@dSt`D`?Ma9-( zB(R$FNH!+fdC87RHY(Y$WS1qIk?e|Om*8{YF&l#wW0;+TEyH3{U$SOyRje^QoI*dBVDW)UPPW}izLqOW=L3eY0=$j)urhp#A9a!a!ofdoN;9MJ EpC<&^k^lez delta 996 zcmZ`&-Afcv6rVdY?u`58=+1r&>ed=28wt8r8bn&5NiX#jrs=fqOz!HkyPg>zf)#`4 zp@%>^57A2`Mp19&doR8A&|7dRiin_x{)C`=W--xf;QsEp=XX9hzk6qETE;J|d6il5`$$)D>k@hBjfRX-6a0&tyCm%PACHj@?UXoL%7TGG`|^JI~oD zXIDA9g0c7`b`GD%N7*EPj@#@aj(0p{I)3OV$S{Fvqd)pg%r4*7Ls3Q6aN3xa!!dkm zoMj>WY1o~Y1k2UMdc6uG!i2e<`Odp6GDGgR)irm`#hiWwjl@RUA)bhQ7>0IjaBwqq z6yGI!n1w$Q+p|l=%j{-~iWyD&>|5 zh6xG;R4ui*C4`S;z%f puR^6%2KqH2DuB29WpIm5rM3iB?6U?#bR_^d- None: + super().__init__(name, symbol, next, init, account, mode, stratvars, open_rush, close_rush, pe, se, runner_id, ilog_save) + + async def orderUpdateBuy(self, data: TradeUpdate): + o: Order = data.order + ##nejak to vymyslet, aby se dal poslat cely Trade a serializoval se + self.state.ilog(e="Příchozí BUY notif", msg=o.status, trade=json.loads(json.dumps(data, default=json_serial))) + if o.status == OrderStatus.FILLED or o.status == OrderStatus.CANCELED: + + #pokud existuje objednavka v pendingbuys - vyhodime ji + if self.state.vars.pendingbuys.pop(str(o.id), False): + self.state.ilog(e="Příchozí BUY notif - mazeme ji z pb", msg=o.status, status=o.status, orderid=str(o.id), pb=self.state.vars.pendingbuys) + print("limit buy filled or cancelled. Vyhazujeme z pendingbuys.") + #ic(self.state.vars.pendingbuys) + + if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL: + #ic("vstupujeme do orderupdatebuy") + print(data) + #dostavame zde i celkové akutální množství - ukládáme + self.state.positions = data.position_qty + self.state.avgp, self.state.positions = self.state.interface.pos() + + async def orderUpdateSell(self, data: TradeUpdate): + + self.state.ilog(e="Příchozí SELL notif", msg=data.order.status, trade=json.loads(json.dumps(data, default=json_serial))) + #PROFIT + #profit pocitame z TradeUpdate.price a TradeUpdate.qty - aktualne provedene mnozstvi a cena + #naklady vypocteme z prumerne ceny, kterou mame v pozicich + if data.event == TradeEvent.FILL or data.event == TradeEvent.PARTIAL_FILL: + if data.event == TradeEvent.FILL: + self.state.vars.sell_in_progress = False + + sold_amount = data.qty * data.price + #podle prumerne ceny, kolik stalo toto mnozstvi + avg_costs = float(self.state.avgp) * float(data.qty) + if avg_costs == 0: + self.state.ilog(e="ERR: Nemame naklady na PROFIT, AVGP je nula. Zaznamenano jako 0", msg="naklady=utrzena cena. TBD opravit.") + avg_costs = sold_amount + + trade_profit = (sold_amount - avg_costs) + self.state.profit += trade_profit + self.state.ilog(e=f"SELL notif - 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)) + + #update pozic, v trade update je i pocet zbylych pozic + old_avgp = self.state.avgp + old_pos = self.state.positions + self.state.positions = int(data.position_qty) + if int(data.position_qty) == 0: + self.state.avgp = 0 + self.state.ilog(e="SELL notifikace "+str(data.order.status), msg="update pozic", old_avgp=old_avgp, old_pos=old_pos, avgp=self.state.avgp, pos=self.state.positions, orderid=str(data.order.id)) + #self.state.avgp, self.state.positions = self.interface.pos() + + if data.event == TradeEvent.FILL or data.event == TradeEvent.CANCELED: + print("Příchozí SELL notifikace - complete FILL nebo CANCEL", data.event) + #muzeme znovu nakupovat, mazeme limitku, blockbuy a pendingbuys + #self.state.blockbuy = 0 + + #ic("notifikace sell mazeme limitku a update pozic") + #updatujeme pozice + self.state.avgp, self.state.positions = self.interface.pos() + #ic(self.state.avgp, self.state.positions) + self.state.vars.limitka = None + self.state.vars.limitka_price = None + self.state.vars.lastbuyindex = -5 + self.state.vars.jevylozeno = 0 + await self.state.cancel_pending_buys() + self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg=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 + def strat_init(self): + #ic("strat INI function") + #lets connect method overrides + self.state.buy = self.buy + self.state.buy_l = self.buy_l + self.state.cancel_pending_buys = self.cancel_pending_buys + + #overidden methods + def buy(self, size = None, repeat: bool = False): + print("overriden method to size&check maximum ") + if int(self.state.positions) >= self.state.vars.maxpozic: + self.state.ilog(e="buy Maxim mnozstvi naplneno", positions=self.state.positions) + print("max mnostvi naplneno") + return 0 + if size is None: + sizer = self.state.vars.chunk + else: + sizer = size + + self.state.blockbuy = 1 + self.state.vars.lastbuyindex = self.state.bars['index'][-1] + self.state.ilog(e="send MARKET buy to if", msg="S:"+str(size), ltp=self.state.interface.get_last_price(self.state.symbol)) + return self.state.interface.buy(size=sizer) + + def buy_l(self, price: float = None, size = None, repeat: bool = False): + print("entering overriden BUY") + if int(self.state.positions) >= self.state.vars.maxpozic: + self.state.ilog(e="buyl Maxim mnozstvi naplneno", price=price, size=size, curr_positions=self.state.positions) + return 0 + if size is None: size=self.state.vars.chunk + if price is None: price=price2dec((self.state.interface.get_last_price(self.symbol))) + #ic(price) + 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) + order = self.state.interface.buy_l(price=price, size=size) + if order != -1: + print("ukladame pendingbuys") + self.state.vars.pendingbuys[str(order)]=price + self.state.blockbuy = 1 + self.state.vars.lastbuyindex = self.state.bars['index'][-1] + #ic(self.state.blockbuy) + #ic(self.state.vars.lastbuyindex) + self.state.ilog(e="Odeslan buy_l a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys) + else: + self.state.ilog(e="Chyba - nepodarilo se odeslat buy_l - nebylo ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys) + + async def cancel_pending_buys(self): + print("cancel pending buys called.") + self.state.ilog(e="Rusime pendingy", pb=self.state.vars.pendingbuys) + ##proto v pendingbuys pridano str(), protoze UUIN nejde serializovat + ##padalo na variable changed during iteration, pridano + if len(self.state.vars.pendingbuys)>0: + tmp = copy.deepcopy(self.state.vars.pendingbuys) + for key in tmp: + #ic(key) + #nejprve vyhodime z pendingbuys + self.state.vars.pendingbuys.pop(key, False) + if key != -1: + res = self.interface.cancel(key) + self.state.ilog(e=f"Pendingy zrusen pro {key=}", orderid=str(key), res=str(res)) + print("CANCEL PENDING BUYS RETURN", res) + self.state.vars.pendingbuys={} + self.state.vars.jevylozeno = 0 + print("cancel pending buys end") + self.state.ilog(e="Dokončeno zruseni vsech pb", pb=self.state.vars.pendingbuys) + + #kopie funkci co jsou v next jen async, nejak vymyslet, aby byly jen jedny + async def is_defensive_mode(self): + akt_pozic = int(self.state.positions) + max_pozic = int(self.state.vars.maxpozic) + def_mode_from = safe_get(self.state.vars, "def_mode_from") + if def_mode_from == None: def_mode_from = max_pozic/2 + if akt_pozic >= int(def_mode_from): + self.state.ilog(e=f"DEFENSIVE MODE active {self.state.vars.def_mode_from=}", msg=self.state.positions) + return True + else: + self.state.ilog(e=f"STANDARD MODE active {self.state.vars.def_mode_from=}", msg=self.state.positions) + return False + + async def get_limitka_price(self): + def_profit = safe_get(self.state.vars, "def_profit") + if def_profit == None: def_profit = self.state.vars.profit + cena = float(self.state.avgp) + if await self.is_defensive_mode(): + return price2dec(cena+get_tick(cena,float(def_profit))) + else: + return price2dec(cena+get_tick(cena,float(self.state.vars.profit))) \ No newline at end of file diff --git a/v2realbot/strategy/__pycache__/base.cpython-310.pyc b/v2realbot/strategy/__pycache__/base.cpython-310.pyc index 498edd6718d33b4c553467c0891b02c9268001a3..801a362aba452059125d3e240d7f9edadd046cfe 100644 GIT binary patch delta 1615 zcmZuxYitx%6rM9P`{=&Qc1yPp+PX_&K>9R7thA!mM^r>>(!>Xw+F9$i`|6!3MOhT0 zA&4PZPg@OYX%&@f43bSstbhvEw?a(x$EeX5^%pVm7si<2IkOrbaX0hrx!?Kjx%WJF z7Bc%Yft=s(k?1q<%&^`za3pXrP^ZvRrRN5EjO#&?3eu2d!jL>Hi&i`xs9HIs45>Ft z4}`YM1z888Yeym^BDNq$r5T4V&jLsz5&Sh!-?vVedjAViM%n|U^oVRpuLJ7~pes>{ z_mtR6V)u<~`k&aFuq{|uqedm2ueG}r;X+K^f#bn&gip3(U+#%H3sSCb=o(SfbXo|RvNi}6AGopt~>MvA1%yszSh9+*3KFz%Fd8ZlP1|s$L4` zi>d0zz_E{X-Nmyte}WhJBHI{VAVt_QNalU$T2=tG*VDAlL$fS;nc)?NgY5Rq zkZDl)#jEJ9PrKPorD?|5Xc+g^w>X|7Vhm5!_xWuX2qwg9cIcgC7O=bF?r6zp1&w4@ zPY5$n>ZBp~(qYGwq}zcf8*cX6r{8`d!qa5#Dqh)m9>Q5NEvG5^^`v3XgGggnY<$fy ztGP9nl1^qtH!st?bns*tmgm;2p4{3aL{5k~{5uwPzQK~WuqGahOtH{ULXk-41{3L& zVTy6=jrYKWeY4le|5Wiv{7r}-VyQe2j}L8sMAaZ!2QpeV3Wd49762RcZFb^KpXPElx7n zb9ss_9yVc@Xwg0>PwO8sqnR*;KWl4Y7^_#s^)Xg$XV}GXKLZbiXk_3S5Zrh%!(g|J znEbZ+oR|2LA&)yds&HY|Eq<3Ar$3d`4Q{Wys~B9Z zC{FH{IE1slFdk?vD_+$cgU63CcbwsUh7%0$G1vvTENeSqJ9Rr@PF-_}tt|h9;Zugs z7(Qpe1W--&g z-f5R|9^Y=Sc1|$+9iC}l?wBOA1^;T_5c`VB(+p<_ELS3-=LQmqf8R#TPvPc{D(}~9 eZe*CGZq&l>INebNKNXL5?3Ljt_FQekJ^uib+>#Rj delta 1679 zcmZ9Mdu&s66vumdZ|}OUEragWz1po~a3Qjn0mD<22`C$8V2sgF3%AU6U2pU29nT6` zi1Lp_;J_v*x($2`62a6sU-&=;A1D(4yYUrcqDG@G{(-?i@SI;EJlf>b^E>DK&i$S5 z`Q0Awf4kpr`g|S-eNL7=WGsoj=0E1&KU2j&nu|;SByY}bd>smFgsB7I~J{?g20c%P#zHz6xk8E2_Sn+;5QrbBCNm^zb30|mh zmVp;k@T!`#0!qOHUZo7^tFWz3;^orkD-)C|<`MK_v4CwaBZ()cHfd=#GdLIs;6GER z!5C`OCPQ}7K*oq!al-~n58Swiv(q>&kOtlphH)GVbisW5JMi78a0sCSL3=1FO}VKyVPad?4AeK ztO#fO5}8aQ-5c&+y*9kE>;6@pU7g))JC}twnj(DnT}yki;jM8?Z^X9pG;G3=^3|am zI_EC>2)2?jGeSz>#^1~D)m|rOb}lZcnC*BqMdWEOR+>-Y;T!BD8nYLz$m=Vv)ODOuVKCrKWc&U&1&oAC&P?}}((@YN7} zAH*m_PLgLR$4o<!`xRvsU;NXN?=2nj73D z?nU{(W+{rsLlomU>J8w|*5Z8GoCxf^-mq-*de>5uTe_AF%hqMX+`3*Qws6_c7@sq~ zV4P>L_To!|4pKk8R`9DN7BdDI7QWGPXLI3PyymMTjuUKU{lHe+MTn+sH5*T*Y^-gq z^G|S0%LsF0!V=Ho^48GJUDd&Fc%*d~9LzVgsW9_QQ{2;y9)xJoR zQcmFB_G;}Qd%wd|?bBUDWHzAPzBF=yonJF966~UA)G#+hqgVeo**}bnJE}^)VY8bt bMAN8+A8|)V75tPR?%3mmH*xx03-0+J&AqKb diff --git a/v2realbot/strategy/base.py b/v2realbot/strategy/base.py index fefe928..3648b9f 100644 --- a/v2realbot/strategy/base.py +++ b/v2realbot/strategy/base.py @@ -131,10 +131,18 @@ class Strategy: """SAVE record to respective STATE variables (bar or trades) ukládáme i index pro případné indikátory - pro zobrazení v grafu ----- NO support for simultaneous rectypes in one queue """ + + #do pole indikatoru se zde vzdycky prida nova hodnota (0) + #tzn. v NEXT dealame u indikatoru vzdy pouze UPDATE + def save_item_history(self,item): if self.rectype == RecordType.BAR: - #jako cas indikatorů pridavame cas baru, jejich hodnoty se naplni v nextu + #jako cas indikatorů pridavame cas baru a inicialni hodnoty vsech indikatoru self.state.indicators['time'].append(item['time']) + for key in self.state.indicators: + if key == 'time': + continue + self.state.indicators[key].append(0) self.append_bar(self.state.bars,item) elif self.rectype == RecordType.TRADE: pass @@ -144,17 +152,22 @@ class Strategy: elif self.rectype == RecordType.CBAR: #novy vzdy pridame if self.nextnew: - self.state.indicators['time'].append(item['time']) + self.state.indicators['time'].append(item['updated']) + for key in self.state.indicators: + if key == 'time': + continue + self.state.indicators[key].append(0) + self.append_bar(self.state.bars,item) self.nextnew = 0 #nasledujici updatneme, po potvrzeni, nasleduje novy bar else: if item['confirmed'] == 0: - self.state.indicators['time'][-1]=item['time'] + self.state.indicators['time'][-1]=item['updated'] self.replace_prev_bar(self.state.bars,item) #confirmed else: - self.state.indicators['time'][-1]=item['time'] + self.state.indicators['time'][-1]=item['updated'] self.replace_prev_bar(self.state.bars,item) self.nextnew = 1 @@ -224,14 +237,15 @@ class Strategy: self.before_iteration() ted = datetime.fromtimestamp(self.state.time).astimezone(zoneNY) if is_open_rush(ted, self.open_rush) or is_close_rush(ted, self.close_rush): + pass #self.state.ilog(e="Rush hour - skipping") #identifikatory jsou ulozeny vektorove, tzn. kdyz nejdeme dovnitr iterace(tak nepotrebujeme prazdny cas pro tuto iteraci) #hodnoty time a identifikatoru musi byt stejne #TBD pripdane predelat a dodelat pro CBARy az je budu pouzivat - if self.rectype == RecordType.BAR: - self.state.indicators['time'].pop() - elif self.rectype == RecordType.CBAR: - print("RUSH skipping NOT IMPLEMENTED for CBARs yet") + # if self.rectype == RecordType.BAR: + # self.state.indicators['time'].pop() + # elif self.rectype == RecordType.CBAR: + # print("RUSH skipping NOT IMPLEMENTED for CBARs yet") else: self.next(item, self.state) diff --git a/v2realbot/utils/__pycache__/utils.cpython-310.pyc b/v2realbot/utils/__pycache__/utils.cpython-310.pyc index a5bb8bb10f0375a101876269802c147f1830dae5..ed2020929da56bac9a2983cc370db6f57d240b34 100644 GIT binary patch delta 1304 zcmZ{i@o!UA6vyA~>$*Zgw-vUx!nVGRA>9}P+W=9=#>Tp_t_(58^apI&xk%TpTkb3B zu(axmKfol!!w&;S0>p&j4AXIe6x?w-GKxoj|5S^+{<%W2ahCsJ#G_>;s1O>y6t^e$`mA~ES2RA?3w(X z9@ydviWUvl4l+(KmX?Id)D#QH7#@a~V3+@67Sfe-mOP8zBN(Y35+_Tu)yqZwMcORXVAUBZ0h);Qn3ttT^C)xct$F~%q`oCoL}_avuI3;1f) f9OE*ByREJ=<{3^~oG#tx^Z`~hjR^zaZ!#YPGrv9& delta 1192 zcmZ{iUu;u#6vywmw`;bQ>DHG1W25aVO4&eRLlALnW3=r5$P!~}a5g)4a=WgpzgvPM zgJD)t{F5jr2Kke?#mKS;NJvGE5{((^lMg2PV4qZCqQ3d)o9Em{qYvKX_qpeM&!6A# zck=ryYOJci9?7q*yPGcNR^uUwbu z#&J3Uqf4T{d|d$88;rm6jzU8nm4SeDOQi- zAgg0Igu~or97k}J{}ZTB8d~yL<&OU8CS9dyHP#l3@X$)yqP7eOvo7T+!J>w+tWUBw zsU>y#@_w`KH=VO+M{~pg)ke4O^U+lE50DkBWr{=RW%7~}a;Ygg-trPybg$)S$kA8c z9bnTR-eLDFhgF{XeG_n&$oK88IT3P#g5Y@p2$Y~CI4L+KSft$vAHDDQd6vXICpc5t z@JFHJ|N112YW*qGoW<;dt!ybMQBxokEQ?w5*-F-_7erW~gMo1EkZ0)Wz%jT`xe;iD ztuJzL-KZLQvrsj%`FzzlZ57uI^{N!TM&Ad!;W9Ob+KktELao7WdL|TrH)JyYw>af% zNxR56y~VPXWz$M9=#id^1ef?)exDPu3eVjY>5AYg{SwN-HRsaP;RLME%i+1rs~q}< zmo2ZoUUNY`s8wo+JOwA5%##r>T(7(mY1CnjsP&!by7X!ntTDdh^-rn4L9JDW+B(5~ zL*h4SaqCZAABcHdP!aSA_A;vOY_Vt-kcah&Xg38P3O=GYqanCW>(MxKHRit#cKVGnxC^urc&?HQ0z(A;M4=2&!ofWf-ju&{}~JWWd=!5t)gaXc8+$& zL+~D@;$tvPZ^wV!c83F1cQISQtgWO=)iXVx&zsXFYrbGB*_JoD(!S@}1u>(NVOWKd wlE float: +def price2dec(price: float, decimals: int = 2) -> float: """ pousti maximalne 2 decimals pokud je trojmistne a vic pak zakrouhli na 2, jinak necha """ - return round(price,2) if count_decimals(price) > 2 else price + return round(price,decimals) if count_decimals(price) > decimals else price def count_decimals(number: float) -> int: """