diff --git a/testy/asyncioRun.py b/testy/asyncioRun.py new file mode 100644 index 0000000..88b9235 --- /dev/null +++ b/testy/asyncioRun.py @@ -0,0 +1,7 @@ +import asyncio + +async def vysledek(): + return 100 + +a = asyncio.run(vysledek()) +print(a) \ No newline at end of file diff --git a/v2realbot/ENTRY_backtest_strategyVykladaci.py b/v2realbot/ENTRY_backtest_strategyVykladaci.py index 3311267..a8fd019 100644 --- a/v2realbot/ENTRY_backtest_strategyVykladaci.py +++ b/v2realbot/ENTRY_backtest_strategyVykladaci.py @@ -40,6 +40,7 @@ stratvars = AttributeDict(maxpozic = 250, 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], @@ -155,10 +156,10 @@ def next(data, state: StrategyState): slope_lookback = int(state.vars.slope_lookback) minimum_slope = float(state.vars.minimum_slope) - if len(state.indicators.ema) > slope_lookback: + if len(state.bars.close) > slope_lookback: #slope = ((state.indicators.ema[-1] - state.indicators.ema[-slope_lookback])/slope_lookback)*100 #PUVODNI slope = ((state.bars.close[-1] - state.bars.close[-slope_lookback])/slope_lookback)*100 - slope = ((state.bars.close[-1] - state.indicators.ema[-slope_lookback])/state.indicators.ema[-slope_lookback])*100 + slope = ((state.bars.close[-1] - state.bars.close[-slope_lookback])/state.bars.close[-slope_lookback])*100 #roc = ((state.indicators.ema[-1] - state.indicators.ema[-roc_lookback])/state.indicators.ema[-roc_lookback])*100 state.indicators.slope.append(slope) #state.indicators.roc.append(roc) @@ -166,6 +167,7 @@ def next(data, state: StrategyState): #ic(state.indicators.roc[-5:]) 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("is falling",isfalling(state.indicators.ema,state.vars.Trend)) print("is rising",isrising(state.indicators.ema,state.vars.Trend)) @@ -175,34 +177,54 @@ def next(data, state: StrategyState): ##CONSOLIDATION PART kazdy Nty bar dle nastaveni if int(data["index"])%int(state.vars.consolidation_bar_count) == 0: print("***Consolidation ENTRY***") + state.ilog(e="Konzolidujeme") orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None) #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 for o in orderlist: if o.side == OrderSide.SELL: print("Nalezena LIMITKA") + limitka_found = True state.vars.limitka = o.id + state.vars.limitka_price = o.limit_price + ##TODO sem pridat upravu ceny if o.side == OrderSide.BUY: pendingbuys_new[str(o.id)]=float(o.limit_price) - print("Nová LIMITKA", state.vars.limitka) + state.ilog(e="Konzolidace", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price) + + #neni limitka, ale mela by byt - vytváříme ji + if state.positions > 0 and state.vars.limitka is None: + state.ilog(e="Neni limitka, ale mela by být.") + price=price2dec(float(state.avgp)+state.vars.profit) + state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=state.positions)) + state.vars.limitka_price = price + state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_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 jevyloze", jevylozeno=state.vars.jevylozeno) #print(limitka) #print(pendingbuys_new) @@ -215,14 +237,21 @@ def next(data, state: StrategyState): else: print("no time for consolidation", data["index"]) + #HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru + lp = state.interface.get_last_price(symbol=state.symbol) + state.ilog(e="ITER_ENTRY", last_price=lp, stratvars=state.vars) + #SLOPE ANGLE PROTECTION + state.ilog(e="SLOPE", curr_slope=slope, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-5:]) if slope < minimum_slope: print("OCHRANA SLOPE TOO HIGH") + state.ilog(e="SLOPE_EXCEEDED") if len(state.vars.pendingbuys)>0: 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) print("slope", slope) print("min slope", minimum_slope) @@ -235,6 +264,7 @@ def next(data, state: StrategyState): ic(state.time) #zatim vykladame full #positions = int(int(state.vars.maxpozic)/int(state.vars.chunk)) + state.ilog(e="BUY SIGNAL", ema=state.indicators.ema[-1], trend=state.vars.Trend) vyloz() ## testuje aktualni cenu od nejvyssi visici limitky @@ -252,6 +282,7 @@ def next(data, state: StrategyState): print("max cena v orderbuys", maxprice) if state.interface.get_last_price(state.symbol) > float(maxprice) + state.vars.ticks2reset: print("ujelo to vice nez o " + str(state.vars.ticks2reset) + ", rusime limit buye") + state.ilog(e="Ujelo to o více " + str(state.vars.ticks2reset), msg="rusime PB buye") ##TODO toto nejak vymyslet - duplikovat? res = asyncio.run(state.cancel_pending_buys()) @@ -268,6 +299,7 @@ def next(data, state: StrategyState): 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 ?? @@ -305,6 +337,7 @@ def init(state: StrategyState): state.indicators['ema'] = [] state.indicators['slope'] = [] #state.indicators['roc'] = [] + #state.ilog(e="INIT", stratvars=state.vars) def main(): diff --git a/v2realbot/main.py b/v2realbot/main.py index a22ffa3..91b2edd 100644 --- a/v2realbot/main.py +++ b/v2realbot/main.py @@ -113,7 +113,7 @@ async def websocket_endpoint( if data=="break": break await ws.send_text(data) - print("WSTX thread received data", data) + print("WSTX thread received data") #,data) except Empty: print("WSTX thread Heartbeat. No data received from queue.") continue diff --git a/v2realbot/static/index.html b/v2realbot/static/index.html index f16ddc8..0facb64 100644 --- a/v2realbot/static/index.html +++ b/v2realbot/static/index.html @@ -16,6 +16,30 @@
+ + +
+
12233 Event
+
+ Detaila mozna structured + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +
+
+ +
+
12233 Event
+
+ Detaila mozna structured + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +
+
+ + +

