angle scope implemented
This commit is contained in:
@ -32,10 +32,10 @@ Více nakupuje oproti Dokupovaci. Tady vylozime a nakupujeme 5 pozic hned. Pri d
|
||||
Do budoucna vice ridit nakupy pri klesani - napr. vyložení jen 2-3 pozic a další dokupy až po triggeru.
|
||||
#
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 250,
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
chunk = 10,
|
||||
MA = 3,
|
||||
Trend = 3,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
@ -47,8 +47,9 @@ stratvars = AttributeDict(maxpozic = 250,
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 20,
|
||||
minimum_slope = -0.23
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
@ -108,6 +109,7 @@ def next(data, state: StrategyState):
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg="first price"+str(price) + "pozic:"+str(vykladka), curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
@ -140,7 +142,6 @@ def next(data, state: StrategyState):
|
||||
|
||||
## slope vyresi rychlé sesupy - jeste je treba podchytit pomalejsi sesupy
|
||||
|
||||
|
||||
slope = 99
|
||||
#minimum slope disabled if -1
|
||||
|
||||
@ -156,15 +157,30 @@ def next(data, state: StrategyState):
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
|
||||
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.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
|
||||
if len(state.bars.close) > slope_lookback + state.vars.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 + state.vars.lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = sum(lookbackprice_array)/state.vars.lookback_offset
|
||||
|
||||
#výpočet úhlu
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
state.indicators.slope.append(slope)
|
||||
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice)
|
||||
|
||||
#state.indicators.roc.append(roc)
|
||||
print("slope", state.indicators.slope[-5:])
|
||||
#ic(state.indicators.roc[-5:])
|
||||
state.ilog(e="Slope "+str(slope), msg="lookback price:"+str(lookbackprice), lookbackoffset=state.vars.lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-5:])
|
||||
else:
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback)
|
||||
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in NEXT Indicator section" + str(e))
|
||||
@ -177,7 +193,7 @@ 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")
|
||||
state.ilog(e="***Konzolidujeme")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#print(orderlist)
|
||||
@ -198,11 +214,11 @@ def next(data, state: StrategyState):
|
||||
if o.side == OrderSide.BUY:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
state.ilog(e="Konzolidace", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price)
|
||||
state.ilog(e="Konzolidace limitky", msg="limitka stejna?:"+str((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)
|
||||
|
||||
#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.")
|
||||
state.ilog(e="Limitka neni, 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
|
||||
@ -224,7 +240,7 @@ def next(data, state: StrategyState):
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevyloze", jevylozeno=state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
#print(limitka)
|
||||
#print(pendingbuys_new)
|
||||
@ -233,25 +249,25 @@ def next(data, state: StrategyState):
|
||||
#print(len(pendingbuys_new))
|
||||
#print(jevylozeno)
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
|
||||
state.ilog(e="***Konzolidace konec")
|
||||
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
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ITER_ENTRY", last_price=lp, stratvars=state.vars)
|
||||
state.ilog(e="ENTRY", msg="AVGP:"+str(state.avgp)+ "POS:" +str(state.positions), 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")
|
||||
state.ilog(e="Slope too high "+str(slope))
|
||||
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)
|
||||
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
print("slope", slope)
|
||||
print("min slope", minimum_slope)
|
||||
|
||||
@ -264,7 +280,6 @@ 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
|
||||
@ -281,10 +296,9 @@ def next(data, state: StrategyState):
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
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())
|
||||
state.ilog(e="UJELO to o více " + str(state.vars.ticks2reset), msg="zrusene pb buye", pb=state.vars.pendingbuys)
|
||||
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
@ -336,6 +350,9 @@ def init(state: StrategyState):
|
||||
print("INIT v main",state.name)
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = {}
|
||||
|
||||
#state.indicators['roc'] = []
|
||||
#state.ilog(e="INIT", stratvars=state.vars)
|
||||
|
||||
@ -351,15 +368,15 @@ def main():
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaci(name = name, symbol = "BAC", account=Account.ACCOUNT2, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se)
|
||||
s = StrategyOrderLimitVykladaci(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 10, 9, 30, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 10, 9, 35, 0, 0, tzinfo=zoneNY),
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=5,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=True)
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
|
||||
@ -16,30 +16,6 @@
|
||||
<body>
|
||||
<div id="main" class="mainConteiner flex-container">
|
||||
<div id="chartContainer" class="flex-items">
|
||||
|
||||
|
||||
<div class="line">
|
||||
<div data-toggle="collapse" data-target="#rec1">12233 <strong>Event</strong></div>
|
||||
<div id="rec1" class="collapse">
|
||||
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.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div data-toggle="collapse" data-target="#rec2">12233 <strong>Event</strong></div>
|
||||
<div id="rec2" class="collapse">
|
||||
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.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4>Status: <span id="status">Not connected</span></h4>
|
||||
<div id="formular">
|
||||
<form action="">
|
||||
@ -286,7 +262,11 @@
|
||||
<div class="form-group">
|
||||
<label for="cash" class="control-label">cash</label>
|
||||
<input type="number" class="form-control" id="cash" name="cash" placeholder="cash" value="100000">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="cash" class="control-label">Subscribe for RT</label>
|
||||
<input type="checkbox" class="form-control" id="subscribe" name="subscribe">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<!--<input type="hidden" name="id" id="id" />-->
|
||||
|
||||
@ -29,7 +29,7 @@ const vwapSeries = chart.addLineSeries({
|
||||
lastValueVisible: false
|
||||
})
|
||||
|
||||
chart.timeScale().fitContent();
|
||||
//chart.timeScale().fitContent();
|
||||
|
||||
//TBD dynamicky zobrazovat vsechny indikatory
|
||||
//document.getElementById('chart').style.display = 'inline-block';
|
||||
|
||||
@ -399,6 +399,7 @@ $("#runModal").on('submit','#runForm', function(event){
|
||||
localStorage.setItem("debug", $('#debug').val());
|
||||
event.preventDefault();
|
||||
$('#run').attr('disabled','disabled');
|
||||
|
||||
var formData = $(this).serializeJSON();
|
||||
//rename runid to id
|
||||
Object.defineProperty(formData, "id", Object.getOwnPropertyDescriptor(formData, "runid"));
|
||||
@ -415,7 +416,13 @@ $("#runModal").on('submit','#runForm', function(event){
|
||||
method:"PUT",
|
||||
contentType: "application/json",
|
||||
data: jsonString,
|
||||
success:function(data){
|
||||
success:function(data){
|
||||
//pokud mame subscribnuto na RT
|
||||
if ($('#subscribe').prop('checked')) {
|
||||
//subscribe input value gets id of current runner
|
||||
$('#runnerId').val($('#runid').val());
|
||||
$( "#bt-conn" ).trigger( "click" );
|
||||
}
|
||||
$('#runForm')[0].reset();
|
||||
window.$('#runModal').modal('hide');
|
||||
$('#run').attr('disabled', false);
|
||||
|
||||
@ -2,8 +2,11 @@ const momentumIndicatorNames = ["roc", "slope"]
|
||||
var indList = []
|
||||
var pbiList = []
|
||||
var ws = null;
|
||||
var logcnt = 0
|
||||
var positionsPriceLine = null
|
||||
var limitkaPriceLine = null
|
||||
var angleSeries = 1
|
||||
|
||||
function connect(event) {
|
||||
var runnerId = document.getElementById("runnerId")
|
||||
try {
|
||||
@ -21,7 +24,7 @@ function connect(event) {
|
||||
ws.onmessage = function(event) {
|
||||
var parsed_data = JSON.parse(event.data)
|
||||
|
||||
console.log(JSON.stringify(parsed_data))
|
||||
//console.log(JSON.stringify(parsed_data))
|
||||
|
||||
//check received data and display lines
|
||||
if (parsed_data.hasOwnProperty("bars")) {
|
||||
@ -38,6 +41,7 @@ function connect(event) {
|
||||
}
|
||||
|
||||
if (parsed_data.hasOwnProperty("bars")) {
|
||||
console.log("mame bary")
|
||||
var bar = parsed_data.bars
|
||||
candlestickSeries.update(bar);
|
||||
volumeSeries.update({
|
||||
@ -53,7 +57,7 @@ function connect(event) {
|
||||
//loglist
|
||||
if (parsed_data.hasOwnProperty("iter_log")) {
|
||||
iterLogList = parsed_data.iter_log
|
||||
console.log("Incoming logline object")
|
||||
//console.log("Incoming logline object")
|
||||
|
||||
var lines = document.getElementById('lines')
|
||||
var line = document.createElement('div')
|
||||
@ -63,21 +67,38 @@ function connect(event) {
|
||||
lines.appendChild(line)
|
||||
|
||||
iterLogList.forEach((logLine) => {
|
||||
console.log("logline item")
|
||||
console.log(JSON.stringify(logLine,null,2))
|
||||
row = logLine.time + " <strong>" + logLine.event + "</strong>:" + logLine.message;
|
||||
//console.log("logline item")
|
||||
//console.log(JSON.stringify(logLine,null,2))
|
||||
|
||||
// <div class="line">
|
||||
// <div data-toggle="collapse" data-target="#rec1">12233 <strong>Event</strong></div>
|
||||
// <div id="rec1" class="collapse">
|
||||
// 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.
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
|
||||
logcnt++;
|
||||
row = '<div data-toggle="collapse" data-target="#rec'+logcnt+'">'+logLine.time + " " + logLine.event + ' - '+ logLine.message+'</div>'
|
||||
str_row = JSON.stringify(logLine.details, null, 2)
|
||||
|
||||
row_detail = '<div id="rec'+logcnt+'" class="collapse pidi"><pre>' + str_row + '</pre></div>'
|
||||
|
||||
var lines = document.getElementById('lines')
|
||||
var line = document.createElement('div')
|
||||
line.classList.add("line")
|
||||
//const newLine = document.createTextNode(row)
|
||||
|
||||
line.insertAdjacentHTML( 'beforeend', row );
|
||||
line.insertAdjacentHTML( 'beforeend', row_detail );
|
||||
//line.appendChild(newLine)
|
||||
var pre = document.createElement("span")
|
||||
pre.classList.add("pidi")
|
||||
const stLine = document.createTextNode(str_row)
|
||||
pre.appendChild(stLine)
|
||||
line.appendChild(pre)
|
||||
//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({
|
||||
@ -100,7 +121,7 @@ function connect(event) {
|
||||
candlestickSeries.removePriceLine(limitkaPriceLine)
|
||||
}
|
||||
limitkaPriceLine = candlestickSeries.createPriceLine(limitkaLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (parsed_data.hasOwnProperty("pendingbuys")) {
|
||||
@ -108,7 +129,7 @@ function connect(event) {
|
||||
|
||||
//vymazeme vsechny predchozi instance pendingbuys
|
||||
if (pbiList.length) {
|
||||
console.log(pbiList)
|
||||
//console.log(pbiList)
|
||||
pbiList.forEach((line) => {
|
||||
candlestickSeries.removePriceLine(line)
|
||||
});
|
||||
@ -116,9 +137,9 @@ function connect(event) {
|
||||
}
|
||||
|
||||
//zobrazime pendingbuys a ulozime instance do pole
|
||||
console.log("pred loopem")
|
||||
//console.log("pred loopem")
|
||||
for (const [orderid, price] of Object.entries(pendingbuys)) {
|
||||
console.log("v loopu", price)
|
||||
//console.log("v loopu", price)
|
||||
const pbLine = {
|
||||
price: parseFloat(price),
|
||||
color: "#e3a059",
|
||||
@ -149,52 +170,99 @@ function connect(event) {
|
||||
candlestickSeries.removePriceLine(positionsPriceLine)
|
||||
}
|
||||
positionsPriceLine = candlestickSeries.createPriceLine(posLine);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed_data.hasOwnProperty("statinds")) {
|
||||
console.log("got static indicators")
|
||||
var statinds = parsed_data.statinds
|
||||
if (Object.keys(statinds).length > 0) {
|
||||
console.log("got static indicators")
|
||||
console.log(JSON.stringify(statinds))
|
||||
|
||||
for (const [klic, hodnota] of Object.entries(statinds)) {
|
||||
console.log(JSON.stringify(klic))
|
||||
console.log(JSON.stringify(hodnota))
|
||||
|
||||
if (klic === "angle") {
|
||||
|
||||
//nejsou vsechny hodnoty
|
||||
if (Object.keys(hodnota).length > 0) {
|
||||
console.log("angle nalezen");
|
||||
console.log(JSON.stringify(hodnota));
|
||||
if (angleSeries !== 1) {
|
||||
console.log("angle neni jedna" + toString(angleSeries))
|
||||
chart.removeSeries(angleSeries)
|
||||
}
|
||||
|
||||
angleSeries = chart.addLineSeries({
|
||||
//title: key,
|
||||
lineWidth: 2,
|
||||
lineStyle: 2,
|
||||
color: "#d432e6",
|
||||
lastValueVisible: false,
|
||||
priceLineVisible: false
|
||||
})
|
||||
dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
|
||||
console.log("pridano")
|
||||
console.log(toString(dataPoints))
|
||||
angleSeries.setData(dataPoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed_data.hasOwnProperty("indicators")) {
|
||||
console.log("jsme uvnitr indikatoru")
|
||||
var indicators = parsed_data.indicators
|
||||
//if there are indicators it means there must be at least two keys (except time which is always present)
|
||||
if (Object.keys(indicators).length > 1) {
|
||||
for (const [key, value] of Object.entries(indicators)) {
|
||||
if (key !== "time") {
|
||||
//if indicator exists in array, initialize it and store reference to array
|
||||
//if indicator doesnt exists in array, initialize it and store reference to array
|
||||
const searchObject= indList.find((obj) => obj.name==key);
|
||||
if (searchObject == undefined) {
|
||||
console.log("object new - init and add")
|
||||
//console.log("object new - init and add")
|
||||
var obj = {name: key, series: null}
|
||||
if (momentumIndicatorNames.includes(key)) {
|
||||
obj.series = chart.addLineSeries({
|
||||
priceScaleId: 'left',
|
||||
title: key,
|
||||
lineWidth: 1,
|
||||
})
|
||||
lineWidth: 1
|
||||
});
|
||||
}
|
||||
else {
|
||||
obj.series = chart.addLineSeries({
|
||||
//title: key,
|
||||
lineWidth: 1,
|
||||
lastValueVisible: false
|
||||
})
|
||||
});
|
||||
}
|
||||
obj.series.update({
|
||||
time: indicators.time,
|
||||
value: value});
|
||||
indList.push(obj)
|
||||
indList.push(obj);
|
||||
}
|
||||
//indicator exists in an array, let update it
|
||||
//indicator exists in an array, lets update it
|
||||
else {
|
||||
console.log("object found - update")
|
||||
//console.log("object found - update")
|
||||
searchObject.series.update({
|
||||
time: indicators.time,
|
||||
value: value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
//chart.timeScale().fitContent();
|
||||
}
|
||||
}
|
||||
ws.onclose = function(event) {
|
||||
|
||||
@ -61,6 +61,6 @@ pre {
|
||||
}
|
||||
|
||||
.pidi {
|
||||
display: block;
|
||||
/* display: block; */
|
||||
font-size: smaller;
|
||||
}
|
||||
@ -18,12 +18,12 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
|
||||
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))
|
||||
self.state.ilog(e="Příchozí BUY notifikace", msg="order status:"+o.status, 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)
|
||||
self.state.ilog(e="Příchozí BUY notifikace - mazeme ji z pb", msg="order status:"+o.status, orderid=str(o.id), pb=self.state.vars.pendingbuys)
|
||||
print("limit buy filled or cancelled. Vyhazujeme z pendingbuys.")
|
||||
ic(self.state.vars.pendingbuys)
|
||||
|
||||
@ -37,7 +37,7 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
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)
|
||||
self.state.ilog(e="Příchozí BUY notif - vytvarime limitku", msg="order status:"+o.status, 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()
|
||||
@ -46,9 +46,9 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
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))
|
||||
self.state.ilog(e="Příchozí BUY notif - menime limitku", msg="order status:"+o.status, 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))
|
||||
self.state.ilog(e="API ERROR pri zmene limitky", 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
|
||||
@ -58,7 +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))
|
||||
self.state.ilog(e="SELL notifikace - 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:
|
||||
@ -74,7 +74,7 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
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)
|
||||
self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg="order status:"+ data.order.status, orderid=str(data.order.id), pb=self.state.vars.pendingbuys)
|
||||
|
||||
#this parent method is called by strategy just once before waiting for first data
|
||||
def strat_init(self):
|
||||
@ -89,7 +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)
|
||||
self.state.ilog(e="buy Maxim mnozstvi naplneno", curr_positions=self.state.positions)
|
||||
print("max mnostvi naplneno")
|
||||
return 0
|
||||
if size is None:
|
||||
@ -105,13 +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:
|
||||
self.state.ilog(e="BUY_REQ_MAX_POS_REACHED", msg="Pozadavek na buy, max pozic", price=price, size=size, curr_positions=self.state.positions)
|
||||
self.state.ilog(e="buyl Maxim mnozstvi naplneno", price=price, size=size, curr_positions=self.state.positions)
|
||||
return 0
|
||||
if size is None: size=self.state.vars.chunk
|
||||
if price is None: price=price2dec((self.state.interface.get_last_price(self.symbol)))
|
||||
ic(price)
|
||||
print("odesilame LIMIT s cenou/qty", price, size)
|
||||
self.state.ilog(e="BUY_REQ_ORDER_SENDING", msg="Pozadavek na buy, odesilame do if", price=price, size=size)
|
||||
self.state.ilog(e="odesilame buy_l 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
|
||||
@ -119,11 +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)
|
||||
self.state.ilog(e="Odslano a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
|
||||
|
||||
async def cancel_pending_buys(self):
|
||||
print("cancel pending buys called.")
|
||||
self.state.ilog(e="CANCEL_ALL_PB_REQUESTED", pb=self.state.vars.pendingbuys)
|
||||
self.state.ilog(e="Rusime pendingy", pb=self.state.vars.pendingbuys)
|
||||
##proto v pendingbuys pridano str(), protoze UUIN nejde serializovat
|
||||
##padalo na variable changed during iteration, pridano
|
||||
if len(self.state.vars.pendingbuys)>0:
|
||||
@ -133,9 +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))
|
||||
self.state.ilog(e="Pendingy zrusen pro"+str(key), orderid=str(key), res=str(res))
|
||||
print("CANCEL PENDING BUYS RETURN", res)
|
||||
self.state.vars.pendingbuys={}
|
||||
self.state.vars.jevylozeno = 0
|
||||
print("cancel pending buys end")
|
||||
self.state.ilog(e="CANCEL_ALL_PB_FINISHED", pb=self.state.vars.pendingbuys)
|
||||
self.state.ilog(e="Dokončeno zruseni vsech pb", pb=self.state.vars.pendingbuys)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -338,9 +338,16 @@ class Strategy:
|
||||
#odchyceny pripad, kdy indikatory jsou inicializovane, ale jeste v nich nejsou data, pak do WS nic neposilame
|
||||
try:
|
||||
rt_out["indicators"][key]= value[-1]
|
||||
#zatim takto odchycene identifikatory, ktere nemaji list, ale dict - do budoucna predelat na samostatny typ "indicators_static"
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
|
||||
#same for static indicators
|
||||
if len(self.state.statinds) > 0:
|
||||
rt_out["statinds"] = dict()
|
||||
for key, value in self.state.statinds.items():
|
||||
rt_out["statinds"][key] = value
|
||||
|
||||
#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)
|
||||
@ -363,8 +370,9 @@ class Strategy:
|
||||
print("RTQUEUE INSERT")
|
||||
#send current values to Realtime display on frontend
|
||||
#all datetime values are converted to timestamp
|
||||
self.rtqueue.put(json.dumps(rt_out, default=json_serial))
|
||||
print("RTQUEUE", self.rtqueue)
|
||||
if self.rtqueue is not None:
|
||||
self.rtqueue.put(json.dumps(rt_out, default=json_serial))
|
||||
print("RTQUEUE", self.rtqueue)
|
||||
|
||||
#cleaning iterlog lsit
|
||||
#TODO pridat cistku i mimo RT blok
|
||||
@ -466,6 +474,7 @@ class StrategyState:
|
||||
self.bars = AttributeDict(bars)
|
||||
self.trades = AttributeDict(trades)
|
||||
self.indicators = AttributeDict(time=[])
|
||||
self.statinds = AttributeDict()
|
||||
#these methods can be overrided by StrategyType (to add or alter its functionality)
|
||||
self.buy = self.interface.buy
|
||||
self.buy_l = self.interface.buy_l
|
||||
|
||||
Binary file not shown.
@ -15,6 +15,7 @@ from typing import List
|
||||
import tomli
|
||||
from v2realbot.config import DATA_DIR
|
||||
import requests
|
||||
from uuid import UUID
|
||||
|
||||
def send_to_telegram(message):
|
||||
apiToken = '5836666362:AAGPuzwp03tczMQTwTBiHW6VsZZ-1RCMAEE'
|
||||
@ -35,7 +36,9 @@ def json_serial(obj):
|
||||
|
||||
if isinstance(obj, (datetime, date)):
|
||||
return obj.timestamp()
|
||||
raise TypeError ("Type %s not serializable" % type(obj))
|
||||
if isinstance(obj, UUID):
|
||||
return str(obj)
|
||||
raise TypeError (str(obj)+"Type %s not serializable" % type(obj))
|
||||
|
||||
def parse_toml_string(tomlst: str):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user