gui sortovani tradu pred zobrazenim
This commit is contained in:
@ -4,17 +4,18 @@ from v2realbot.strategy.base import StrategyState
|
|||||||
from v2realbot.strategy.StrategyOrderLimitVykladaci import StrategyOrderLimitVykladaci
|
from v2realbot.strategy.StrategyOrderLimitVykladaci import StrategyOrderLimitVykladaci
|
||||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||||
from v2realbot.indicators.indicators import ema
|
from v2realbot.indicators.indicators import ema
|
||||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, dict_replace_value, print, safe_get
|
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from icecream import install, ic
|
#from icecream import install, ic
|
||||||
#from rich import print
|
#from rich import print
|
||||||
from threading import Event
|
from threading import Event
|
||||||
from msgpack import packb, unpackb
|
from msgpack import packb, unpackb
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import tomli
|
from traceback import format_exc
|
||||||
install()
|
|
||||||
ic.configureOutput(includeContext=True)
|
# install()
|
||||||
|
# ic.configureOutput(includeContext=True)
|
||||||
#ic.disable()
|
#ic.disable()
|
||||||
|
|
||||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
@ -116,6 +117,116 @@ def next(data, state: StrategyState):
|
|||||||
else:
|
else:
|
||||||
return price2dec(float(state.avgp)+float(state.vars.profit))
|
return price2dec(float(state.avgp)+float(state.vars.profit))
|
||||||
|
|
||||||
|
def consolidation():
|
||||||
|
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||||
|
if state.vars.jevylozeno == 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 = {}
|
||||||
|
limitka_old = state.vars.limitka
|
||||||
|
#print("Puvodni LIMITKA", limitka_old)
|
||||||
|
#zaciname s cistym stitem
|
||||||
|
state.vars.limitka = None
|
||||||
|
state.vars.limitka_price = None
|
||||||
|
limitka_found = False
|
||||||
|
limitka_qty = 0
|
||||||
|
limitka_filled_qty = 0
|
||||||
|
for o in orderlist:
|
||||||
|
if o.side == OrderSide.SELL:
|
||||||
|
|
||||||
|
if limitka_found:
|
||||||
|
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
||||||
|
result=state.interface.cancel(o.id)
|
||||||
|
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
||||||
|
continue
|
||||||
|
|
||||||
|
#print("Nalezena LIMITKA")
|
||||||
|
limitka_found = True
|
||||||
|
state.vars.limitka = o.id
|
||||||
|
state.vars.limitka_price = o.limit_price
|
||||||
|
limitka_qty = int(o.qty)
|
||||||
|
limitka_filled_qty = int(o.filled_qty)
|
||||||
|
|
||||||
|
#aktualni mnozstvi = puvodni minus filled
|
||||||
|
if limitka_filled_qty is not None:
|
||||||
|
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
||||||
|
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
||||||
|
##TODO sem pridat upravu ceny
|
||||||
|
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||||
|
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#neni limitka, ale mela by byt - vytváříme ji
|
||||||
|
if int(state.positions) > 0 and state.vars.limitka is None:
|
||||||
|
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
||||||
|
price=get_limitka_price()
|
||||||
|
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
||||||
|
state.vars.limitka_price = price
|
||||||
|
if state.vars.limitka == -1:
|
||||||
|
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
||||||
|
state.vars.limitka = None
|
||||||
|
state.vars.limitka_price = None
|
||||||
|
else:
|
||||||
|
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||||
|
|
||||||
|
#existuje a nesedi mnozstvi nebo cena
|
||||||
|
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
||||||
|
#limitka existuje, ale spatne mnostvi - updatujeme
|
||||||
|
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
||||||
|
#snad to nespadne, kdyztak pridat exception handling
|
||||||
|
puvodni = state.vars.limitka
|
||||||
|
#TBD zde odchytit nejak result
|
||||||
|
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
||||||
|
|
||||||
|
if state.vars.limitka == -1:
|
||||||
|
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
||||||
|
state.vars.limitka = puvodni
|
||||||
|
else:
|
||||||
|
limitka_qty = int(state.positions)
|
||||||
|
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
||||||
|
|
||||||
|
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
||||||
|
|
||||||
|
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(limitka)
|
||||||
|
#print(pendingbuys_new)
|
||||||
|
#print(pendingbuys)
|
||||||
|
#print(len(pendingbuys))
|
||||||
|
#print(len(pendingbuys_new))
|
||||||
|
#print(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
|
#mozna presunout o level vys
|
||||||
def vyloz():
|
def vyloz():
|
||||||
##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
|
||||||
@ -179,7 +290,6 @@ def next(data, state: StrategyState):
|
|||||||
state.vars.jevylozeno = 1
|
state.vars.jevylozeno = 1
|
||||||
|
|
||||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||||
|
|
||||||
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
||||||
if state.bars.confirmed[-1] == 0:
|
if state.bars.confirmed[-1] == 0:
|
||||||
print("OCHR: multibuy protection. waiting for next bar")
|
print("OCHR: multibuy protection. waiting for next bar")
|
||||||
@ -193,42 +303,30 @@ def next(data, state: StrategyState):
|
|||||||
|
|
||||||
state.ilog(e="-----")
|
state.ilog(e="-----")
|
||||||
|
|
||||||
|
#EMA INDICATOR -
|
||||||
|
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||||
|
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||||
try:
|
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.append(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)
|
||||||
|
|
||||||
## slope vyresi rychlé sesupy - jeste je treba podchytit pomalejsi sesupy
|
#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 = 99
|
||||||
#minimum slope disabled if -1
|
|
||||||
|
|
||||||
|
|
||||||
#roc_lookback = 20
|
|
||||||
#print(state.vars.MA, "MACKO")
|
|
||||||
#print(state.bars.hlcc4)
|
|
||||||
|
|
||||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
|
||||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
|
||||||
try:
|
|
||||||
ma = int(state.vars.MA)
|
|
||||||
source = state.bars.close[-ma:] #state.bars.vwap
|
|
||||||
ema_value = ema(source, ma)
|
|
||||||
state.indicators.ema.append(trunc(ema_value[-1],3))
|
|
||||||
except Exception as e:
|
|
||||||
state.ilog(e="EMA ukladame 0", message=str(e))
|
|
||||||
state.indicators.ema.append(0)
|
|
||||||
|
|
||||||
#TODO helikoz se EMA pocita pro cely set po kazde iteraci znouv, tak je toto PRASARNA
|
|
||||||
#davame pryc jestli bude to vyse fungovat
|
|
||||||
##state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
|
||||||
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)
|
||||||
lookback_offset = int(state.vars.lookback_offset)
|
lookback_offset = int(state.vars.lookback_offset)
|
||||||
|
|
||||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||||
|
|
||||||
#SLOPE INDICATOR POPULATION
|
|
||||||
#ú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 pro vizualizaci
|
|
||||||
array_od = slope_lookback + lookback_offset
|
array_od = slope_lookback + lookback_offset
|
||||||
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]
|
||||||
@ -240,157 +338,41 @@ def next(data, state: StrategyState):
|
|||||||
slope = round(slope, 4)
|
slope = round(slope, 4)
|
||||||
state.indicators.slope.append(slope)
|
state.indicators.slope.append(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)
|
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)
|
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||||
#print("slope", state.indicators.slope[-5:])
|
|
||||||
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_length = 5
|
slope_MA_length = 5
|
||||||
state.indicators.slopeMA = ema(state.indicators.slope, slope_MA_length) #state.bars.vwap
|
source = state.indicators.slope[-slope_MA_length:]
|
||||||
# #TODO - docasne posilam cele MA
|
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||||
# try:
|
slopeMA = slopeMAseries[-1]
|
||||||
# state.ilog(e="Slope - MA"+str(state.indicators.slopeMA[-1]), slopeMA=str(state.indicators.slopeMA[-20:]))
|
state.indicators.slopeMA.append(slopeMA)
|
||||||
# except Exception as e:
|
|
||||||
# state.ilog(e="Slope - MA"+str(state.indicators.slopeMA[-1]))
|
|
||||||
|
|
||||||
|
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:])
|
||||||
|
|
||||||
|
#dale pracujeme s timto MAckovanym slope
|
||||||
|
slope = slopeMA
|
||||||
else:
|
else:
|
||||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||||
#kvuli spravnemu zobrazovani na gui
|
#kvuli spravnemu zobrazovani na gui
|
||||||
state.indicators.slope.append(0)
|
state.indicators.slope.append(0)
|
||||||
state.indicators.slopeMA.append(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)
|
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Exception in NEXT Indicator section", str(e))
|
print("Exception in NEXT Slope Indicator section", str(e))
|
||||||
state.ilog(e="EXCEPTION", msg="Exception in NEXT 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 falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||||
|
|
||||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
consolidation()
|
||||||
if state.vars.jevylozeno == 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 = {}
|
|
||||||
limitka_old = state.vars.limitka
|
|
||||||
#print("Puvodni LIMITKA", limitka_old)
|
|
||||||
#zaciname s cistym stitem
|
|
||||||
state.vars.limitka = None
|
|
||||||
state.vars.limitka_price = None
|
|
||||||
limitka_found = False
|
|
||||||
limitka_qty = 0
|
|
||||||
limitka_filled_qty = 0
|
|
||||||
for o in orderlist:
|
|
||||||
if o.side == OrderSide.SELL:
|
|
||||||
|
|
||||||
if limitka_found:
|
|
||||||
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
|
||||||
result=state.interface.cancel(o.id)
|
|
||||||
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
|
||||||
continue
|
|
||||||
|
|
||||||
#print("Nalezena LIMITKA")
|
|
||||||
limitka_found = True
|
|
||||||
state.vars.limitka = o.id
|
|
||||||
state.vars.limitka_price = o.limit_price
|
|
||||||
limitka_qty = int(o.qty)
|
|
||||||
limitka_filled_qty = int(o.filled_qty)
|
|
||||||
|
|
||||||
#aktualni mnozstvi = puvodni minus filled
|
|
||||||
if limitka_filled_qty is not None:
|
|
||||||
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
|
||||||
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
|
||||||
##TODO sem pridat upravu ceny
|
|
||||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
|
||||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
#neni limitka, ale mela by byt - vytváříme ji
|
|
||||||
if int(state.positions) > 0 and state.vars.limitka is None:
|
|
||||||
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
|
||||||
price=get_limitka_price()
|
|
||||||
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
|
||||||
state.vars.limitka_price = price
|
|
||||||
if state.vars.limitka == -1:
|
|
||||||
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
|
||||||
state.vars.limitka = None
|
|
||||||
state.vars.limitka_price = None
|
|
||||||
else:
|
|
||||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
|
||||||
|
|
||||||
#existuje a nesedi mnozstvi nebo cena
|
|
||||||
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
|
||||||
#limitka existuje, ale spatne mnostvi - updatujeme
|
|
||||||
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
|
||||||
#snad to nespadne, kdyztak pridat exception handling
|
|
||||||
puvodni = state.vars.limitka
|
|
||||||
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
|
||||||
|
|
||||||
if state.vars.limitka == -1:
|
|
||||||
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
|
||||||
state.vars.limitka = puvodni
|
|
||||||
else:
|
|
||||||
limitka_qty = int(state.positions)
|
|
||||||
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
|
||||||
|
|
||||||
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
|
||||||
|
|
||||||
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(limitka)
|
|
||||||
#print(pendingbuys_new)
|
|
||||||
#print(pendingbuys)
|
|
||||||
#print(len(pendingbuys))
|
|
||||||
#print(len(pendingbuys_new))
|
|
||||||
#print(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"])
|
|
||||||
|
|
||||||
#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=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)
|
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)
|
||||||
|
|
||||||
#maxSlopeMA = -0.03
|
|
||||||
#SLOPE ANGLE PROTECTIONs
|
#SLOPE ANGLE PROTECTIONs
|
||||||
#slope zachycuje rychle sestupy
|
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
|
||||||
#slopeMA zachycuje táhlé sestupy
|
|
||||||
# try:
|
|
||||||
# slopeMA = state.indicators.slopeMA[-1]
|
|
||||||
# except Exception as e:
|
|
||||||
# slopeMA = 99
|
|
||||||
|
|
||||||
if slope < minimum_slope: # or slopeMA<maxSlopeMA:
|
if slope < minimum_slope: # or slopeMA<maxSlopeMA:
|
||||||
print("OCHRANA SLOPE TOO HIGH")
|
print("OCHRANA SLOPE TOO HIGH")
|
||||||
# if slopeMA<maxSlopeMA:
|
# if slopeMA<maxSlopeMA:
|
||||||
|
|||||||
@ -19,6 +19,7 @@ from tinydb.operations import set
|
|||||||
import json
|
import json
|
||||||
from numpy import ndarray
|
from numpy import ndarray
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
|
from datetime import timedelta, time
|
||||||
|
|
||||||
arch_header_file = DATA_DIR + "/arch_header.json"
|
arch_header_file = DATA_DIR + "/arch_header.json"
|
||||||
arch_detail_file = DATA_DIR + "/arch_detail.json"
|
arch_detail_file = DATA_DIR + "/arch_detail.json"
|
||||||
@ -526,8 +527,15 @@ def get_alpaca_history_bars(symbol: str, datetime_object_from: datetime, datetim
|
|||||||
#print("before df")
|
#print("before df")
|
||||||
bars = client.get_stock_bars(bar_request)
|
bars = client.get_stock_bars(bar_request)
|
||||||
result = []
|
result = []
|
||||||
|
##pridavame pro jistotu minutu z obou stran kvuli frontendu
|
||||||
|
business_hours = {
|
||||||
|
# monday = 0, tuesday = 1, ... same pattern as date.weekday()
|
||||||
|
"weekdays": [0, 1, 2, 3, 4],
|
||||||
|
"from": time(hour=9, minute=28),
|
||||||
|
"to": time(hour=16, minute=2)
|
||||||
|
}
|
||||||
for row in bars.data[symbol]:
|
for row in bars.data[symbol]:
|
||||||
if is_open_hours(row.timestamp):
|
if is_open_hours(row.timestamp, business_hours):
|
||||||
result.append(row)
|
result.append(row)
|
||||||
|
|
||||||
# print("df", bars)
|
# print("df", bars)
|
||||||
|
|||||||
@ -55,8 +55,14 @@ function transform_data(data) {
|
|||||||
//light chart neumi vice zaznamu ve stejny cas
|
//light chart neumi vice zaznamu ve stejny cas
|
||||||
//protoze v BT se muze stat vice tradu v jeden cas, testujeme stejne hodnoty a pripadne pricteme jednu ms
|
//protoze v BT se muze stat vice tradu v jeden cas, testujeme stejne hodnoty a pripadne pricteme jednu ms
|
||||||
//tradu s jednim casem muze byt za sebou vic, proto iterator
|
//tradu s jednim casem muze byt za sebou vic, proto iterator
|
||||||
|
if (last_timestamp > timestamp) {
|
||||||
|
console.log("NEKONZISTENCE RAZENI",last_timestamp, timestamp)
|
||||||
|
console.log("aktualni trade", JSON.stringify(trade,null,2))
|
||||||
|
console.log("předchozí trade", JSON.stringify(data.trades[index-1],null,2))
|
||||||
|
}
|
||||||
if (last_timestamp == timestamp) {
|
if (last_timestamp == timestamp) {
|
||||||
last_timestamp = timestamp
|
last_timestamp = timestamp
|
||||||
|
console.log("DUPLICITA tradu", trade)
|
||||||
timestamp = timestamp + iterator
|
timestamp = timestamp + iterator
|
||||||
iterator += 0.001
|
iterator += 0.001
|
||||||
}
|
}
|
||||||
@ -78,7 +84,7 @@ function transform_data(data) {
|
|||||||
a_markers["position"] = "aboveBar"
|
a_markers["position"] = "aboveBar"
|
||||||
a_markers["color"] = "#e8c76d"
|
a_markers["color"] = "#e8c76d"
|
||||||
a_markers["shape"] = "arrowDown"
|
a_markers["shape"] = "arrowDown"
|
||||||
if (CHART_SHOW_TEXT)
|
//if (CHART_SHOW_TEXT)
|
||||||
// a_markers["text"] = trade.position_qty + " " + parseFloat(trade.pos_avg_price).toFixed(3)
|
// a_markers["text"] = trade.position_qty + " " + parseFloat(trade.pos_avg_price).toFixed(3)
|
||||||
a_markers["text"] = CHART_SHOW_TEXT ? trade.position_qty + "/" + parseFloat(trade.pos_avg_price).toFixed(3) :trade.position_qty
|
a_markers["text"] = CHART_SHOW_TEXT ? trade.position_qty + "/" + parseFloat(trade.pos_avg_price).toFixed(3) :trade.position_qty
|
||||||
avgp_markers.push(a_markers)
|
avgp_markers.push(a_markers)
|
||||||
@ -113,14 +119,22 @@ function transform_data(data) {
|
|||||||
// position: 'aboveBar',
|
// position: 'aboveBar',
|
||||||
// color: '#e91e63',
|
// color: '#e91e63',
|
||||||
// shape: 'arrowDown',
|
// shape: 'arrowDown',
|
||||||
// text: 'Sell @ ' + Math.floor(datesForMarkers[i].high + 2),
|
// text: 'Sell @ ' + Math.floor(datesForMarkers[i].high + 2),
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//pro jistotu jeste seradime podle casu
|
||||||
|
//v BT se muze predbehnout a lightweight to pak nezobrazi
|
||||||
|
const sorter = (a, b) => a.time > b.time ? 1 : -1;
|
||||||
|
|
||||||
|
markers.sort(sorter)
|
||||||
|
markers_line.sort(sorter)
|
||||||
|
|
||||||
transformed["avgp_buy_line"] = avgp_buy_line
|
transformed["avgp_buy_line"] = avgp_buy_line
|
||||||
|
transformed["avgp_markers"] = avgp_markers
|
||||||
transformed["markers"] = markers
|
transformed["markers"] = markers
|
||||||
transformed["markers_line"] = markers_line
|
transformed["markers_line"] = markers_line
|
||||||
transformed["avgp_markers"] = avgp_markers
|
|
||||||
//get additional indicators
|
//get additional indicators
|
||||||
return transformed
|
return transformed
|
||||||
}
|
}
|
||||||
@ -140,8 +154,13 @@ function prepare_data(archRunner, timeframe_amount, timeframe_unit, archivedRunn
|
|||||||
req["datetime_object_from"] = archRunner.started
|
req["datetime_object_from"] = archRunner.started
|
||||||
req["datetime_object_to"] = archRunner.stopped
|
req["datetime_object_to"] = archRunner.stopped
|
||||||
}
|
}
|
||||||
req["timeframe_amount"] = timeframe_amount
|
console.log("datum pred",req.datetime_object_from)
|
||||||
req["timeframe_unit"] = timeframe_unit
|
//pridame z obou stran 1 minutu - kvuli zobrazeni na frontendu,
|
||||||
|
req["datetime_object_from"] = subtractMinutes(new Date(req.datetime_object_from),1).toISOString()
|
||||||
|
req["datetime_object_to"] = addMinutes(new Date(req.datetime_object_to),1).toISOString()
|
||||||
|
console.log("datum po", req.datetime_object_from)
|
||||||
|
req["timeframe_amount"] = timeframe_amount
|
||||||
|
req["timeframe_unit"] = timeframe_unit
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url:"/history_bars/",
|
url:"/history_bars/",
|
||||||
beforeSend: function (xhr) {
|
beforeSend: function (xhr) {
|
||||||
@ -385,8 +404,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
|
|||||||
chart.removeSeries(markersLine)
|
chart.removeSeries(markersLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("avgp_buy_line",transformed_data["avgp_buy_line"])
|
//console.log("avgp_buy_line",JSON.stringify(transformed_data["avgp_buy_line"],null,2))
|
||||||
console.log("avgp_markers",transformed_data["avgp_markers"])
|
//console.log("avgp_markers",JSON.stringify(transformed_data["avgp_markers"],null,2))
|
||||||
|
|
||||||
if (transformed_data["avgp_buy_line"].length > 0) {
|
if (transformed_data["avgp_buy_line"].length > 0) {
|
||||||
avgBuyLine = chart.addLineSeries({
|
avgBuyLine = chart.addLineSeries({
|
||||||
@ -403,14 +422,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
avgBuyLine.setData(transformed_data["avgp_buy_line"]);
|
avgBuyLine.setData(transformed_data["avgp_buy_line"]);
|
||||||
}
|
avgBuyLine.setMarkers(transformed_data["avgp_markers"]);
|
||||||
catch (error) {
|
|
||||||
console.log("avgbuyline")
|
|
||||||
}
|
|
||||||
|
|
||||||
avgBuyLine.setMarkers(transformed_data["avgp_markers"])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
markersLine = chart.addLineSeries({
|
markersLine = chart.addLineSeries({
|
||||||
@ -421,8 +434,11 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
|
|||||||
lastValueVisible: false
|
lastValueVisible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
markersLine.setData(transformed_data["markers_line"]);
|
//console.log("markers_line",JSON.stringify(transformed_data["markers_line"],null,2))
|
||||||
markersLine.setMarkers(transformed_data["markers"])
|
//console.log("markers",JSON.stringify(transformed_data["markers"],null,2))
|
||||||
|
|
||||||
|
markersLine.setData(transformed_data["markers_line"]);
|
||||||
|
markersLine.setMarkers(transformed_data["markers"])
|
||||||
|
|
||||||
//chart.subscribeCrosshairMove(param => {
|
//chart.subscribeCrosshairMove(param => {
|
||||||
chart.subscribeCrosshairMove(param => {
|
chart.subscribeCrosshairMove(param => {
|
||||||
|
|||||||
@ -5,9 +5,6 @@ var logcnt = 0
|
|||||||
var positionsPriceLine = null
|
var positionsPriceLine = null
|
||||||
var limitkaPriceLine = null
|
var limitkaPriceLine = null
|
||||||
var angleSeries = 1
|
var angleSeries = 1
|
||||||
var candlestickSeries = null
|
|
||||||
var volumeSeries = null
|
|
||||||
var vwapSeries = null
|
|
||||||
|
|
||||||
//get details of runner to populate chart status
|
//get details of runner to populate chart status
|
||||||
//fetch necessary - it could be initiated by manually inserting runnerId
|
//fetch necessary - it could be initiated by manually inserting runnerId
|
||||||
|
|||||||
@ -5,6 +5,9 @@ var colors = ["#8B1874","#B71375","#B46060","#61c740","#BE6DB7","#898121","#4389
|
|||||||
var reset_colors = colors
|
var reset_colors = colors
|
||||||
var indList = []
|
var indList = []
|
||||||
var verticalSeries=null
|
var verticalSeries=null
|
||||||
|
var candlestickSeries = null
|
||||||
|
var volumeSeries = null
|
||||||
|
var vwapSeries = null
|
||||||
|
|
||||||
indConfig = {}
|
indConfig = {}
|
||||||
settings = {}
|
settings = {}
|
||||||
@ -89,11 +92,25 @@ function update_chart_legend(param) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function subtractMinutes(date, minutes) {
|
||||||
|
date.setMinutes(date.getMinutes() - minutes);
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMinutes(date, minutes) {
|
||||||
|
date.setMinutes(date.getMinutes() + minutes);
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
//remove previous chart if exists and intiialize chart variables
|
//remove previous chart if exists and intiialize chart variables
|
||||||
function cleanup_chart() {
|
function cleanup_chart() {
|
||||||
if (chart) {
|
if (chart) {
|
||||||
|
console.log("cleanup")
|
||||||
chart.remove()
|
chart.remove()
|
||||||
clear_status_header()
|
clear_status_header()
|
||||||
|
chart = null
|
||||||
indList = [];
|
indList = [];
|
||||||
markersLine = null
|
markersLine = null
|
||||||
avgBuyLine = null
|
avgBuyLine = null
|
||||||
|
|||||||
Binary file not shown.
@ -147,7 +147,7 @@ def is_close_rush(dt: datetime, mins: int = 30):
|
|||||||
rushtime = (datetime.combine(date.today(), business_hours["to"]) - timedelta(minutes=mins)).time()
|
rushtime = (datetime.combine(date.today(), business_hours["to"]) - timedelta(minutes=mins)).time()
|
||||||
return rushtime <= dt.time() <= business_hours["to"]
|
return rushtime <= dt.time() <= business_hours["to"]
|
||||||
|
|
||||||
def is_open_hours(dt):
|
def is_open_hours(dt, business_hours: dict = None):
|
||||||
""""
|
""""
|
||||||
Returns True if market is open that time. Holidays not implemented yet.
|
Returns True if market is open that time. Holidays not implemented yet.
|
||||||
|
|
||||||
@ -155,12 +155,13 @@ def is_open_hours(dt):
|
|||||||
dt = dt.astimezone(zoneNY)
|
dt = dt.astimezone(zoneNY)
|
||||||
#print("Ameriko time", dt)
|
#print("Ameriko time", dt)
|
||||||
|
|
||||||
business_hours = {
|
if business_hours is None:
|
||||||
# monday = 0, tuesday = 1, ... same pattern as date.weekday()
|
business_hours = {
|
||||||
"weekdays": [0, 1, 2, 3, 4],
|
# monday = 0, tuesday = 1, ... same pattern as date.weekday()
|
||||||
"from": time(hour=9, minute=30),
|
"weekdays": [0, 1, 2, 3, 4],
|
||||||
"to": time(hour=16, minute=0)
|
"from": time(hour=9, minute=30),
|
||||||
}
|
"to": time(hour=16, minute=0)
|
||||||
|
}
|
||||||
|
|
||||||
holidays = [date(2022, 12, 24), date(2022, 2, 24)]
|
holidays = [date(2022, 12, 24), date(2022, 2, 24)]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user