Status: Not connected

@@ -26,11 +50,16 @@
- - +
+
+
+
+
+
+
+
diff --git a/v2realbot/static/js/mychart.js b/v2realbot/static/js/mychart.js index db8616c..15ca211 100644 --- a/v2realbot/static/js/mychart.js +++ b/v2realbot/static/js/mychart.js @@ -1,16 +1,18 @@ //const chartOptions = { layout: { textColor: 'black', background: { type: 'solid', color: 'white' } } }; -const chartOptions = { width: 1200, height: 600, leftPriceScale: {visible: true}} +const chartOptions = { width: 1045, height: 600, leftPriceScale: {visible: true}} const chart = LightweightCharts.createChart(document.getElementById('chart'), chartOptions); chart.applyOptions({ timeScale: { visible: true, timeVisible: true, secondsVisible: true }, crosshair: { mode: LightweightCharts.CrosshairMode.Normal, labelVisible: true }}) -const candlestickSeries = chart.addCandlestickSeries(); +const candlestickSeries = chart.addCandlestickSeries({ lastValueVisible: true, priceLineWidth:2, priceLineColor: "red", priceFormat: { type: 'price', precision: 2, minMove: 0.01 }}); candlestickSeries.priceScale().applyOptions({ scaleMargins: { top: 0.1, // highest point of the series will be 10% away from the top bottom: 0.4, // lowest point will be 40% away from the bottom }, }); + + const volumeSeries = chart.addHistogramSeries({title: "Volume", color: '#26a69a', priceFormat: {type: 'volume'}, priceScaleId: ''}); volumeSeries.priceScale().applyOptions({ // set the positioning of the volume series @@ -21,11 +23,13 @@ volumeSeries.priceScale().applyOptions({ }); const vwapSeries = chart.addLineSeries({ - title: "vwap", +// title: "vwap", color: '#2962FF', lineWidth: 1, + lastValueVisible: false }) +chart.timeScale().fitContent(); //TBD dynamicky zobrazovat vsechny indikatory //document.getElementById('chart').style.display = 'inline-block'; @@ -54,7 +58,7 @@ chart.subscribeCrosshairMove((param) => { firstRow.innerText += item.name + " " + ind.value + " "; }); - firstRow.innerText += 'vwap' + ' ' + vwap.toFixed(2) + " o" + bars.open + " h" + bars.high + " l" + bars.low + " c" + bars.close + " v" + volumes.value; + firstRow.innerText += ' vwap' + ' ' + vwap.toFixed(2) + " O" + bars.open + " H" + bars.high + " L" + bars.low + " C" + bars.close + " V" + volumes.value + ""; } else { firstRow.innerText = '-'; diff --git a/v2realbot/static/js/mywebsocket.js b/v2realbot/static/js/mywebsocket.js index b45073f..1977473 100644 --- a/v2realbot/static/js/mywebsocket.js +++ b/v2realbot/static/js/mywebsocket.js @@ -1,6 +1,9 @@ const momentumIndicatorNames = ["roc", "slope"] var indList = [] +var pbiList = [] var ws = null; +var positionsPriceLine = null +var limitkaPriceLine = null function connect(event) { var runnerId = document.getElementById("runnerId") try { @@ -16,12 +19,6 @@ function connect(event) { document.getElementById("chart").style.display = "block" } ws.onmessage = function(event) { - //var messages = document.getElementById('messages') - //var message = document.createElement('li') - //var content = document.createTextNode(event.data) - //message.appendChild(content) - //messages.appendChild(message) - var parsed_data = JSON.parse(event.data) console.log(JSON.stringify(parsed_data)) @@ -53,6 +50,107 @@ function connect(event) { }); } + //loglist + if (parsed_data.hasOwnProperty("iter_log")) { + iterLogList = parsed_data.iter_log + console.log("Incoming logline object") + + var lines = document.getElementById('lines') + var line = document.createElement('div') + line.classList.add("line") + const newLine = document.createTextNode("-----------------NEXT ITER------------------") + line.appendChild(newLine) + lines.appendChild(line) + + iterLogList.forEach((logLine) => { + console.log("logline item") + console.log(JSON.stringify(logLine,null,2)) + row = logLine.time + " " + logLine.event + ":" + logLine.message; + str_row = JSON.stringify(logLine.details, null, 2) + var lines = document.getElementById('lines') + var line = document.createElement('div') + line.classList.add("line") + //const newLine = document.createTextNode(row) + line.insertAdjacentHTML( 'beforeend', row ); + //line.appendChild(newLine) + var pre = document.createElement("span") + pre.classList.add("pidi") + const stLine = document.createTextNode(str_row) + pre.appendChild(stLine) + line.appendChild(pre) + lines.appendChild(line) + }); + $('#messages').animate({ + scrollTop: $('#lines')[0].scrollHeight}, 2000); + } + + //limitka + if (parsed_data.hasOwnProperty("limitka")) { + limitka = parsed_data.limitka + const limitkaLine = { + price: limitka.price, + color: '#1ed473', + lineWidth: 1, + lineStyle: 1, // LineStyle.Dotted + axisLabelVisible: true, + title: "SELL:XX", + }; + + if (limitkaPriceLine !== null) { + candlestickSeries.removePriceLine(limitkaPriceLine) + } + limitkaPriceLine = candlestickSeries.createPriceLine(limitkaLine); + } + + + if (parsed_data.hasOwnProperty("pendingbuys")) { + pendingbuys = parsed_data.pendingbuys + + //vymazeme vsechny predchozi instance pendingbuys + if (pbiList.length) { + console.log(pbiList) + pbiList.forEach((line) => { + candlestickSeries.removePriceLine(line) + }); + pbiList = [] + } + + //zobrazime pendingbuys a ulozime instance do pole + console.log("pred loopem") + for (const [orderid, price] of Object.entries(pendingbuys)) { + console.log("v loopu", price) + const pbLine = { + price: parseFloat(price), + color: "#e3a059", + lineWidth: 1, + lineStyle: 1, // LineStyle.Dotted + axisLabelVisible: true, + title: "BUY:", + }; + + pbLineInstance = candlestickSeries.createPriceLine(pbLine); + pbiList.push(pbLineInstance) + } + + } + + if (parsed_data.hasOwnProperty("positions")) { + positions = parsed_data.positions + const posLine = { + price: positions.avgp, + color: 'black', + lineWidth: 1, + lineStyle: 1, // LineStyle.Dotted + axisLabelVisible: true, + title: "POS:"+positions.positions, + }; + + if (positionsPriceLine !== null) { + candlestickSeries.removePriceLine(positionsPriceLine) + } + positionsPriceLine = candlestickSeries.createPriceLine(posLine); + } + if (parsed_data.hasOwnProperty("indicators")) { var indicators = parsed_data.indicators //if there are indicators it means there must be at least two keys (except time which is always present) @@ -73,8 +171,9 @@ function connect(event) { } else { obj.series = chart.addLineSeries({ - title: key, + //title: key, lineWidth: 1, + lastValueVisible: false }) } obj.series.update({ @@ -95,6 +194,7 @@ function connect(event) { console.log(`${key}: ${value}`); } } + //chart.timeScale().fitContent(); } } ws.onclose = function(event) { diff --git a/v2realbot/static/main.css b/v2realbot/static/main.css index 7958b55..0f61487 100644 --- a/v2realbot/static/main.css +++ b/v2realbot/static/main.css @@ -15,6 +15,7 @@ align-self: auto; order: 0; margin-inline-start: 50px; + padding-bottom: 10px; } .chartContainer { @@ -30,4 +31,36 @@ font-size: 16px; line-height: 18px; font-weight: 300; +} + +#msgContainer { + display: grid; + overflow: auto; + height: 568px; +} + +.msgContainerInner { + display: flex; + overflow: auto; + height: 568px; + flex-direction: column-reverse; +} + +pre { + display: block; + /* padding: 9.5px; */ + /* margin: 0 0 10px; */ + font-size: 10px; + /* line-height: 2.428571; */ + color: #333; + word-break: break-all; + word-wrap: break-word; + /* background-color: #f5f5f5; */ + /* border: 1px solid #ccc; */ + border-radius: 4px; +} + +.pidi { + display: block; + font-size: smaller; } \ No newline at end of file diff --git a/v2realbot/strategy/StrategyOrderLimitVykladaci.py b/v2realbot/strategy/StrategyOrderLimitVykladaci.py index af19a66..e8b6613 100644 --- a/v2realbot/strategy/StrategyOrderLimitVykladaci.py +++ b/v2realbot/strategy/StrategyOrderLimitVykladaci.py @@ -17,11 +17,13 @@ class StrategyOrderLimitVykladaci(Strategy): super().__init__(name, symbol, next, init, account, mode, stratvars, open_rush, close_rush, pe, se) async def orderUpdateBuy(self, data: TradeUpdate): - o: Order = data.order + self.state.ilog(e="NOT:BUY_NOT_INCOMING", status=o.status, orderid=str(o.id)) 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="NOT:BUY_NOT_DELETE_PB", msg="mazeme z pendingu", orderid=str(o.id), pb=self.state.vars.pendingbuys) print("limit buy filled or cancelled. Vyhazujeme z pendingbuys.") ic(self.state.vars.pendingbuys) @@ -34,13 +36,20 @@ class StrategyOrderLimitVykladaci(Strategy): self.state.avgp = float(data.price) price=price2dec(float(o.filled_avg_price)+self.state.vars.profit) self.state.vars.limitka = await self.interface.sell_l(price=price, size=o.filled_qty) + self.state.vars.limitka_price = price + self.state.ilog(e="NOT:BUY_NOT_LIMITKA_CREATE", msg="limitka neni vytvarime", orderid=str(o.id), limitka=str(self.state.vars.limitka), limtka_price=self.state.vars.limitka_price) else: #avgp, pos self.state.avgp, self.state.positions = self.state.interface.pos() cena = price2dec(float(self.state.avgp) + float(self.state.vars.profit)) try: + puvodni = self.state.vars.limitka self.state.vars.limitka = await self.interface.repl(price=cena,orderid=self.state.vars.limitka,size=int(self.state.positions)) + self.state.vars.limitka_price = cena + self.state.ilog(e="NOT:BUY_NOT_LIMITKA_REPLACE", msg="limitka existuje-replace", orderid=str(o.id), limitka=str(self.state.vars.limitka), limtka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni)) except APIError as e: + self.state.ilog(e="NOT:BUY_NOT_LIMITKA_REPLACE_ERROR", msg=str(e), orderid=str(o.id), limitka=str(self.state.vars.limitka), limitka_price=self.state.vars.limitka_price, puvodni_limitka=str(puvodni)) + #stejne parametry - stava se pri rychle obratce, nevadi if e.code == 42210000: return 0,0 else: @@ -49,6 +58,7 @@ class StrategyOrderLimitVykladaci(Strategy): async def orderUpdateSell(self, data: TradeUpdate): if data.event == TradeEvent.PARTIAL_FILL: + self.state.ilog(e="NOT:SELL_PARTIAL_FILL", msg="pouze update pozic", orderid=str(data.order.id)) ic("partial fill jen udpatujeme pozice") self.state.avgp, self.state.positions = self.interface.pos() elif data.event == TradeEvent.FILL or data.event == TradeEvent.CANCELED: @@ -60,9 +70,11 @@ class StrategyOrderLimitVykladaci(Strategy): 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="NOT:SELL_FILL_OR_CANCEL", msg="mazeme limitku a pb", 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): @@ -77,6 +89,7 @@ class StrategyOrderLimitVykladaci(Strategy): 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_REQ_MAX_POS_REACHED", msg="Pozadavek na buy, max pozic", curr_positions=self.state.positions) print("max mnostvi naplneno") return 0 if size is None: @@ -92,12 +105,13 @@ class StrategyOrderLimitVykladaci(Strategy): 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: - print("max mnostvi naplneno") + self.state.ilog(e="BUY_REQ_MAX_POS_REACHED", msg="Pozadavek na buy, max pozic", 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="BUY_REQ_ORDER_SENDING", msg="Pozadavek na buy, odesilame do if", price=price, size=size) order = self.state.interface.buy_l(price=price, size=size) print("ukladame pendingbuys") self.state.vars.pendingbuys[str(order)]=price @@ -105,9 +119,11 @@ class StrategyOrderLimitVykladaci(Strategy): self.state.vars.lastbuyindex = self.state.bars['index'][-1] ic(self.state.blockbuy) ic(self.state.vars.lastbuyindex) + self.state.ilog(e="BUY_REQ_ORDER_SENT", msg="Uloženo 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="CANCEL_ALL_PB_REQUESTED", 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: @@ -117,7 +133,9 @@ class StrategyOrderLimitVykladaci(Strategy): #nejprve vyhodime z pendingbuys self.state.vars.pendingbuys.pop(key, False) res = self.interface.cancel(key) + self.state.ilog(e="PB_CANCELLED", orderid=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="CANCEL_ALL_PB_FINISHED", pb=self.state.vars.pendingbuys) diff --git a/v2realbot/strategy/__pycache__/StrategyOrderLimitVykladaci.cpython-310.pyc b/v2realbot/strategy/__pycache__/StrategyOrderLimitVykladaci.cpython-310.pyc index 36e1869..70bd52c 100644 Binary files a/v2realbot/strategy/__pycache__/StrategyOrderLimitVykladaci.cpython-310.pyc and b/v2realbot/strategy/__pycache__/StrategyOrderLimitVykladaci.cpython-310.pyc differ diff --git a/v2realbot/strategy/__pycache__/base.cpython-310.pyc b/v2realbot/strategy/__pycache__/base.cpython-310.pyc index eb8e8da..bbca36c 100644 Binary files a/v2realbot/strategy/__pycache__/base.cpython-310.pyc and b/v2realbot/strategy/__pycache__/base.cpython-310.pyc differ diff --git a/v2realbot/strategy/base.py b/v2realbot/strategy/base.py index f2e0d75..782948c 100644 --- a/v2realbot/strategy/base.py +++ b/v2realbot/strategy/base.py @@ -251,6 +251,7 @@ class Strategy: elif self.pe.is_set(): print(current_thread().name, "Paused.") continue + #self.state.iter_log(event="INGEST",msg="New data ingested", item=item) print("New data ingested") #calling main loop self.strat_loop(item=item) @@ -339,7 +340,25 @@ class Strategy: rt_out["indicators"][key]= value[-1] except IndexError: pass - print(rt_out) + + #vkladame average price and positions, pokud existuji + #self.state.avgp , self.state.positions + rt_out["positions"] = dict(time=self.state.time, positions=self.state.positions, avgp=self.state.avgp) + + #vkladame limitku a pendingbuys + try: + rt_out["pendingbuys"] = self.state.vars.pendingbuys + rt_out["limitka"] = dict(id=self.state.vars.limitka, price=self.state.vars.limitka_price) + + except Exception as e: + print(str(e)) + pass + + #vkladame iteration log (do toho si muze instance vlozit cokoliv relavantniho pro danou iteraci) a po iteraci se smaze + if len(self.state.iter_log_list) > 0: + rt_out["iter_log"] = self.state.iter_log_list + + #print(rt_out) print("RTQUEUE INSERT") #send current values to Realtime display on frontend @@ -347,6 +366,10 @@ class Strategy: self.rtqueue.put(json.dumps(rt_out, default=json_serial)) print("RTQUEUE", self.rtqueue) + #cleaning iterlog lsit + #TODO pridat cistku i mimo RT blok + self.state.iter_log_list = [] + # inicializace poplatna typu strategie (např. u LIMITu dotažení existující limitky) def strat_init(self): @@ -448,4 +471,12 @@ class StrategyState: self.buy_l = self.interface.buy_l self.sell = self.interface.sell self.sell_l = self.interface.sell_l - self.cancel_pending_buys = None \ No newline at end of file + self.cancel_pending_buys = None + self.iter_log_list = [] + + def ilog(self, e: str = None, msg: str = None, **kwargs): + if e is None: + row = dict(time=self.time, message=msg, details=kwargs) + else: + row = dict(time=self.time, event=e, message=msg, details=kwargs) + self.iter_log_list.append(row) \ No newline at end of file