In dieser Lösung können mehrere Zeitrahmen gleichzeitig visualisiert werden, die Diagramme unterschiedlicher Zeitrahmen werden aufeinander bezogen, ABER nur bis zu einem bestimmten Zeitpunkt (nennen wir diesen trigger_date).
Code: Select all
time_tracker = ColumnDataSource(data=dict(trigger_date=[max_dt]))
An jede Schaltfläche muss ich alle Daten übergeben, das heißt jede Datenquelle aller Zeitrahmen und jeden Datenrahmen aller Zeitrahmen zur Implementierung der Schrittlogik (um die Diagramme nur bis zu einem bestimmten Zeitpunkt anzuzeigen und emit() ändert sich ordnungsgemäß).
Wichtig: Die Anzahl und die Werte der Zeitrahmen (Aggregationseinheiten) sind nicht statisch und nicht im Voraus bekannt. Es wird nur durch die Eingabe des Benutzers bestimmt. Ein Zeitrahmen kann buchstäblich alles sein. KANN NICHT als konstante Liste aufgeführt werden, z. B.: 30s, 1m, 5m, 15m, 30m, 1h, 4h, 1d, ...
Deshalb ist es einfach unmöglich, so etwas zu definieren:
Code: Select all
step_buttons[timeframe]['prev'].js_on_click(CustomJS(
args = dict(
time_tracker = time_tracker,
direction = -1,
min_dt = min_dt,
max_dt = max_dt,
# ALL TIMEFRAMES CAN NOT BE LISTED HERE BECAUSE IT'S UNKNOWN
datasource_5m = ...,
datasource_15m = ...,
datasource_30m = ...,
datasource_1h = ...,
datasource_4h = ...,
?????????????? = ...,
),
code = JS_CODE_STEP_LOGIC,
))
Code: Select all
js_data[timeframe] = {
'data_source' : ColumnDataSource(dataframes[timeframe]),
'candle_data' : dataframes[timeframe].to_dict(orient="list"),
}
# or
# data_sources = {}
# candle_data = {}
# for timeframe in dataframes.keys():
# data_sources[timeframe] = ColumnDataSource(dataframes[timeframe])
# candle_data[timeframe] = dataframes[timeframe].to_dict(orient="list")
# ...
for tf in timeframes:
# I'VE A LOT OF THESE BUTTONS
# THE ARGUMENT LIST CAN NOT BE FIXED HERE
# I'VE TO PUT DATA SOURCES INTO A HIERARCHY WITH TIMEFRAME KEYS (candle_data_and_sources )
# AND IMPLEMENT A DYNAMIC LOGIC ON JS SIDE
# THE TIMEFRAMES ARE NOT KNOWN IN ADVANCE
# THIS IS WHAT DUPLICATES THE DATA
# AND INCREASES THE SIZE OF THE GENERATED HTML
step_buttons[tf]['prev'].js_on_click(CustomJS(
args = dict(
candle_data_and_sources = js_data, # need to use complex structure here
# or
# data_sources = data_sources
# candle_data = candle_data
time_tracker = time_tracker,
direction = -1,
timeframe = tf,
min_dt = min_dt,
max_dt = max_dt,
),
code = JS_CODE_STEP_LOGIC,
))
step_buttons[tf]['next'] = ...
FRAGEN:
- Wie könnte ich alle verfügbaren Daten nur einmal an jede Schaltfläche übergeben, ohne das Modell hier zu duplizieren?
- Habe ich das Recht, dass es sich nicht gut anfühlt, alle möglichen Zeitrahmen fest in die Argumente der Schaltfläche zu codieren? Möglichkeit, dies umzusetzen (und in meinem Fall könnte es sogar sein). unmöglich)..
Ich habe versucht, diese Einschränkung zu umgehen mit dem Festlegen dieser komplexen Datenstruktur als globale Variable auf JS-Seite, aber ich konnte keine funktionierende Lösung finden.
Sehen Sie sich die Details hier an: Globale Variable in Bokeh initialisieren und im Handlercode verwenden?
Zusätzliche Informationen 2:
Die verwendete Schrittlogik ähnelt dieser:
Code: Select all
JS_CODE_STEP_LOGIC = """
const trigger_date = new Date(time_tracker.data['trigger_date'][0]);
let new_date = new Date(trigger_date);
new_date.setDate(new_date.getDate() + 1 * direction * get_tf_value(timeframe));
if (direction < 0){
new_date = new Date(Math.max(min_dt, new_date));
} else if (direction > 0){
new_date = new Date(Math.min(max_dt, new_date));
}
time_tracker.data['trigger_date'][0] = new_date.toISOString();
// I NEED TO DO THE FOLLOWING LOGIC FOR EACH TIMEFRAME
// THE NUMBER/VALUE OF TIMEFRAMES HERE ARE DYNAMIC
// THEREFORE THEY ARE ADDRESSING THE DATASOURCE IN THE HIERARCHY
for (const [timeframe, data] of Object.entries(candle_data_and_sources)) {
const filtererd_obejcts = {};
for (const [key, value] of Object.entries(data['candle_data'])) {
if(!filtererd_obejcts[key]){
filtererd_obejcts[key] = [];
}
}
for (let i = 0; i < data['candle_data'].trigger_dt.length; i++) {
if (new Date(data['candle_data'].trigger_dt[i])