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.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
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 icecream import install, ic
#from icecream import install, ic
#from rich import print
from threading import Event
from msgpack import packb, unpackb
import asyncio
import os
import tomli
install()
ic.configureOutput(includeContext=True)
from traceback import format_exc
# install()
# ic.configureOutput(includeContext=True)
#ic.disable()
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@ -116,6 +117,116 @@ def next(data, state: StrategyState):
else:
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
def vyloz():
##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
#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.bars.confirmed[-1] == 0:
print("OCHR: multibuy protection. waiting for next bar")
@ -193,42 +303,30 @@ def next(data, state: StrategyState):
state.ilog(e="-----")
#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.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
#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)
minimum_slope = float(state.vars.minimum_slope)
lookback_offset = int(state.vars.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_do = slope_lookback
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
@ -240,157 +338,41 @@ def next(data, state: StrategyState):
slope = round(slope, 4)
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.indicators.roc.append(roc)
#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 vyrovna vykyvy ve slope, dále pracujeme se slopeMA
slope_MA_length = 5
state.indicators.slopeMA = ema(state.indicators.slope, slope_MA_length) #state.bars.vwap
# #TODO - docasne posilam cele MA
# try:
# state.ilog(e="Slope - MA"+str(state.indicators.slopeMA[-1]), slopeMA=str(state.indicators.slopeMA[-20:]))
# except Exception as e:
# state.ilog(e="Slope - MA"+str(state.indicators.slopeMA[-1]))
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.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:
#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.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 Indicator section", str(e))
state.ilog(e="EXCEPTION", msg="Exception in NEXT Indicator section" + str(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 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
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"])
consolidation()
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
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)
#maxSlopeMA = -0.03
#SLOPE ANGLE PROTECTIONs
#slope zachycuje rychle sestupy
#slopeMA zachycuje táhlé sestupy
# try:
# slopeMA = state.indicators.slopeMA[-1]
# except Exception as e:
# slopeMA = 99
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
if slope < minimum_slope: # or slopeMA<maxSlopeMA:
print("OCHRANA SLOPE TOO HIGH")
# if slopeMA<maxSlopeMA:

View File

@ -19,6 +19,7 @@ from tinydb.operations import set
import json
from numpy import ndarray
from traceback import format_exc
from datetime import timedelta, time
arch_header_file = DATA_DIR + "/arch_header.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")
bars = client.get_stock_bars(bar_request)
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]:
if is_open_hours(row.timestamp):
if is_open_hours(row.timestamp, business_hours):
result.append(row)
# print("df", bars)

View File

@ -55,8 +55,14 @@ function transform_data(data) {
//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
//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) {
last_timestamp = timestamp
console.log("DUPLICITA tradu", trade)
timestamp = timestamp + iterator
iterator += 0.001
}
@ -78,7 +84,7 @@ function transform_data(data) {
a_markers["position"] = "aboveBar"
a_markers["color"] = "#e8c76d"
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"] = CHART_SHOW_TEXT ? trade.position_qty + "/" + parseFloat(trade.pos_avg_price).toFixed(3) :trade.position_qty
avgp_markers.push(a_markers)
@ -115,12 +121,20 @@ function transform_data(data) {
// shape: 'arrowDown',
// 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_markers"] = avgp_markers
transformed["markers"] = markers
transformed["markers_line"] = markers_line
transformed["avgp_markers"] = avgp_markers
//get additional indicators
return transformed
}
@ -140,8 +154,13 @@ function prepare_data(archRunner, timeframe_amount, timeframe_unit, archivedRunn
req["datetime_object_from"] = archRunner.started
req["datetime_object_to"] = archRunner.stopped
}
req["timeframe_amount"] = timeframe_amount
req["timeframe_unit"] = timeframe_unit
console.log("datum pred",req.datetime_object_from)
//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({
url:"/history_bars/",
beforeSend: function (xhr) {
@ -385,8 +404,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
chart.removeSeries(markersLine)
}
console.log("avgp_buy_line",transformed_data["avgp_buy_line"])
console.log("avgp_markers",transformed_data["avgp_markers"])
//console.log("avgp_buy_line",JSON.stringify(transformed_data["avgp_buy_line"],null,2))
//console.log("avgp_markers",JSON.stringify(transformed_data["avgp_markers"],null,2))
if (transformed_data["avgp_buy_line"].length > 0) {
avgBuyLine = chart.addLineSeries({
@ -403,14 +422,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
});
try {
avgBuyLine.setData(transformed_data["avgp_buy_line"]);
}
catch (error) {
console.log("avgbuyline")
}
avgBuyLine.setMarkers(transformed_data["avgp_markers"])
avgBuyLine.setMarkers(transformed_data["avgp_markers"]);
}
markersLine = chart.addLineSeries({
@ -421,8 +434,11 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
lastValueVisible: false
});
markersLine.setData(transformed_data["markers_line"]);
markersLine.setMarkers(transformed_data["markers"])
//console.log("markers_line",JSON.stringify(transformed_data["markers_line"],null,2))
//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 => {

View File

@ -5,9 +5,6 @@ var logcnt = 0
var positionsPriceLine = null
var limitkaPriceLine = null
var angleSeries = 1
var candlestickSeries = null
var volumeSeries = null
var vwapSeries = null
//get details of runner to populate chart status
//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 indList = []
var verticalSeries=null
var candlestickSeries = null
var volumeSeries = null
var vwapSeries = null
indConfig = {}
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
function cleanup_chart() {
if (chart) {
console.log("cleanup")
chart.remove()
clear_status_header()
chart = null
indList = [];
markersLine = 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()
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.
@ -155,12 +155,13 @@ def is_open_hours(dt):
dt = dt.astimezone(zoneNY)
#print("Ameriko time", dt)
business_hours = {
# monday = 0, tuesday = 1, ... same pattern as date.weekday()
"weekdays": [0, 1, 2, 3, 4],
"from": time(hour=9, minute=30),
"to": time(hour=16, minute=0)
}
if business_hours is None:
business_hours = {
# monday = 0, tuesday = 1, ... same pattern as date.weekday()
"weekdays": [0, 1, 2, 3, 4],
"from": time(hour=9, minute=30),
"to": time(hour=16, minute=0)
}
holidays = [date(2022, 12, 24), date(2022, 2, 24)]