Grid Indikator für MT4 und MT5

Das original Gitter des MT4 und MT5 ist meiner Ansicht nach unbrauchbar, weil die Linien irgendwohin gelegt werden.
Was ich sehen möchte ist ein Gitter, welches Perioden markiert und runde Preise, weswegen ich mein eigenes programmiert habe. Außerdem möchte ich nicht ständig die Einstellungen anpassen müssen, weil zuviele oder zuwenig Linien zu sehen sind. Mein Ziel bei diesem Grid bzw. Gitter ist also, dass es möglichst selbständig gute Abstände berechnet.
Ganz neu ist mein MQL5 Balance und EA Monitor.
Einstellung
Es gibt Haupt- und Zwischenlinien, wobei die Häufigkeit der Hauptlinien festgelegt werden kann, sowie das Erscheinungsbild der 4 Linientypen (2 senkrecht und 2 waagerecht). Für die Häufigkeit erscheint mir 2-fach oder 5-fach als sinnvolle Einstellung.
Alle Linien können in den Hintergrund gelegt werden und die Information kann ausgeblendet werden, so hat man wirklich nur ein Raster im Chart. Selbstverständlich können alle Linien auf die gleiche Farbe und den gleichen Linientyp eingestellt werden. Ich benutze dafür gerne "DimGray" oder "DarkSlateGray" mit Typ "Dot". Dadurch kann man es sich so einstellen, dass es wirklich nicht stört.

