TendenciaPrecioFecha
- Utilitys
- Version: 1.31
AutoFindBestTrendLine – Automatischer Trendlinien-Erkenner
Allgemeine Beschreibung: AutoFindBestTrendLine ist ein Dienstprogramm für MetaTrader 5, das den historischen Chartverlauf analysiert und automatisch die bestmögliche Trendlinie ermittelt, sei es anhand von Höchstständen (Widerständen), Tiefstständen (Unterstützungen) oder beidem. Das Skript identifiziert die beiden relevantesten Punkte und zeichnet eine optimale Linie, die auf der Anzahl der tatsächlichen Berührungspunkte mit dem Kurs basiert.
Wichtigste Vorteile:
-
Automatische Erkennung von Trendlinien ohne manuelles Eingreifen.
-
Funktioniert bei jedem Symbol und jedem Zeitrahmen.
-
Ermöglicht die Wahl zwischen der Analyse von Höchst- und Tiefstständen oder beidem.
-
Zeichnet Linien mit konfigurierbarer Farbe, Stil und Stärke.
-
Bisherige Linien werden nicht gelöscht: Bei jeder Ausführung wird eine neue Linie erstellt.
-
Leicht, schnell und ohne kontinuierlichen Ressourcenverbrauch (es handelt sich um ein Skript).
-
Ideal für technische Trader, die nach echten Unterstützungs- und Widerstandsniveaus suchen.
So funktioniert es: Das Skript analysiert alle Kerzen ab dem angegebenen Datum und wertet Punktkombinationen aus, um die Linie mit der höchsten Anzahl an Berührungspunkten zu finden. Sobald diese erkannt wurde, zeichnet es sie automatisch in den Chart ein und zeigt detaillierte Informationen im Protokoll an.
Eingabeparameter:
-
InpStartDate – Startdatum der Analyse.
-
InpSearchMode – Suchart: Höchststände, Tiefststände oder beides.
-
InpLineColor – Farbe der Trendlinie.
-
InpLineStyle – Linienstil (durchgehend, gestrichelt, gepunktet).
-
InpLineWidth – Linienstärke (1 bis 5).
Empfohlene Verwendung: Führen Sie das Skript in einem beliebigen Chart aus, um eine optimale Trendlinie zu erhalten, die auf dem tatsächlichen Kursverhalten basiert. Nützlich zur Validierung von Unterstützungs- und Widerstandszonen, zur Erkennung technischer Strukturen und zur Ergänzung manueller Analysen. //+------------------------------------------------------------------+
//| AutoFindBestTrendLine.mq5 |
//| Copyright 2026 |
//| |
//+------------------------------------------------------------------+
#property copyright „Copyright 2026“
#property link ""
#property version „1.31“
#property script_show_inputs
// Aufzählung zur Auswahl der zu analysierenden Punktarten
enum ENUM_SEARCH_MODE
{
SEARCH_BOTH = 0, // Hochs und Tiefs analysieren
SEARCH_HIGHS_ONLY = 1, // Nur Höchststände (Widerstände)
SEARCH_LOWS_ONLY = 2 // Nur Unterstützungen (Tiefstwerte)
};
// Konfigurierbare Eingabeparameter
input datetime InpStartDate = D'2026.01.01 00:00'; // Startdatum der Analyse
input ENUM_SEARCH_MODE InpSearchMode = SEARCH_BOTH; // Suchmodus
input color InpLineColor = clrDodgerBlue; // Farbe der Trendlinie
input ENUM_LINE_STYLE InpLineStyle = STYLE_SOLID; // Linienstil (durchgehend, gestrichelt, gepunktet...)
input int InpLineWidth = 3; // Linienstärke (1 bis 5)
//+------------------------------------------------------------------+
//| Startfunktion des Skripts |
//+------------------------------------------------------------------+
void OnStart()
{
// 1. Daten aus den Balken des aktuellen Charts kopieren
MqlRates rates[];
ArraySetAsSeries(rates, true);
int totalBars = CopyRates(_Symbol, _Period, 0, Bars(_Symbol, _Period), rates);
if(totalBars < 5)
{
Print("Fehler: Es sind nicht genügend Balken im Chart vorhanden, um eine Analyse durchzuführen.");
return;
}
// Den Index des Balkens ermitteln, der dem ausgewählten Startdatum entspricht
int startIndex = -1;
for(int i = 0; i < totalBars; i++)
{
if(rates[i].time <= InpStartDate)
{
startIndex = i;
break;
}
}
if(startIndex < 0)
{
startIndex = totalBars - 1; // Wenn das Datum älter ist als der Verlauf, wird das älteste verfügbare Datum verwendet
}
Print("==================================================");
Print(" AUTOMATISCHER SCAN WIRD GESTARTET");
Print(" Seit: ", TimeToString(rates[startIndex].time, TIME_DATE|TIME_MINUTES), " | Analysierte Kerzen: ", startIndex + 1);
Print("==================================================");
int bestTouches = -1;
datetime bestT1 = 0, bestT2 = 0;
double bestP1 = 0.0, bestP2 = 0.0;
string lineTypeFound = "";
// 2. Kombinationen entsprechend dem ausgewählten Modus auswerten (angepasst, um kurze Grafiken zu berücksichtigen)
int minLimit = MathMin(2, startIndex);
for(int i = startIndex; i >= minLimit; i--)
{
for(int j = i - 1; j >= 0; j--)
{
datetime t1 = rates[i].time;
datetime t2 = rates[j].time;
if(t1 == t2) continue;
// Höchststände auswerten
if(InpSearchMode == SEARCH_BOTH || InpSearchMode == SEARCH_HIGHS_ONLY)
{
double p1 = rates[i].high;
double p2 = rates[j].high;
int touches = CountLineTouches(p1, t1, p2, t2, rates, startIndex);
if(touches > bestTouches)
{
bestTouches = touches;
bestT1 = t1; bestP1 = p1;
bestT2 = t2; bestP2 = p2;
lineTypeFound = "Widerstand (High-High)";
}
}
// Minima auswerten
if(InpSearchMode == SEARCH_BOTH || InpSearchMode == SEARCH_LOWS_ONLY)
{
double p1 = rates[i].low;
double p2 = rates[j].low;
int touches = CountLineTouches(p1, t1, p2, t2, rates, startIndex);
if(touches > bestTouches)
{
bestTouches = touches;
bestT1 = t1; bestP1 = p1;
bestT2 = t2; bestP2 = p2;
lineTypeFound = "Stütze (Low-Low)";
}
}
}
}
if(bestTouches <= 0)
{
Print("Hinweis: Es konnte keine Linie gezeichnet werden. Versuche, in den Skript-Einstellungen ein neueres Startdatum (z. B. vor wenigen Tagen) einzugeben.");
return;
}
// 3. Einen EINDEUTIGEN Namen erstellen, damit die vorherigen Linien nicht gelöscht werden
string lineName = StringFormat("AutoTrend_%d", GetTickCount());
if(ObjectCreate(0, lineName, OBJ_TREND, 0, bestT1, bestP1, bestT2, bestP2))
{
// Layout und Strahlen konfigurieren und die Bearbeitung mit der Maus ermöglichen
ObjectSetInteger(0, lineName, OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, lineName, OBJPROP_RAY_RIGHT, true);
ObjectSetInteger(0, lineName, OBJPROP_COLOR, InpLineColor);
ObjectSetInteger(0, lineName, OBJPROP_STYLE, InpLineStyle);
ObjectSetInteger(0, lineName, OBJPROP_WIDTH, InpLineWidth);
ObjectSetInteger(0, lineName, OBJPROP_SELECTABLE, true);
ObjectSetInteger(0, lineName, OBJPROP_HIDDEN, false);
ChartRedraw(0);
}
// 4. Detaillierte Informationen im Protokoll anzeigen
Print("==================================================");
Print(" OPTIMALER TREND GEFUNDEN UND DARGESTELLT:");
Print(" Name des Objekts: ", lineName);
Print(" Erkannter Typ: ", lineTypeFound);
Print(" [KOPIEREN] Punkt 1 -> Zeit: ", TimeToString(bestT1, TIME_DATE|TIME_MINUTES), " | Kurs: ", DoubleToString(bestP1, _Digits));
Print(" [KOPIEREN] Punkt 2 -> Zeit: ", TimeToString(bestT2, TIME_DATE|TIME_MINUTES), " | Kurs: ", DoubleToString(bestP2, _Digits));
Print(" Berührte Kerzen : ", bestTouches);
Print("==================================================");
}
// Hilfsfunktion zum Zählen der Berührungen
int CountLineTouches(double p1, datetime t1, double p2, datetime t2, const MqlRates &rates[], int limitIndex)
{
int touches = 0;
double slope = (double)(p2 - p1) / (double)(t2 - t1);
for(int k = limitIndex; k >= 0; k--)
{
datetime barTime = rates[k].time;
double linePrice = p1 + (double)(barTime - t1) * slope;
if(linePrice >= rates[k].low && linePrice <= rates[k].high)
{
touches++;
}
}
return touches;
}
