backend: slope support, gui:add json
This commit is contained in:
15
testy/testSlope.py
Normal file
15
testy/testSlope.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
sma = list
|
||||||
|
|
||||||
|
sma = [28.90, 28.91, 28.91, 28.92, 28.97, 28.99]
|
||||||
|
slope_lookback = 4
|
||||||
|
roc_lookback = 4
|
||||||
|
|
||||||
|
slope = (sma[-1] - sma[-slope_lookback])/slope_lookback
|
||||||
|
roc = ((sma[-1] - sma[-roc_lookback])/sma[-roc_lookback])*100
|
||||||
|
|
||||||
|
print(slope)
|
||||||
|
|
||||||
|
|
||||||
|
# -1 až 0 klesání
|
||||||
|
# 0 až 1 stoupání
|
||||||
3
testy/testTelegram.py
Normal file
3
testy/testTelegram.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from v2realbot.utils.utils import send_to_telegram
|
||||||
|
|
||||||
|
send_to_telegram("nazdarek")
|
||||||
@ -45,7 +45,10 @@ stratvars = AttributeDict(maxpozic = 250,
|
|||||||
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],
|
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],
|
||||||
blockbuy = 0,
|
blockbuy = 0,
|
||||||
ticks2reset = 0.04,
|
ticks2reset = 0.04,
|
||||||
consolidation_bar_count = 10)
|
consolidation_bar_count = 10,
|
||||||
|
slope_lookback = 20,
|
||||||
|
minimum_slope = -0.23
|
||||||
|
)
|
||||||
##toto rozparsovat a strategii spustit stejne jako v main
|
##toto rozparsovat a strategii spustit stejne jako v main
|
||||||
toml_string = """
|
toml_string = """
|
||||||
[[strategies]]
|
[[strategies]]
|
||||||
@ -106,7 +109,7 @@ def next(data, state: StrategyState):
|
|||||||
price = last_price
|
price = last_price
|
||||||
##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
|
||||||
state.buy_l(price=price, size=qty)
|
state.buy_l(price=price, size=qty)
|
||||||
print("prvni limitka na aktuální cenu. Další podle křicvky", price, qty)
|
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||||
for i in range(0,vykladka-1):
|
for i in range(0,vykladka-1):
|
||||||
price = price2dec(float(price - curve[i]))
|
price = price2dec(float(price - curve[i]))
|
||||||
if price == last_price:
|
if price == last_price:
|
||||||
@ -133,24 +136,55 @@ def next(data, state: StrategyState):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
## slope vyresi rychlé sesupy - jeste je treba podchytit pomalejsi sesupy
|
||||||
|
|
||||||
|
|
||||||
|
slope = 99
|
||||||
|
#minimum slope disabled if -1
|
||||||
|
|
||||||
|
|
||||||
|
#roc_lookback = 20
|
||||||
#print(state.vars.MA, "MACKO")
|
#print(state.vars.MA, "MACKO")
|
||||||
#print(state.bars.hlcc4)
|
#print(state.bars.hlcc4)
|
||||||
state.indicators.ema = ema(state.bars.close, state.vars.MA) #state.bars.vwap
|
state.indicators.ema = ema(state.bars.close, state.vars.MA) #state.bars.vwap
|
||||||
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
||||||
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
||||||
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
|
ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
|
||||||
|
|
||||||
|
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
|
||||||
|
state.indicators.slope.append(slope)
|
||||||
|
#state.indicators.roc.append(roc)
|
||||||
|
ic(state.indicators.slope[-5:])
|
||||||
|
#ic(state.indicators.roc[-5:])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("No data for MA yet", str(e))
|
print("Exception in NEXT Indicator section", str(e))
|
||||||
|
|
||||||
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))
|
||||||
|
|
||||||
#and data['index'] > state.vars.lastbuyindex+state.vars.Trend:
|
#SLOPE ANGLE PROTECTION
|
||||||
#neni vylozeno muzeme nakupovat
|
if slope < minimum_slope:
|
||||||
|
print("OCHRANA SLOPE TOO HIGH")
|
||||||
|
if len(state.vars.pendingbuys)>0:
|
||||||
|
print("CANCEL PENDINGBUYS")
|
||||||
|
ic(state.vars.pendingbuys)
|
||||||
|
res = asyncio.run(state.cancel_pending_buys())
|
||||||
|
ic(state.vars.pendingbuys)
|
||||||
|
print("slope", slope)
|
||||||
|
print("min slope", minimum_slope)
|
||||||
|
|
||||||
if ic(state.vars.jevylozeno) == 0:
|
if ic(state.vars.jevylozeno) == 0:
|
||||||
print("Neni vylozeno, muzeme testovat nakup")
|
print("Neni vylozeno, muzeme testovat nakup")
|
||||||
|
|
||||||
if isfalling(state.indicators.ema,state.vars.Trend):
|
if isfalling(state.indicators.ema,state.vars.Trend) and slope > minimum_slope:
|
||||||
print("BUY MARKET")
|
print("BUY MARKET")
|
||||||
ic(data['updated'])
|
ic(data['updated'])
|
||||||
ic(state.time)
|
ic(state.time)
|
||||||
@ -167,7 +201,7 @@ def next(data, state: StrategyState):
|
|||||||
#TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou
|
#TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou
|
||||||
#TODO spoustet 1x za X iteraci nebo cas
|
#TODO spoustet 1x za X iteraci nebo cas
|
||||||
if state.vars.jevylozeno == 1:
|
if state.vars.jevylozeno == 1:
|
||||||
#pokud mame vylozeno a cena je vetsi nez 0.04
|
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||||
if len(state.vars.pendingbuys)>0:
|
if len(state.vars.pendingbuys)>0:
|
||||||
maxprice = max(state.vars.pendingbuys.values())
|
maxprice = max(state.vars.pendingbuys.values())
|
||||||
print("max cena v orderbuys", maxprice)
|
print("max cena v orderbuys", maxprice)
|
||||||
@ -264,6 +298,8 @@ def init(state: StrategyState):
|
|||||||
#place to declare new vars
|
#place to declare new vars
|
||||||
print("INIT v main",state.name)
|
print("INIT v main",state.name)
|
||||||
state.indicators['ema'] = []
|
state.indicators['ema'] = []
|
||||||
|
state.indicators['slope'] = []
|
||||||
|
#state.indicators['roc'] = []
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@ -517,7 +517,7 @@ class Backtester:
|
|||||||
#with lock:
|
#with lock:
|
||||||
for o in self.open_orders:
|
for o in self.open_orders:
|
||||||
#print(o)
|
#print(o)
|
||||||
if o.symbol == symbol:
|
if o.symbol == symbol and o.canceled_at is None:
|
||||||
if side is None or o.side == side:
|
if side is None or o.side == side:
|
||||||
res.append(o)
|
res.append(o)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@ -235,6 +235,7 @@ def capsule(target: object, db: object):
|
|||||||
reason = "SHUTDOWN OK"
|
reason = "SHUTDOWN OK"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
reason = "SHUTDOWN Exception:" + str(e)
|
reason = "SHUTDOWN Exception:" + str(e)
|
||||||
|
print(str(e))
|
||||||
print(reason)
|
print(reason)
|
||||||
finally:
|
finally:
|
||||||
# remove runners after thread is stopped and save results to stratin history
|
# remove runners after thread is stopped and save results to stratin history
|
||||||
|
|||||||
Binary file not shown.
@ -147,7 +147,7 @@ class LiveInterface(GeneralInterface):
|
|||||||
return a
|
return a
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
#order doesnt exist
|
#order doesnt exist
|
||||||
if e.code == 40410000: return 0,0
|
if e.code == 40410000: return 0
|
||||||
else:
|
else:
|
||||||
print("nepovedlo se zrusit objednavku", str(e))
|
print("nepovedlo se zrusit objednavku", str(e))
|
||||||
#raise Exception(e)
|
#raise Exception(e)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ from fastapi import FastAPI, Depends, HTTPException, status
|
|||||||
from fastapi.security import APIKeyHeader
|
from fastapi.security import APIKeyHeader
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import controller.services as cs
|
import v2realbot.controller.services as cs
|
||||||
from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest
|
from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest
|
||||||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
||||||
from fastapi.responses import HTMLResponse, FileResponse
|
from fastapi.responses import HTMLResponse, FileResponse
|
||||||
|
|||||||
@ -79,7 +79,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="stratin-table" class="flex-items">
|
<div id="stratin-table" class="flex-items">
|
||||||
<div id="stratin-table">
|
<div id="stratin-table">
|
||||||
<button id="button_add" class="btn btn-success">Add</button><button id="button_edit" class="btn btn-success">Edit</button><button id="button_dup" class="btn btn-success">Duplicate</button><button id="button_delete" class="btn btn-success">Delete</button><button id="button_run" class="btn btn-success">Run Strategy</button>
|
<button id="button_add" class="btn btn-success">Add</button>
|
||||||
|
<button id="button_add_json" class="btn btn-success">Add JSON</button>
|
||||||
|
<button id="button_edit" class="btn btn-success">Edit</button>
|
||||||
|
<button id="button_dup" class="btn btn-success">Duplicate</button>
|
||||||
|
<button id="button_copy" class="btn btn-success">Copy JSON</button>
|
||||||
|
<button id="button_delete" class="btn btn-success">Delete</button>
|
||||||
|
<button id="button_run" class="btn btn-success">Run Strategy</button>
|
||||||
<table id="stratinTable" class="display" style="width:100%">
|
<table id="stratinTable" class="display" style="width:100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -192,6 +198,28 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="jsonModal" class="modal fade">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<form method="post" id="jsonForm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title_json"><i class="fa fa-plus"></i> Add JSON Record</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="jsontext" class="control-label">JSON</label>
|
||||||
|
<textarea class="form-control" rows="7" id="jsontext" name="jsontext" required></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<input type="submit" name="json_add" id="json_add" class="btn btn-info" value="Add" />
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="runModal" class="modal fade">
|
<div id="runModal" class="modal fade">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form method="post" id="runForm">
|
<form method="post" id="runForm">
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//const chartOptions = { layout: { textColor: 'black', background: { type: 'solid', color: 'white' } } };
|
//const chartOptions = { layout: { textColor: 'black', background: { type: 'solid', color: 'white' } } };
|
||||||
const chartOptions = { width: 1200, height: 600}
|
const chartOptions = { width: 1200, height: 600, leftPriceScale: {visible: true}}
|
||||||
const chart = LightweightCharts.createChart(document.getElementById('chart'), chartOptions);
|
const chart = LightweightCharts.createChart(document.getElementById('chart'), chartOptions);
|
||||||
chart.applyOptions({ timeScale: { visible: true, timeVisible: true, secondsVisible: true }, crosshair: {
|
chart.applyOptions({ timeScale: { visible: true, timeVisible: true, secondsVisible: true }, crosshair: {
|
||||||
mode: LightweightCharts.CrosshairMode.Normal, labelVisible: true
|
mode: LightweightCharts.CrosshairMode.Normal, labelVisible: true
|
||||||
|
|||||||
@ -64,6 +64,7 @@ $(document).ready(function () {
|
|||||||
$('#button_stop').attr('disabled','disabled');
|
$('#button_stop').attr('disabled','disabled');
|
||||||
$('#button_edit').attr('disabled','disabled');
|
$('#button_edit').attr('disabled','disabled');
|
||||||
$('#button_dup').attr('disabled','disabled');
|
$('#button_dup').attr('disabled','disabled');
|
||||||
|
$('#button_copy').attr('disabled','disabled');
|
||||||
$('#button_delete').attr('disabled','disabled');
|
$('#button_delete').attr('disabled','disabled');
|
||||||
$('#button_run').attr('disabled','disabled');
|
$('#button_run').attr('disabled','disabled');
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ $(document).ready(function () {
|
|||||||
if ($(this).hasClass('selected')) {
|
if ($(this).hasClass('selected')) {
|
||||||
$(this).removeClass('selected');
|
$(this).removeClass('selected');
|
||||||
$('#button_dup').attr('disabled','disabled');
|
$('#button_dup').attr('disabled','disabled');
|
||||||
|
$('#button_copy').attr('disabled','disabled');
|
||||||
$('#button_edit').attr('disabled','disabled');
|
$('#button_edit').attr('disabled','disabled');
|
||||||
$('#button_delete').attr('disabled','disabled');
|
$('#button_delete').attr('disabled','disabled');
|
||||||
$('#button_run').attr('disabled','disabled');
|
$('#button_run').attr('disabled','disabled');
|
||||||
@ -79,6 +81,7 @@ $(document).ready(function () {
|
|||||||
stratinRecords.$('tr.selected').removeClass('selected');
|
stratinRecords.$('tr.selected').removeClass('selected');
|
||||||
$(this).addClass('selected');
|
$(this).addClass('selected');
|
||||||
$('#button_dup').attr('disabled',false);
|
$('#button_dup').attr('disabled',false);
|
||||||
|
$('#button_copy').attr('disabled',false);
|
||||||
$('#button_edit').attr('disabled',false);
|
$('#button_edit').attr('disabled',false);
|
||||||
$('#button_delete').attr('disabled',false);
|
$('#button_delete').attr('disabled',false);
|
||||||
$('#button_run').attr('disabled',false);
|
$('#button_run').attr('disabled',false);
|
||||||
@ -105,6 +108,28 @@ $(document).ready(function () {
|
|||||||
stratinRecords.ajax.reload();
|
stratinRecords.ajax.reload();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//button refresh
|
||||||
|
$('#button_copy').click(function () {
|
||||||
|
event.preventDefault();
|
||||||
|
$('#button_copy').attr('disabled','disabled');
|
||||||
|
row = stratinRecords.row('.selected').data();
|
||||||
|
const rec = new Object()
|
||||||
|
rec.id2 = parseInt(row.id2);
|
||||||
|
rec.name = row.name;
|
||||||
|
rec.symbol = row.symbol;
|
||||||
|
rec.class_name = row.class_name;
|
||||||
|
rec.script = row.script;
|
||||||
|
rec.open_rush = row.open_rush;
|
||||||
|
rec.close_rush = row.close_rush;
|
||||||
|
rec.stratvars_conf = row.stratvars_conf;
|
||||||
|
rec.add_data_conf = row.add_data_conf;
|
||||||
|
rec.note = row.note;
|
||||||
|
rec.history = "";
|
||||||
|
jsonString = JSON.stringify(rec);
|
||||||
|
navigator.clipboard.writeText(jsonString);
|
||||||
|
$('#button_copy').attr('disabled', false);
|
||||||
|
})
|
||||||
|
|
||||||
//button duplicate
|
//button duplicate
|
||||||
$('#button_dup').click(function () {
|
$('#button_dup').click(function () {
|
||||||
row = stratinRecords.row('.selected').data();
|
row = stratinRecords.row('.selected').data();
|
||||||
@ -250,6 +275,7 @@ $(document).ready(function () {
|
|||||||
$('#action').val('addRecord');
|
$('#action').val('addRecord');
|
||||||
$('#save').val('Add');
|
$('#save').val('Add');
|
||||||
});
|
});
|
||||||
|
|
||||||
//edit button
|
//edit button
|
||||||
$('#button_edit').click(function () {
|
$('#button_edit').click(function () {
|
||||||
row = stratinRecords.row('.selected').data();
|
row = stratinRecords.row('.selected').data();
|
||||||
@ -279,6 +305,10 @@ $(document).ready(function () {
|
|||||||
$('#save').val('Delete');
|
$('#save').val('Delete');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
//json add button
|
||||||
|
$('#button_add_json').click(function () {
|
||||||
|
window.$('#jsonModal').modal('show');
|
||||||
|
});
|
||||||
} );
|
} );
|
||||||
|
|
||||||
//stratin table
|
//stratin table
|
||||||
@ -441,7 +471,7 @@ $("#recordModal").on('submit','#recordForm', function(event){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//code for add
|
//code for edit
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#save').attr('disabled','disabled');
|
$('#save').attr('disabled','disabled');
|
||||||
var formData = $(this).serializeJSON();
|
var formData = $(this).serializeJSON();
|
||||||
@ -474,7 +504,40 @@ $("#recordModal").on('submit','#recordForm', function(event){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//delete
|
//add json modal
|
||||||
|
$("#jsonModal").on('submit','#jsonForm', function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
$('#json_add').attr('disabled','disabled');
|
||||||
|
jsonString = $('#jsontext').val();
|
||||||
|
$.ajax({
|
||||||
|
url:"/stratins/",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
method:"POST",
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json",
|
||||||
|
data: jsonString,
|
||||||
|
success:function(data){
|
||||||
|
$('#jsonForm')[0].reset();
|
||||||
|
window.$('#jsonModal').modal('hide');
|
||||||
|
$('#json_add').attr('disabled', false);
|
||||||
|
setTimeout(function () {
|
||||||
|
runnerRecords.ajax.reload();
|
||||||
|
stratinRecords.ajax.reload();
|
||||||
|
}, 750)
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
window.alert(JSON.stringify(xhr));
|
||||||
|
console.log(JSON.stringify(xhr));
|
||||||
|
$('#json_add').attr('disabled', false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//delete modal
|
||||||
$("#delModal").on('submit','#delForm', function(event){
|
$("#delModal").on('submit','#delForm', function(event){
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#delete').attr('disabled','disabled');
|
$('#delete').attr('disabled','disabled');
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
const momentumIndicatorNames = ["roc", "slope"]
|
||||||
var indList = []
|
var indList = []
|
||||||
var ws = null;
|
var ws = null;
|
||||||
function connect(event) {
|
function connect(event) {
|
||||||
@ -54,7 +55,7 @@ function connect(event) {
|
|||||||
|
|
||||||
if (parsed_data.hasOwnProperty("indicators")) {
|
if (parsed_data.hasOwnProperty("indicators")) {
|
||||||
var indicators = parsed_data.indicators
|
var indicators = parsed_data.indicators
|
||||||
//if there are indicators it means there must be at least two keys (first time is there everytime)
|
//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) {
|
if (Object.keys(indicators).length > 1) {
|
||||||
for (const [key, value] of Object.entries(indicators)) {
|
for (const [key, value] of Object.entries(indicators)) {
|
||||||
if (key !== "time") {
|
if (key !== "time") {
|
||||||
@ -63,10 +64,19 @@ function connect(event) {
|
|||||||
if (searchObject == undefined) {
|
if (searchObject == undefined) {
|
||||||
console.log("object new - init and add")
|
console.log("object new - init and add")
|
||||||
var obj = {name: key, series: null}
|
var obj = {name: key, series: null}
|
||||||
obj.series = chart.addLineSeries({
|
if (momentumIndicatorNames.includes(key)) {
|
||||||
title: key,
|
obj.series = chart.addLineSeries({
|
||||||
lineWidth: 1,
|
priceScaleId: 'left',
|
||||||
})
|
title: key,
|
||||||
|
lineWidth: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.series = chart.addLineSeries({
|
||||||
|
title: key,
|
||||||
|
lineWidth: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
obj.series.update({
|
obj.series.update({
|
||||||
time: indicators.time,
|
time: indicators.time,
|
||||||
value: value});
|
value: value});
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
.legend {
|
.legend {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: #050505;
|
color: #050505;
|
||||||
left: 60px;
|
left: 115px;
|
||||||
top: 99px;
|
top: 99px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|||||||
@ -116,7 +116,9 @@ class StrategyOrderLimitVykladaci(Strategy):
|
|||||||
ic(key)
|
ic(key)
|
||||||
#nejprve vyhodime z pendingbuys
|
#nejprve vyhodime z pendingbuys
|
||||||
self.state.vars.pendingbuys.pop(key, False)
|
self.state.vars.pendingbuys.pop(key, False)
|
||||||
self.interface.cancel(key)
|
res = self.interface.cancel(key)
|
||||||
|
if res < 0:
|
||||||
|
print("ERROR CANCEL PENDING BUYS")
|
||||||
self.state.vars.pendingbuys={}
|
self.state.vars.pendingbuys={}
|
||||||
self.state.vars.jevylozeno = 0
|
self.state.vars.jevylozeno = 0
|
||||||
print("cancel pending buys end")
|
print("cancel pending buys end")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -334,7 +334,11 @@ class Strategy:
|
|||||||
if len(self.state.indicators) > 0:
|
if len(self.state.indicators) > 0:
|
||||||
rt_out["indicators"] = dict()
|
rt_out["indicators"] = dict()
|
||||||
for key, value in self.state.indicators.items():
|
for key, value in self.state.indicators.items():
|
||||||
rt_out["indicators"][key] = value[-1]
|
#odchyceny pripad, kdy indikatory jsou inicializovane, ale jeste v nich nejsou data, pak do WS nic neposilame
|
||||||
|
try:
|
||||||
|
rt_out["indicators"][key]= value[-1]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
print(rt_out)
|
print(rt_out)
|
||||||
|
|
||||||
print("RTQUEUE INSERT")
|
print("RTQUEUE INSERT")
|
||||||
@ -344,10 +348,6 @@ class Strategy:
|
|||||||
print("RTQUEUE", self.rtqueue)
|
print("RTQUEUE", self.rtqueue)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# inicializace poplatna typu strategie (např. u LIMITu dotažení existující limitky)
|
# inicializace poplatna typu strategie (např. u LIMITu dotažení existující limitky)
|
||||||
def strat_init(self):
|
def strat_init(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
Binary file not shown.
@ -14,6 +14,18 @@ from v2realbot.common.model import StrategyInstance, Runner
|
|||||||
from typing import List
|
from typing import List
|
||||||
import tomli
|
import tomli
|
||||||
from v2realbot.config import DATA_DIR
|
from v2realbot.config import DATA_DIR
|
||||||
|
import requests
|
||||||
|
|
||||||
|
def send_to_telegram(message):
|
||||||
|
apiToken = '5836666362:AAGPuzwp03tczMQTwTBiHW6VsZZ-1RCMAEE'
|
||||||
|
chatID = '5029424778'
|
||||||
|
apiURL = f'https://api.telegram.org/bot{apiToken}/sendMessage'
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(apiURL, json={'chat_id': chatID, 'text': message})
|
||||||
|
print(response.text)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
#datetime to timestamp
|
#datetime to timestamp
|
||||||
def json_serial(obj):
|
def json_serial(obj):
|
||||||
|
|||||||
Reference in New Issue
Block a user