gui sortovani tradu pred zobrazenim

This commit is contained in:
David Brazda
2023-05-10 15:07:29 +02:00
parent 6d8095e1ab
commit c76c4ed4ba
7 changed files with 213 additions and 192 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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 => {

View File

@ -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

View File

@ -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

View File

@ -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)]