AV_Grid.mq5
Download Indikator AV_Grid.mq5 für MT4 und MT5. Hier folgt der Quellcode:
//+------------------------------------------------------------------+
//| AV_Grid.mq5 |
//| Copyright 2022, Anja Vogel |
//| https://www.anjavogel.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Anja Vogel"
#property link "https://www.anjavogel.com"
#define VERSION "1.8"
#property version VERSION
string indicatorName = "AV Grid V" + VERSION;
string indicatorShortname = "Grid " + VERSION;
#property description "Probiere folgende Farbsets für die Linien:"
#property description " "
#property description "a) LightBlue, CadetBlue, DarkGray, DimGray"
#property description "b) Silver, Gray, Silver, Gray"
#property description "c) 4x Gray"
#property description "d) 4x DarkSlateGray"
#property description " "
#property description "Probiere auch Foreground und Background des Charts"
#property description "auf die gleiche Farbe einzustellen, z.B 50,50,50"
#property description "und 4x Hintergrund = false."
#property description " "
#property description "Für ein besonders zurückhaltendes Raster, benutze z.B. "
#property description "4x DarkSlateGray und 4x Hintergrund = true."
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
input color infoColor = clrCadetBlue; // Info Schriftfarbe
input int infoSize = 10; // Info Schriftgröße
input bool showInfo = true; // Info anzeigen
#ifdef __MQL5__
input group "::: 1.1) Horizontale Hauptlinie :::"
#endif
input int every = 2; // Hauptlinie alle x Linien
input color horizontalColor1 = clrCadetBlue; // Farbe
input ENUM_LINE_STYLE horizontalStyle1 = STYLE_DOT; // Linientyp
input int horizontalWidth1 = 1; // Dicke
input bool horizontalBackground1 = false; // Hintergrund
#ifdef __MQL5__
input group "::: 1.2) Horizontale Zwischenlinie :::"
#endif
input color horizontalColor2 = clrLightSlateGray; // Farbe
input ENUM_LINE_STYLE horizontalStyle2 = STYLE_DOT; // Linientyp
input int horizontalWidth2 = 1; // Dicke
input bool horizontalBackground2 = true; // Hintergrund
#ifdef __MQL5__
input group "::: 2.1) Vertikale Hauptlinie :::"
#endif
input color vertikalColor1 = clrDarkGray; // Farbe
input ENUM_LINE_STYLE vertikalStyle1 = STYLE_DOT; // Linientyp
input int vertikalWidth1 = 1; // Dicke
input bool vertikalBackground1 = false; // Hintergrund
#ifdef __MQL5__
input group "::: 2.2) Vertikale Zwischenlinie :::"
#endif
input color vertikalColor2 = clrDimGray; // Farbe
input ENUM_LINE_STYLE vertikalStyle2 = STYLE_DOT; // Linientyp
input int vertikalWidth2 = 1; // Dicke
input bool vertikalBackground2 = true; // Hintergrund
input bool develop = false; // Entwickler
string vLabel = "vGrid-";
string hLabel = "hGrid-";
double lastWindowMax = 0.0;
double lastWindowMin = 0.0;
double lastMaxPrice = 0.0;
double lastMinPrice = 0.0;
double center = 0.0;
int diffDigits = 0;
double diffStep = 50.0;
long lastWithInBars = 0;
int mode = 0;
int lastMode = 0;
long pastBars = 1;
int vLines = 0;
//+------------------------------------------------------------------+
// OnInit()
//+------------------------------------------------------------------+
int OnInit()
{
diffDigits = _Digits - 2;
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortname);
PlotIndexSetString(0, PLOT_LABEL, indicatorName);
EventSetTimer(1); // Timer mit x Sekunden
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
// OnDeinit()
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0, "Grid");
ObjectsDeleteAll(0, hLabel);
ObjectsDeleteAll(0, vLabel);
EventKillTimer();
}
//+------------------------------------------------------------------+
// OnTimer()
//+------------------------------------------------------------------+
void OnTimer()
{
if (MQLInfoInteger(MQL_TESTER)) return;
double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX);
double minPrice = ChartGetDouble(0,CHART_PRICE_MIN);
if (maxPrice == 0.0) return;
if (maxPrice != lastWindowMax || minPrice != lastWindowMin || lastWithInBars != ChartGetInteger(0,CHART_WIDTH_IN_BARS)) {
if (!calculateLines()) {
//out("Lösche alle horizontalen Linien wegen neuem Abstand!");
lastMaxPrice = 0.0;
lastMinPrice = 0.0;
ObjectsDeleteAll(0, hLabel);
}
// zeichne Linien
drawHorizontal();
drawVertical();
// Nach dem Zeichnen Fenstergröße speichern
lastWindowMax = maxPrice;
lastWindowMin = minPrice;
//if (develop) ChartWrite("Grid", TimeToString(TimeCurrent(),TIME_SECONDS) + " (" + (string)diffStep + ") " + _Symbol + " (" + (string)NormalizeDouble((maxPrice - minPrice) / diffStep, 1) + " Linien|Mode " + (string)mode + "|S." + (string)ChartGetInteger(0,CHART_SCALE,0) + ") "+ DoubleToStr(_Point, _Digits) + " / " + 100*pointToPip(), 15, 25);
if (develop) ChartWrite("Grid", "V" + VERSION + " " + TimeToString(TimeCurrent(),TIME_SECONDS) + " | " + (string)(diffStep * pointToPip()) + " Pip | " + _Symbol + " | " + getModeName(), 15, 25);
else if (showInfo) ChartWrite("Grid", (string)(diffStep * pointToPip()) + " Pip | " + _Symbol + " | " + getModeName(), 15, 25);
}
}
//+------------------------------------------------------------------+
// OnCalculate()
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// siehe OnTimer()
if (MQLInfoInteger(MQL_TESTER)) {
// zeichne Linien
drawHorizontal();
drawVertical();
ChartWrite("Grid", "(" + (string)diffStep + ") " + _Symbol + " (Mode " + (string)mode + "|S." + (string)ChartGetInteger(0,CHART_SCALE,0) + ")", 15, 25);
}
return(rates_total);
}
//+------------------------------------------------------------------+
// horizontale Linien
//+------------------------------------------------------------------+
void drawHorizontal()
{
double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX);
double minPrice = ChartGetDouble(0,CHART_PRICE_MIN);
center = calculateCenter();
DrawHLine(hLabel, NormalizeDouble(center, _Digits), TimeCurrent(), calculateBold(center)); // wichtigste Linie
if (develop) ObjectSetInteger(0, hLabel, OBJPROP_COLOR, clrYellow);
double walk = lastMaxPrice != 0.0 ? lastMaxPrice : center; // starte an der letzen Linie nach oben
while (walk < maxPrice) {
if (diffStep > 0) walk += diffStep;
else walk = maxPrice; // Ausstieg
DrawHLine(hLabel + DoubleToString(walk, _Digits), NormalizeDouble(walk, _Digits), TimeCurrent(), calculateBold(walk));
lastMaxPrice = walk;
}
walk = lastMinPrice != 0.0 ? lastMinPrice : center; // starte an der letzen Linie nach unten
while (walk > minPrice) {
if (diffStep > 0) walk -= diffStep;
else walk = minPrice; // Ausstieg
DrawHLine(hLabel + DoubleToString(walk, _Digits), NormalizeDouble(walk, _Digits), TimeCurrent(), calculateBold(walk));
lastMinPrice = walk;
}
}
//+------------------------------------------------------------------+
// vertikale Linien
//+------------------------------------------------------------------+
void drawVertical()
{
double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX);
double minPrice = ChartGetDouble(0,CHART_PRICE_MIN);
// Zur Ermittlung der Anzahl der Minuten des jeweiligen Zeitrahmens
// ist der Wert der Funktion PeriodSeconds durch 60 zu dividieren.
int seconds = PeriodSeconds(ChartPeriod(0)); // /60
int shift = 0;
pastBars = Bars(NULL, 0) - 2;
if (MQLInfoInteger(MQL_TESTER) || pastBars < 1) { // Strategietester
pastBars = 1;
}
if (seconds <= PeriodSeconds(PERIOD_M1)) { // Tageswechsel & H4, H1-Wechsel
mode = 1;
if (ChartGetInteger(0,CHART_SCALE,0) < 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_M5)) { // Tageswechsel & H8, H2-Wechsel
mode = 2;
if (ChartGetInteger(0,CHART_SCALE,0) <= 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_M15)) { // Tageswechsel, H8-Wechsel
mode = 3;
if (ChartGetInteger(0,CHART_SCALE,0) <= 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_H1)) { // Wochenwechsel, Tageswechsel
mode = 4;
if (ChartGetInteger(0,CHART_SCALE,0) <= 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_H4)) { // Monatswechsel, Wochenwechsel
mode = 5;
if (ChartGetInteger(0,CHART_SCALE,0) <= 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_D1)) { // Quartalswechsel, Monatswechsel
mode = 6;
if (ChartGetInteger(0,CHART_SCALE,0) <= 1) mode++;
if (ChartGetInteger(0,CHART_SCALE,0) >= 4) mode--;
} else if (seconds <= PeriodSeconds(PERIOD_W1)) { // Halbjahreswechsel, Quartalswechsel
mode = 7;
if (ChartGetInteger(0,CHART_SCALE,0) == 0) mode = 9;
if (ChartGetInteger(0,CHART_SCALE,0) == 1) mode = 9;
if (ChartGetInteger(0,CHART_SCALE,0) == 2) mode = 8;
if (ChartGetInteger(0,CHART_SCALE,0) == 5) mode = 6;
} else if (seconds > PeriodSeconds(PERIOD_W1)) { // Jahreswechsel, Halbjahreswechsel
mode = 8;
if (ChartGetInteger(0,CHART_SCALE,0) <= 2) mode++;
} // mode = 9 heißt alle 10 Jahre, alle 5 Jahre
if (mode < 0) mode = 0;
if (mode > 9) mode = 9;
if (lastMode != mode || lastWithInBars != ChartGetInteger(0,CHART_WIDTH_IN_BARS)) {
out("Lösche vertikalen Linien wegen Mode- oder Breiten-Änderung und zeichne neu!");
ObjectsDeleteAll(0, vLabel);
lastMode = mode;
lastWithInBars = ChartGetInteger(0,CHART_WIDTH_IN_BARS);
}
vLines = 0;
for (shift = 0; shift <= pastBars; shift++) {
if (vLines > 500) break;
if (mode == 0) { // H4, H1-Wechsel
if (TimeHour(Time[shift+1]) != TimeHour(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], (TimeHour(Time[shift]) % 4 == 0));
}
}
else if (mode == 1) { // Tageswechsel & H4, H1-Wechsel
if (TimeDay(Time[shift+1]) != TimeDay(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], true);
}
else if (TimeHour(Time[shift+1]) != TimeHour(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], (TimeHour(Time[shift]) % 4 == 0));
}
}
else if (mode == 2) { // Tageswechsel & H8, H2-Wechsel
if (TimeDay(Time[shift+1]) != TimeDay(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], true);
}
else if (TimeHour(Time[shift+1]) != TimeHour(Time[shift])) {
if (TimeHour(Time[shift]) % 2 == 0)
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], (TimeHour(Time[shift]) % 8 == 0));
}
}
else if (mode == 3) { // Tageswechsel, H8-Wechsel
if (TimeDay(Time[shift+1]) != TimeDay(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], true);
}
else if (TimeHour(Time[shift+1]) != TimeHour(Time[shift])) {
if (TimeHour(Time[shift]) % 8 == 0)
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], false);
}
}
else if (mode == 4) { // Wochenwechsel, Tageswechsel
if (TimeDayOfWeek(Time[shift+1]) > TimeDayOfWeek(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], true);
}
else if (TimeDay(Time[shift+1]) != TimeDay(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], false);
}
}
else if (mode == 5) { // Monatswechsel, Wochenwechsel
if (TimeDay(Time[shift+1]) > TimeDay(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], true);
}
else if (TimeDayOfWeek(Time[shift+1]) > TimeDayOfWeek(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], false);
}
}
else if (mode == 6) { // Quartalswechsel, Monatswechsel
if (TimeMonth(Time[shift+1]) != TimeMonth(Time[shift])) {
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], TimeMonth(Time[shift]) % 3 == 0);
}
}
else if (mode == 7) { // Halbjahreswechsel, Quartalswechsel
if (TimeMonth(Time[shift+1]) != TimeMonth(Time[shift])) {
if (TimeMonth(Time[shift]) % 3 == 0)
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], TimeMonth(Time[shift]) % 6 == 0);
}
}
else if (mode == 8) { // Jahreswechsel, Halbjahreswechsel
if (TimeMonth(Time[shift+1]) != TimeMonth(Time[shift])) {
if (TimeMonth(Time[shift]) % 6 == 0)
DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], TimeMonth(Time[shift]) % 12 == 0);
}
}
else if (mode == 9) { // alle 10 Jahre, alle 5 Jahre
if (TimeYear(Time[shift+1]) != TimeYear(Time[shift])) {
if (TimeYear(Time[shift]) % 5 == 0) DrawVLine(vLabel + TimeToString(Time[shift]), minPrice, Time[shift], TimeYear(Time[shift]) % 10 == 0);
}
}
}
}
//+------------------------------------------------------------------+
// getModeName()
//+------------------------------------------------------------------+
string getModeName()
{
switch(mode) {
case 0: return "H4 + H1";
case 1: return "D + H1";
case 2: return "D + H2";
case 3: return "D + H8";
case 4: return "W + D";
case 5: return "MN + W";
case 6: return "MN3 + MN";
case 7: return "MN6 + MN3";
case 8: return "Y + MN6";
case 9: return "Y10 + Y5";
}
return "-";
}
//+------------------------------------------------------------------+
// Berechne einen guten Preis-Abstand
//+------------------------------------------------------------------+
bool calculateLines()
{
double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX);
double minPrice = ChartGetDouble(0,CHART_PRICE_MIN);
double oldDiffStep = diffStep;
diffDigits = _Digits - 2;
switch (diffDigits) {
case 1: // 3 Nachkommastellen
diffStep = 1.0;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.5;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.25;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.1;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.05;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.025;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.01;
}
}
}
}
}
}
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 2.5;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 5.0;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 10.0;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 25.0;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 50.0;
}
}
}
}
}
break;
case 2: // 4 Nachkommastellen
diffStep = 0.1;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.05;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.025;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.01;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.005;
}
}
}
}
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.25;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.5;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 1.0;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 5.0;
}
}
}
}
break;
case 3: // 5 Nachkommastellen
diffStep = 0.01;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.005;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.0025;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.001;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 0.0005;
}
}
}
}
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.025;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.05;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.1;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 0.25;
}
}
}
}
break;
default: // 2 Nachkommastellen
diffStep = 100;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 50;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 25;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 10;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 5;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 2.5;
if ((maxPrice - minPrice) / diffStep <= 3) {
diffStep = 1;
}
}
}
}
}
}
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 250;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 500;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 1000;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 2500;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 5000;
if ((maxPrice - minPrice) / diffStep >= 9) {
diffStep = 10000;
}
}
}
}
}
}
}
if (oldDiffStep != diffStep) {
return false; // neu zeichnen
}
return true; // alles gut
}
//+------------------------------------------------------------------+
// Berechne, ob die Preis-Linie eine Hauptlinie ist
//+------------------------------------------------------------------+
bool calculateBold(double walk)
{
bool st = false;
if (diffStep >= 1) st = ((int)MathAbs(walk-center) % (int)(every * diffStep)) == 0 ? true : false;
// (walk - center) % (every * diffStep)
if (diffStep < 1) st = (int)(MathRound(10000 * MathAbs(walk-center))) % (int)(MathRound(10000 * every * diffStep)) == 0 ? true : false;
return st;
}
//+------------------------------------------------------------------+
// Berechne die erste Linie, von der aus nach oben und unten gezeichnet wird
//+------------------------------------------------------------------+
double calculateCenter()
{
double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX);
double minPrice = ChartGetDouble(0,CHART_PRICE_MIN);
double existingCenter = ObjectGetDouble(0, hLabel, OBJPROP_PRICE); // gibt es die wichtigste Linie schon?
if (existingCenter > 0) center = existingCenter;
if (center == 0.0) {
center = NormalizeDouble((maxPrice + minPrice)/2, diffDigits); // Forex
if (diffStep >= 1) {
center = (int)center - ((int)center % (int)(diffStep*2)); // Rest abziehen z.B. für DAX
}
if (diffStep <= 0.25) { // && diffStep >= 0.005
center = diffStep * (int)MathRound(1/diffStep * center); // Korrektur für z.B 0.77400 und 0.77900
}
if (diffStep < 0.01) {
center = NormalizeDouble(center, 2); // 0.001 bis 0.005
} else if (diffStep < 0.1) {
center = NormalizeDouble(center, 1); // 0.01 bis 0.05
} else if (diffStep < 1.0) {
center = NormalizeDouble(center, 0); // 0.1 bis 0.5
}
if (diffStep == 2.5) {
center = (int)center - ((int)center % 5); // XAUUSD
}
}
//if (existingCenter != center) out((string)existingCenter + " center " + (string)center);
return center;
}
//+------------------------------------------------------------------+
// Zeichne horizontale Linie
//+------------------------------------------------------------------+
void DrawHLine(string label, double price, datetime timeShift, bool strong = false)
{
if (price == 0.0 && label == hLabel) return;
/*if (ObjectFind(0, label) >= 0) { // dauert länger
return;
}*/
ObjectCreate(0, label, OBJ_HLINE, 0, timeShift, NormalizeDouble(price, _Digits));
ObjectSetInteger(0, label, OBJPROP_HIDDEN, !develop);
ObjectSetInteger(0, label, OBJPROP_SELECTABLE, false);
ObjectSetString(0, label, OBJPROP_TOOLTIP, DoubleToString(price, _Digits));
if (strong) {
ObjectSetInteger(0, label, OBJPROP_STYLE, horizontalStyle1);
ObjectSetInteger(0, label, OBJPROP_WIDTH, horizontalWidth1);
ObjectSetInteger(0, label, OBJPROP_COLOR, horizontalColor1);
ObjectSetInteger(0, label, OBJPROP_BACK, horizontalBackground1);
} else {
ObjectSetInteger(0, label, OBJPROP_STYLE, horizontalStyle2);
ObjectSetInteger(0, label, OBJPROP_WIDTH, horizontalWidth2);
ObjectSetInteger(0, label, OBJPROP_COLOR, horizontalColor2);
ObjectSetInteger(0, label, OBJPROP_BACK, horizontalBackground2);
}
// Strategietester zu unruhig
if (MQLInfoInteger(MQL_TESTER)) {
ObjectSetInteger(0, label, OBJPROP_BACK, true);
}
}
//+------------------------------------------------------------------+
// Zeichne vertikale Linie
//+------------------------------------------------------------------+
void DrawVLine(string label, double price, datetime timeShift, bool strong = false)
{
/*if (ObjectFind(0, label) >= 0) { // dauert länger
return;
}*/
vLines++;
ObjectCreate(0, label, OBJ_VLINE, 0, timeShift, price);
ObjectSetInteger(0, label, OBJPROP_HIDDEN, !develop);
ObjectSetInteger(0, label, OBJPROP_SELECTABLE, false);
if (strong) {
ObjectSetInteger(0, label, OBJPROP_STYLE, vertikalStyle1);
ObjectSetInteger(0, label, OBJPROP_WIDTH, vertikalWidth1);
ObjectSetInteger(0, label, OBJPROP_COLOR, vertikalColor1);
ObjectSetInteger(0, label, OBJPROP_BACK, vertikalBackground1);
} else {
ObjectSetInteger(0, label, OBJPROP_STYLE, vertikalStyle2);
ObjectSetInteger(0, label, OBJPROP_WIDTH, vertikalWidth2);
ObjectSetInteger(0, label, OBJPROP_COLOR, vertikalColor2);
ObjectSetInteger(0, label, OBJPROP_BACK, vertikalBackground2);
}
if (TimeMinute(timeShift) == 0 && TimeHour(timeShift) == 0) {
ObjectSetString(0, label, OBJPROP_TOOLTIP, TimeToString(timeShift, TIME_DATE));
} else {
ObjectSetString(0, label, OBJPROP_TOOLTIP, TimeToString(timeShift, TIME_DATE | TIME_MINUTES));
}
}
//+------------------------------------------------------------------+
// Schreibe Information
//+------------------------------------------------------------------+
void ChartWrite(string name,
string comment,
int x_distance,
int y_distance)
{
// Label bereits vorhanden?
if (ObjectFind(0, name) < 0) {
// erstellen
if (!ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0)) {
return;
}
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, infoSize);
ObjectSetString(0, name, OBJPROP_FONT, "Lucida Console");
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x_distance);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_distance);
}
// aktualisieren
ObjectSetInteger(0, name, OBJPROP_COLOR, infoColor);
ObjectSetString(0, name, OBJPROP_TEXT, comment);
}
//+------------------------------------------------------------------+
// pointToPip()
//+------------------------------------------------------------------+
// Wenn 1-, 2- oder 0-stellig quotiert wird, ist 1 Pip = 1.0
// Wenn 3- quotiert wird, ist 1 Pip = 0.01
// Wenn 5- oder 4-stellig quotiert wird, ist 1 Pip = 0.0001
//+------------------------------------------------------------------+
double pointToPip()
{
if (_Digits <= 2) return 1.0;
if (_Digits == 3) return 0.01;
return 0.0001;
}
//+------------------------------------------------------------------+
// Logge Information, nur wenn eingeschaltet (gut bei Nutzung in mehreren Charts)
//+------------------------------------------------------------------+
void out(string text)
{
if (develop) Print(_Symbol, " ----------- ", text, " ----------- ");
}
//+------------------------------------------------------------------+
#ifdef __MQL5__
int TimeDay(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.day);
}
int TimeDayOfWeek(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.day_of_week);
}
int TimeDayOfYear(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.day_of_year);
}
int TimeHour(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.hour);
}
int TimeMinute(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.min);
}
int TimeMonth(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.mon);
}
int TimeSeconds(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.sec);
}
int TimeYear(datetime date) {
MqlDateTime tm;
TimeToStruct(date,tm);
return(tm.year);
}
#define DEFINE_TIMESERIE(NAME,FUNC,T) \
class CLASS##NAME \
{ \
public: \
static T Get(const string Symb,const int TimeFrame,const int iShift) \
{ \
T tValue[]; \
\
return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
} \
\
T operator[](const int iPos) const \
{ \
return(CLASS##NAME::Get(_Symbol, _Period, iPos)); \
} \
}; \
\
CLASS##NAME NAME;
DEFINE_TIMESERIE(Volume, TickVolume,long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
#endif // __MQL5__
//+------------------------------------------------------------------+
Externe Links
Bevor ich mein eigenes Grid gebaut habe, war das folgende bei mir im MT4 im Einsatz:
MQL4 AlterGrid v2 IndikatorMöchtest du MQL programmieren lernen? Dieser Kurs macht wirklich Spaß und kostet nur einen Euro. Mein Prädikat: ausgezeichnet und auch nicht langweilig mit Vorwissen:
MQL5 EinsteigerkursMQL4 Einsteigerkurs