dynamicky scope a upravy GUI

This commit is contained in:
David Brazda
2023-06-30 20:37:24 +02:00
parent f3821a8f4f
commit 3d0b2d0a0b
6 changed files with 1177 additions and 82 deletions

View File

@ -498,7 +498,7 @@ def next(data, state: StrategyState):
#state.indicators.RSI14[-1]=0
def populate_cbar_rsi_indicator():
#CBAR RSI indicator
#CBAR RSI indicator
options = safe_get(state.vars.indicators, 'crsi', None)
if options is None:
state.ilog(e="No options for crsi in stratvars")

File diff suppressed because it is too large Load Diff

View File

@ -342,7 +342,7 @@
</div>
<div class="form-group">
<label for="stratvars_conf" class="form-label">stratvars_conf</label>
<textarea class="form-control" rows="8" id="stratvars_conf" name="stratvars_conf" required></textarea>
<textarea class="form-control" rows="16" id="stratvars_conf" name="stratvars_conf" required></textarea>
</div>
<div class="form-group">
<label for="add_data_conf" class="form-label">add_data_conf</label>

View File

@ -320,7 +320,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
//funkci do ktere muzu zavolat vse co pujde jako data do chartu
//MOVE TO UTILS ro reuse??
if (conf && conf.display) {
//if (conf && conf.display) {
if (conf) {
//tranform data do správného formátru
items = []
@ -395,7 +396,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
priceFormat: {type: 'volume'},
priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible,
priceScaleId: conf.priceScaleId});
priceScaleId: conf.priceScaleId,
visible: conf.display});
obj.series.priceScale().applyOptions({
// set the positioning of the volume series
@ -407,36 +409,42 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
}
else {
var barva = colors.shift()
obj.series = chart.addLineSeries({
color: colors.shift(),
color: barva,
priceScaleId: conf.priceScaleId,
title: (conf.titlevisible?conf.name:""),
lineWidth: 1
lineWidth: 1,
visible: conf.display
});
//toto nejak vymyslet konfiguracne, additional threshold lines
if (key == "slopeMA") {
// //existuje statinds se stejnym klicem - bereme z nej minimum slope
// a = data.statinds[key]
// console.log("pro klic" + key + ":"+a, JSON.stringify(a,null,2))
// console.log(data.statinds[key].minimum_slope)
// console.log(JSON.stringify(data.statinds,null,2))
//console.log((key in data.statinds), data.statinds, key)
if (key in data.statinds) {
//natvrdo nakreslime lajnu pro min angle
//TODO predelat na configuracne
const minSlopeLineOptopns = {
price: data.statinds.angle.minimum_slope,
color: '#b67de8',
price: data.statinds[key].minimum_slope,
color: barva,
lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true,
title: "min:",
title: "min",
};
const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns);
const maxSlopeLineOptopns = {
price: data.statinds.angle.maximum_slope,
color: '#b67de8',
price: data.statinds[key].maximum_slope,
color: barva,
lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true,
title: "max:",
title: "max",
};
const maxSlopeLine = obj.series.createPriceLine(maxSlopeLineOptopns);

View File

@ -4,9 +4,10 @@ var ws = null;
var logcnt = 0
var positionsPriceLine = null
var limitkaPriceLine = null
var angleSeries = 1
var angleSeries_slow = 1
var angleSeries = {}
//var angleSeries_slow = 1
var cbar = false
var angleColor = {}
//get details of runner to populate chart status
//fetch necessary - it could be initiated by manually inserting runnerId
@ -211,23 +212,21 @@ function connect(event) {
for (const [klic, hodnota] of Object.entries(statinds)) {
// console.log(JSON.stringify(klic))
// console.log(JSON.stringify(hodnota))
//TODO predelat na configuracni klice vizualizacni dotahovane z backendu, ktere namapuji vybrane stratvars na typ vizualizace
if (klic === "angle") {
//klic je nazev atirbutu, zatim zde mame jenom angle (do budoucna v json konifguraci)
//nejsou vsechny hodnoty
if (Object.keys(hodnota).length > 2) {
// console.log("angle nalezen");
// console.log(JSON.stringify(hodnota));
if (angleSeries !== 1) {
if (angleSeries[klic]) {
// console.log("angle neni jedna" + toString(angleSeries))
chart.removeSeries(angleSeries)
chart.removeSeries(angleSeries[klic])
}
angleSeries = chart.addLineSeries({
angleSeries[klic] = chart.addLineSeries({
//title: key,
lineWidth: 2,
lineStyle: 2,
color: "#d432e6",
color: angleColor[klic],
lastValueVisible: false,
priceLineVisible: false,
priceLineWidth: 0,
@ -236,47 +235,39 @@ function connect(event) {
dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
// console.log("pridano")
// console.log(toString(dataPoints))
angleSeries.setData(dataPoints)
angleSeries[klic].setData(dataPoints)
}
}
if (klic === "angle_slow") {
//nejsou vsechny hodnoty
if (Object.keys(hodnota).length > 2) {
// console.log("angle nalezen");
// console.log(JSON.stringify(hodnota));
if (angleSeries_slow !== 1) {
// console.log("angle neni jedna" + toString(angleSeries))
chart.removeSeries(angleSeries_slow)
}
// if (klic === "angle_slow") {
angleSeries_slow = chart.addLineSeries({
//title: key,
lineWidth: 2,
lineStyle: 2,
color: "#8c52c7",
lastValueVisible: false,
priceLineVisible: false,
priceLineWidth: 0,
priceLineStyle: 3
})
dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
// console.log("pridano")
// console.log(toString(dataPoints))
angleSeries_slow.setData(dataPoints)
}
}
// //nejsou vsechny hodnoty
// if (Object.keys(hodnota).length > 2) {
// // console.log("angle nalezen");
// // console.log(JSON.stringify(hodnota));
// if (angleSeries_slow !== 1) {
// // console.log("angle neni jedna" + toString(angleSeries))
// chart.removeSeries(angleSeries_slow)
// }
// angleSeries_slow = chart.addLineSeries({
// //title: key,
// lineWidth: 2,
// lineStyle: 2,
// color: colors.shift(),
// lastValueVisible: false,
// priceLineVisible: false,
// priceLineWidth: 0,
// priceLineStyle: 3
// })
// dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
// // console.log("pridano")
// // console.log(toString(dataPoints))
// angleSeries_slow.setData(dataPoints)
// }
// }
}
}
}
@ -299,7 +290,8 @@ function connect(event) {
//INIT INDICATOR BASED on CONFIGURATION
//MOVE TO UTILS ro reuse??
if (conf && conf.display) {
//if (conf && conf.display) {
if (conf && conf) {
if (conf.embed) {
if (conf.histogram) {
@ -310,7 +302,8 @@ function connect(event) {
priceFormat: {type: 'volume'},
priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible,
priceScaleId: conf.priceScaleId});
priceScaleId: conf.priceScaleId,
visible: conf.display});
obj.series.priceScale().applyOptions({
// set the positioning of the volume series
@ -322,12 +315,14 @@ function connect(event) {
}
else {
var barva = colors.shift()
obj.series = chart.addLineSeries({
color: colors.shift(),
color: barva,
priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible,
title: (conf.titlevisible?conf.name:""),
lineWidth: 1
lineWidth: 1,
visible: conf.display
});
}
@ -337,28 +332,43 @@ function connect(event) {
value: value});
indList.push(obj);
//pridavali jsme indikator, updatneme buttonky
var container1 = document.getElementById('chart');
var btnElement = document.getElementById("indicatorsButtons")
if (btnElement) {
container1.removeChild(btnElement);
}
var indbuttonElement = populate_indicator_buttons(true);
container1.appendChild(indbuttonElement)
//toto nejak vymyslet konfiguracne, additional threshold lines
if (key == "slopeMA") {
//pokud existuje statin pro tento klic, pak z nej vysosame min_lajny
if (key in parsed_data.statinds) {
//natvrdo nakreslime lajnu pro min angle
if (!(key in angleColor)) {
angleColor[key] = barva
}
//TODO predelat na configuracne
const minSlopeLineOptopns = {
price: parsed_data.statinds.angle.minimum_slope,
color: '#b67de8',
price: parsed_data.statinds[key].minimum_slope,
color: barva,
lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true,
title: "min:",
title: "min",
};
const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns);
const maxSlopeLineOptopns = {
price: parsed_data.statinds.angle.maximum_slope,
color: '#b67de8',
price: parsed_data.statinds[key].maximum_slope,
color: barva,
lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true,
title: "max:",
title: "max",
};
const maxSlopeLine = obj.series.createPriceLine(maxSlopeLineOptopns);

View File

@ -25,18 +25,22 @@ indConfig = [ {name: "ema", titlevisible: false, embed: true, display: true, pri
{name: "tick_volume", histogram: true, titlevisible: true, embed: true, display: true, priceScaleId: '', lastValueVisible: false},
{name: "tick_price", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
{name: "ivwap", titlevisible: true, embed: true, display: false, priceScaleId: "right", lastValueVisible: false},
{name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "middle", lastValueVisible: false},
{name: "slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "slow_slope", titlevisible: true, embed: true, display: false, priceScaleId: "middle", lastValueVisible: false},
{name: "slow_slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
{name: "slopeNEW", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
{name: "slope10", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "slope10puv", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "slope30", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "slow_slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
{name: "slow_slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "emaSlow", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
{name: "emaFast", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
{name: "RSI14", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "CRSI", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "aroon", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "apo", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "ppo", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "stoch2", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "RSI14", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "CRSI", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "aroon", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "apo", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "ppo", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "stoch2", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "sec_price", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},]
@ -182,7 +186,8 @@ function update_chart_legend(param) {
indList.forEach(function (item) {
var ind = param.seriesData.get(item.series)
var color = item.series.options().color;
if (ind !== undefined) { firstRow.innerHTML += name(item.name, color) + val(ind.value.toFixed(3), color)}
var visibility = item.series.options().visible;
if (ind !== undefined && visibility) { firstRow.innerHTML += name(item.name, color) + val(ind.value.toFixed(3), color)}
});
}
else {
@ -295,10 +300,14 @@ function initialize_vwap() {
})
}
function remove_indicator_buttons() {
var elem1 = document.getElementById("indicatorsButtons");
elem1.remove()
}
function populate_indicator_buttons(def) {
var buttonElement = document.createElement('div');
buttonElement.id = "indicatorsButtons"
buttonElement.id = "indicatorsButtons"
buttonElement.classList.add('switcher');
indList.forEach(function (item, index) {
@ -316,6 +325,31 @@ function populate_indicator_buttons(def) {
buttonElement.appendChild(itemEl);
});
//create toggle all button
var itemEl = document.createElement('button');
itemEl.innerText = "all"
itemEl.classList.add('switcher-item');
if (def) {
itemEl.classList.add('switcher-active-item');
}
itemEl.addEventListener('click', function() {
onResetClicked();
});
buttonElement.appendChild(itemEl);
function onResetClicked() {
indList.forEach(function (item, index) {
vis = true;
const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
indList[index].series.applyOptions({
visible: vis });
})
}
function onItemClicked1(index) {
vis = true;
const elem = document.getElementById("IND"+index);