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 #state.indicators.RSI14[-1]=0
def populate_cbar_rsi_indicator(): def populate_cbar_rsi_indicator():
#CBAR RSI indicator #CBAR RSI indicator
options = safe_get(state.vars.indicators, 'crsi', None) options = safe_get(state.vars.indicators, 'crsi', None)
if options is None: if options is None:
state.ilog(e="No options for crsi in stratvars") 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>
<div class="form-group"> <div class="form-group">
<label for="stratvars_conf" class="form-label">stratvars_conf</label> <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>
<div class="form-group"> <div class="form-group">
<label for="add_data_conf" class="form-label">add_data_conf</label> <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 //funkci do ktere muzu zavolat vse co pujde jako data do chartu
//MOVE TO UTILS ro reuse?? //MOVE TO UTILS ro reuse??
if (conf && conf.display) { //if (conf && conf.display) {
if (conf) {
//tranform data do správného formátru //tranform data do správného formátru
items = [] items = []
@ -395,7 +396,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
priceFormat: {type: 'volume'}, priceFormat: {type: 'volume'},
priceScaleId: conf.priceScaleId, priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible, lastValueVisible: conf.lastValueVisible,
priceScaleId: conf.priceScaleId}); priceScaleId: conf.priceScaleId,
visible: conf.display});
obj.series.priceScale().applyOptions({ obj.series.priceScale().applyOptions({
// set the positioning of the volume series // set the positioning of the volume series
@ -407,36 +409,42 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
} }
else { else {
var barva = colors.shift()
obj.series = chart.addLineSeries({ obj.series = chart.addLineSeries({
color: colors.shift(), color: barva,
priceScaleId: conf.priceScaleId, priceScaleId: conf.priceScaleId,
title: (conf.titlevisible?conf.name:""), title: (conf.titlevisible?conf.name:""),
lineWidth: 1 lineWidth: 1,
visible: conf.display
}); });
//toto nejak vymyslet konfiguracne, additional threshold lines // //existuje statinds se stejnym klicem - bereme z nej minimum slope
if (key == "slopeMA") { // 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 //natvrdo nakreslime lajnu pro min angle
//TODO predelat na configuracne //TODO predelat na configuracne
const minSlopeLineOptopns = { const minSlopeLineOptopns = {
price: data.statinds.angle.minimum_slope, price: data.statinds[key].minimum_slope,
color: '#b67de8', color: barva,
lineWidth: 1, lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true, axisLabelVisible: true,
title: "min:", title: "min",
}; };
const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns); const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns);
const maxSlopeLineOptopns = { const maxSlopeLineOptopns = {
price: data.statinds.angle.maximum_slope, price: data.statinds[key].maximum_slope,
color: '#b67de8', color: barva,
lineWidth: 1, lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true, axisLabelVisible: true,
title: "max:", title: "max",
}; };
const maxSlopeLine = obj.series.createPriceLine(maxSlopeLineOptopns); const maxSlopeLine = obj.series.createPriceLine(maxSlopeLineOptopns);

View File

@ -4,9 +4,10 @@ var ws = null;
var logcnt = 0 var logcnt = 0
var positionsPriceLine = null var positionsPriceLine = null
var limitkaPriceLine = null var limitkaPriceLine = null
var angleSeries = 1 var angleSeries = {}
var angleSeries_slow = 1 //var angleSeries_slow = 1
var cbar = false var cbar = false
var angleColor = {}
//get details of runner to populate chart status //get details of runner to populate chart status
//fetch necessary - it could be initiated by manually inserting runnerId //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)) { for (const [klic, hodnota] of Object.entries(statinds)) {
// console.log(JSON.stringify(klic)) // console.log(JSON.stringify(klic))
// console.log(JSON.stringify(hodnota)) // console.log(JSON.stringify(hodnota))
//TODO predelat na configuracni klice vizualizacni dotahovane z backendu, ktere namapuji vybrane stratvars na typ vizualizace //klic je nazev atirbutu, zatim zde mame jenom angle (do budoucna v json konifguraci)
if (klic === "angle") {
//nejsou vsechny hodnoty //nejsou vsechny hodnoty
if (Object.keys(hodnota).length > 2) { if (Object.keys(hodnota).length > 2) {
// console.log("angle nalezen"); // console.log("angle nalezen");
// console.log(JSON.stringify(hodnota)); // console.log(JSON.stringify(hodnota));
if (angleSeries !== 1) { if (angleSeries[klic]) {
// console.log("angle neni jedna" + toString(angleSeries)) // console.log("angle neni jedna" + toString(angleSeries))
chart.removeSeries(angleSeries) chart.removeSeries(angleSeries[klic])
} }
angleSeries = chart.addLineSeries({ angleSeries[klic] = chart.addLineSeries({
//title: key, //title: key,
lineWidth: 2, lineWidth: 2,
lineStyle: 2, lineStyle: 2,
color: "#d432e6", color: angleColor[klic],
lastValueVisible: false, lastValueVisible: false,
priceLineVisible: false, priceLineVisible: false,
priceLineWidth: 0, priceLineWidth: 0,
@ -236,47 +235,39 @@ function connect(event) {
dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}] dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
// console.log("pridano") // console.log("pridano")
// console.log(toString(dataPoints)) // console.log(toString(dataPoints))
angleSeries.setData(dataPoints) angleSeries[klic].setData(dataPoints)
} }
}
if (klic === "angle_slow") {
//nejsou vsechny hodnoty // if (klic === "angle_slow") {
if (Object.keys(hodnota).length > 2) {
// console.log("angle nalezen"); // //nejsou vsechny hodnoty
// console.log(JSON.stringify(hodnota)); // if (Object.keys(hodnota).length > 2) {
if (angleSeries_slow !== 1) { // // console.log("angle nalezen");
// console.log("angle neni jedna" + toString(angleSeries)) // // console.log(JSON.stringify(hodnota));
chart.removeSeries(angleSeries_slow) // if (angleSeries_slow !== 1) {
} // // console.log("angle neni jedna" + toString(angleSeries))
// chart.removeSeries(angleSeries_slow)
// }
angleSeries_slow = chart.addLineSeries({ // angleSeries_slow = chart.addLineSeries({
//title: key, // //title: key,
lineWidth: 2, // lineWidth: 2,
lineStyle: 2, // lineStyle: 2,
color: "#8c52c7", // color: colors.shift(),
lastValueVisible: false, // lastValueVisible: false,
priceLineVisible: false, // priceLineVisible: false,
priceLineWidth: 0, // priceLineWidth: 0,
priceLineStyle: 3 // priceLineStyle: 3
}) // })
dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}] // dataPoints = [{time: hodnota.lookbacktime, value: hodnota.lookbackprice},{ time: hodnota.time, value: hodnota.price}]
// console.log("pridano") // // console.log("pridano")
// console.log(toString(dataPoints)) // // console.log(toString(dataPoints))
angleSeries_slow.setData(dataPoints) // angleSeries_slow.setData(dataPoints)
} // }
} // }
} }
} }
} }
@ -299,7 +290,8 @@ function connect(event) {
//INIT INDICATOR BASED on CONFIGURATION //INIT INDICATOR BASED on CONFIGURATION
//MOVE TO UTILS ro reuse?? //MOVE TO UTILS ro reuse??
if (conf && conf.display) { //if (conf && conf.display) {
if (conf && conf) {
if (conf.embed) { if (conf.embed) {
if (conf.histogram) { if (conf.histogram) {
@ -310,7 +302,8 @@ function connect(event) {
priceFormat: {type: 'volume'}, priceFormat: {type: 'volume'},
priceScaleId: conf.priceScaleId, priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible, lastValueVisible: conf.lastValueVisible,
priceScaleId: conf.priceScaleId}); priceScaleId: conf.priceScaleId,
visible: conf.display});
obj.series.priceScale().applyOptions({ obj.series.priceScale().applyOptions({
// set the positioning of the volume series // set the positioning of the volume series
@ -322,12 +315,14 @@ function connect(event) {
} }
else { else {
var barva = colors.shift()
obj.series = chart.addLineSeries({ obj.series = chart.addLineSeries({
color: colors.shift(), color: barva,
priceScaleId: conf.priceScaleId, priceScaleId: conf.priceScaleId,
lastValueVisible: conf.lastValueVisible, lastValueVisible: conf.lastValueVisible,
title: (conf.titlevisible?conf.name:""), title: (conf.titlevisible?conf.name:""),
lineWidth: 1 lineWidth: 1,
visible: conf.display
}); });
} }
@ -337,28 +332,43 @@ function connect(event) {
value: value}); value: value});
indList.push(obj); 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 //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 //natvrdo nakreslime lajnu pro min angle
if (!(key in angleColor)) {
angleColor[key] = barva
}
//TODO predelat na configuracne //TODO predelat na configuracne
const minSlopeLineOptopns = { const minSlopeLineOptopns = {
price: parsed_data.statinds.angle.minimum_slope, price: parsed_data.statinds[key].minimum_slope,
color: '#b67de8', color: barva,
lineWidth: 1, lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true, axisLabelVisible: true,
title: "min:", title: "min",
}; };
const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns); const minSlopeLine = obj.series.createPriceLine(minSlopeLineOptopns);
const maxSlopeLineOptopns = { const maxSlopeLineOptopns = {
price: parsed_data.statinds.angle.maximum_slope, price: parsed_data.statinds[key].maximum_slope,
color: '#b67de8', color: barva,
lineWidth: 1, lineWidth: 1,
lineStyle: 2, // LineStyle.Dotted lineStyle: 2, // LineStyle.Dotted
axisLabelVisible: true, axisLabelVisible: true,
title: "max:", title: "max",
}; };
const maxSlopeLine = obj.series.createPriceLine(maxSlopeLineOptopns); 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_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: "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: "ivwap", titlevisible: true, embed: true, display: false, priceScaleId: "right", lastValueVisible: false},
{name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "middle", lastValueVisible: false}, {name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
{name: "slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false}, {name: "slopeNEW", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
{name: "slow_slope", titlevisible: true, embed: true, display: false, priceScaleId: "middle", lastValueVisible: false}, {name: "slope10", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
{name: "slow_slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "middle", 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: "emaSlow", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
{name: "emaFast", 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: "RSI14", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "CRSI", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false}, {name: "CRSI", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "aroon", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false}, {name: "aroon", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "apo", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false}, {name: "apo", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "ppo", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false}, {name: "ppo", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
{name: "stoch2", titlevisible: true, embed: true, display: true, priceScaleId: "left", 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},] {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) { indList.forEach(function (item) {
var ind = param.seriesData.get(item.series) var ind = param.seriesData.get(item.series)
var color = item.series.options().color; 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 { else {
@ -295,10 +300,14 @@ function initialize_vwap() {
}) })
} }
function remove_indicator_buttons() {
var elem1 = document.getElementById("indicatorsButtons");
elem1.remove()
}
function populate_indicator_buttons(def) { function populate_indicator_buttons(def) {
var buttonElement = document.createElement('div'); var buttonElement = document.createElement('div');
buttonElement.id = "indicatorsButtons" buttonElement.id = "indicatorsButtons"
buttonElement.classList.add('switcher'); buttonElement.classList.add('switcher');
indList.forEach(function (item, index) { indList.forEach(function (item, index) {
@ -316,6 +325,31 @@ function populate_indicator_buttons(def) {
buttonElement.appendChild(itemEl); 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) { function onItemClicked1(index) {
vis = true; vis = true;
const elem = document.getElementById("IND"+index); const elem = document.getElementById("IND"+index);