und werden Sie Mitglied unserer Fangruppe
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Bewerten Sie es im Terminal MetaTrader 5
- Ansichten:
- 54
- Rating:
- Veröffentlicht:
-
Benötigen Sie einen Roboter oder Indikator, der auf diesem Code basiert? Bestellen Sie ihn im Freelance-Bereich Zum Freelance
Die Standard-API-Funktionen ChartXYToTimePrice und ChartTimePriceToXY haben erhebliche Nachteile. So arbeitet ChartXYToTimePrice nur dann korrekt, wenn die Eingabeparameter X und Y im sichtbaren Bereich des Chart-Fensters liegen, außerhalb des Fensters gibt die Funktion Nullen zurück. ChartTimePriceToXY arbeitet in einigen Fällen ebenfalls fehlerhaft. Beide Funktionen sind langsam.
Ich stelle die Funktionen vor, die in allen Bereichen der Eingabeparameter korrekt arbeiten:
int GetXFromTime(datetime time) { int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double pixels_per_time = (double)pixels_per_bar / PeriodSeconds(); int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); datetime time_0 = iTime(Symbol(), Period(), 0); if(time <= time_0) { int nearest_bar = iBarShift(Symbol(), Period(), time); datetime time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); datetime time_remaining = time - time_nearest_bar; time_remaining -= (int)MathFloor(time_remaining / PeriodSeconds()) * PeriodSeconds(); return (first_bar - nearest_bar) * pixels_per_bar + (int)MathRound(time_remaining * pixels_per_time); } else return first_bar * pixels_per_bar + (int)MathRound((time - time_0) * pixels_per_time); } //+------------------------------------------------------------------+ int GetYFromPrice(double price) { double price_max = ChartGetDouble(0, CHART_PRICE_MAX); double price_min = ChartGetDouble(0, CHART_PRICE_MIN); double pixels_per_price = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) / (price_max - price_min); return (int)MathRound((price_max - price) * pixels_per_price); } //+------------------------------------------------------------------+ datetime GetTimeFromX(int x_dist) { int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double time_per_pixel = (double)PeriodSeconds() / pixels_per_bar; datetime time_remaining = (int)(((double)x_dist / pixels_per_bar - (int)(x_dist / pixels_per_bar)) * pixels_per_bar * time_per_pixel); int nearest_bar = first_bar - (int)(x_dist / pixels_per_bar); datetime time_nearest_bar = {}; if(nearest_bar < 0) { datetime time_0 = iTime(Symbol(), Period(), 0); datetime delta_time_start = time_0 - time_first_bar; datetime delta_time_stop = (0 - nearest_bar) * PeriodSeconds(); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double GetPriceFromY(int y_dist) { double price_per_pixel = (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); double price_max = ChartGetDouble(0, CHART_PRICE_MAX); return price_max - price_per_pixel * y_dist; } //+------------------------------------------------------------------+
Ein Skript, das die Korrektheit der Arbeit der Funktionen demonstriert. Das Wesen der Funktion besteht darin, dass die generierten X- und Y-Koordinaten in Zeit und Preis umgewandelt werden, und dann wieder in X und Y. Wenn die eingegebenen X- und Y-Koordinaten von den ausgegebenen abweichen, bedeutet dies, dass die Funktionen Probleme haben, und das Skript gibt die Diskrepanz aus. Wenn alles in Ordnung ist, druckt das Skript während der Arbeit nichts aus, aber ganz am Ende gibt es das Ergebnis aus
void OnStart() { int generations_total = {}; int deviations_total = {}; uint time_start_script = GetTickCount(); while(!IsStopped()) { int x_input = 16383 - MathRand(); int y_input = 16383 - MathRand(); int first_bar_downloaded = TerminalInfoInteger(TERMINAL_MAXBARS) - 1; datetime time_first_bar_downloaded = iTime(Symbol(), Period(), first_bar_downloaded); double price_max_start = ChartGetDouble(0, CHART_PRICE_MAX); double price_min_start = ChartGetDouble(0, CHART_PRICE_MIN); int first_bar_start = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); int chart_scale_start = (int)ChartGetInteger(0, CHART_SCALE); int x_0 = GetXFromTime(time_first_bar_downloaded); int y_0 = GetYFromPrice(0); if(x_input < x_0) x_input = x_0; if(y_input > y_0) y_input = y_0; datetime time = GetTimeFromX(x_input); double price = GetPriceFromY(y_input); int x_output = GetXFromTime(time); int y_output = GetYFromPrice(price); double price_max_stop = ChartGetDouble(0, CHART_PRICE_MAX); double price_min_stop = ChartGetDouble(0, CHART_PRICE_MIN); int first_bar_stop = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); int chart_scale_stop = (int)ChartGetInteger(0, CHART_SCALE); if(price_max_start == price_max_stop && price_min_start == price_min_stop && first_bar_start == first_bar_stop && chart_scale_start == chart_scale_stop)//Überprüfen Sie, dass sich bei der Übertragung der Koordinaten von einem System in ein anderes und zurück der Maßstab und die Position der Karte nicht ändern. { ++generations_total; if(x_input != x_output || y_input != y_output) { ++deviations_total; Print("!!! deviation detected !!!"); Print("x_input= ", x_input, " y_input= ", y_input); Print("x_output= ", x_output, " y_output= ", y_output); } } } Print("Test ended up with ", deviations_total, " deviations"); if(deviations_total == 0) Print("Everything is Ok"); Print("generations_total= ", generations_total); int generations_rate = generations_total / ((double)(GetTickCount() - time_start_script) / 1000); Print("generations rate= ", generations_rate, " generations / sec"); } //+------------------------------------------------------------------+ int GetXFromTime(datetime time) { int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double pixels_per_time = (double)pixels_per_bar / PeriodSeconds(); int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); datetime time_0 = iTime(Symbol(), Period(), 0); if(time <= time_0) { int nearest_bar = iBarShift(Symbol(), Period(), time); datetime time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); datetime time_remaining = time - time_nearest_bar; time_remaining -= (int)MathFloor(time_remaining / PeriodSeconds()) * PeriodSeconds(); return (first_bar - nearest_bar) * pixels_per_bar + (int)MathRound(time_remaining * pixels_per_time); } else return first_bar * pixels_per_bar + (int)MathRound((time - time_0) * pixels_per_time); } //+------------------------------------------------------------------+ int GetYFromPrice(double price) { double price_max = ChartGetDouble(0, CHART_PRICE_MAX); double price_min = ChartGetDouble(0, CHART_PRICE_MIN); double pixels_per_price = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) / (price_max - price_min); return (int)MathRound((price_max - price) * pixels_per_price); } //+------------------------------------------------------------------+ datetime GetTimeFromX(int x_dist) { int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double time_per_pixel = (double)PeriodSeconds() / pixels_per_bar; datetime time_remaining = (int)(((double)x_dist / pixels_per_bar - (int)(x_dist / pixels_per_bar)) * pixels_per_bar * time_per_pixel); int nearest_bar = first_bar - (int)(x_dist / pixels_per_bar); datetime time_nearest_bar = {}; if(nearest_bar < 0) { datetime time_0 = iTime(Symbol(), Period(), 0); datetime delta_time_start = time_0 - time_first_bar; datetime delta_time_stop = (0 - nearest_bar) * PeriodSeconds(); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double GetPriceFromY(int y_dist) { double price_per_pixel = (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); double price_max = ChartGetDouble(0, CHART_PRICE_MAX); return price_max - price_per_pixel * y_dist; } //+------------------------------------------------------------------+
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalpublikation: https://www.mql5.com/ru/code/48325
Entwicklung von Multicurrency Expert Advisor - Quellcodes aus der Artikelserie
Quellcodes, die im Rahmen der Entwicklung einer Bibliothek zur Erstellung von Expert Advisors für mehrere Währungen geschrieben wurden, die mehrere Instanzen verschiedener Handelsstrategien kombinieren.
Entwicklung eines Multi-Currency Expert Advisors - Quellcodes aus einer Reihe von Artikeln
Die Quellcodes, die während der Entwicklung der Bibliothek zur Erstellung von Multiwährungs-Expert Advisors geschrieben wurden, die viele Instanzen verschiedener Handelsstrategien kombinieren.
Simple Bar Timer
Es ist ein Skript, das die verbleibende Zeit bis zum Eintreffen des nächsten Taktes anzeigt.
TimeGMT library for the strategy tester
Statische Klasse zur Fixierung der Funktion TimeGMT() während des Tests im Strategietester.