Wir sollten versuchen, unnötige Zyklen zu vermeiden. Wir haben eine Flut von Zitaten, und Sie müssen sofort die richtigen Einträge machen, damit Sie nicht in der Geschichte wühlen und Computerressourcen verschwenden müssen.
Ich fühle mich wie ein Erstklässler, obwohl ich 42 bin.
Wir sollten versuchen, unnötige Schleifen zu vermeiden. Wir haben Angebote, die in Strömen eingehen, und müssen die richtigen Einträge sofort vornehmen, damit wir nicht in der Historie wühlen und Computerressourcen verschwenden müssen.
Ich habe Ihren Code ausgeführt.
Ist hier etwas nicht in Ordnung?
#property version"1.00"#property strict//символ и таймфрейм текущего графикаstring symbol;
ENUM_TIMEFRAMES frame;
datetime time;
struct BarData
{
struct Elem
{
int number; //порядковый номер периода (дня, месяца или года)double high; //максимум периодаdouble low; //минимум периодаdatetime time_high; //время максимумаdatetime time_low; //время минимума
} Arr[]; //массив периодаint index; //текущий индекс массиваdouble max; //последнее максимальное значение периодаdouble min; //последнее минимальное значение периодаdatetime time_max; //время максимумаdatetime time_min; //время минимума//при создании структуры указываем, что массив пустой
BarData(){index=-1;}
//функция записывает текущие экстремумыvoid WriteBar(int eNumber, string eSymbol, ENUM_TIMEFRAMES eFrame, datetime eTime)
{
int eShift=iBarShift(eSymbol,eFrame,eTime);
double eHigh=iHigh(eSymbol,eFrame,eShift);
double eLow=iLow(eSymbol,eFrame,eShift);
//если элементов ещё нет или период сменилсяif(index<0 || eNumber!=Arr[index].number)
{
ArrayResize(Arr,++index+1);
Arr[index].number=eNumber;
Arr[index].high=eHigh;
Arr[index].low=eLow;
Arr[index].time_high=eTime;
Arr[index].time_low=eTime;
}
//если произошло обновление текущего максимумаif(eHigh-Arr[index].high>0)
{
Arr[index].high=eHigh;
Arr[index].time_high=eTime;
}
//если произошло обновление текущего минимумаif(Arr[index].low-eLow>0)
{
Arr[index].low=eLow;
Arr[index].time_low=eTime;
}
//если произошло обновление предыдущего максимумаif(eHigh-max>0)
{
for(int i=index+1; i>=0; i--)
{
if(Arr[index].high-eHigh>0)
{
max=Arr[index].high;
time_max=Arr[index].time_high;
break;
}
}
}
//если произошло обновление предыдущего минимумаif(min-eLow>0)
{
for(int i=index+1; i>=0; i--)
{
if(eLow-Arr[index].low>0)
{
min=Arr[index].low;
time_min=Arr[index].time_low;
break;
}
}
}
}
} day, month, year;
intOnInit()
{
symbol=Symbol();
frame=(ENUM_TIMEFRAMES)Period();
return(INIT_SUCCEEDED);
}
voidOnTick()
{
//текущее время закрытого бара
time=iTime(symbol,frame,1);
MqlDateTime date;
TimeToStruct(time,date);
//делаем записи каждого периода
day.WriteBar(date.day,symbol,frame,time);
month.WriteBar(date.mon,symbol,frame,time);
year.WriteBar(date.year,symbol,frame,time);
//теперь имеем значения Comment(TimeToString(day.time_max)+" : "+DoubleToString(day.max)+" : "+DoubleToString(day.Arr[day.index].high)+"\n"+TimeToString(day.time_min)+" : "+DoubleToString(day.Arr[day.index].low)+" : "+DoubleToString(day.min));
}
So sieht es aus
1) Low_D1-Pegel des Vortages
2) Min_D nächstgelegenes Tagestief in der Geschichte
//+------------------------------------------------------------------+//| Test_Level.mq4 |//| Copyright 2020, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2020, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"#property strictdouble Bar_data_D1 [][6]; // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров D1double Low_D1_Level; // Возвращает значение минимальной цены бара D1double Min_D_Level ; // ближайшей минимальный D уровеньdatetime Time_Day;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
Level();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
On_Timer();
}
//+------------------------------------------------------------------+//+------------------------------------------------------------------+//| Функция Level //+------------------------------------------------------------------+void Level()
{
ArrayCopyRates(Bar_data_D1,_Symbol,PERIOD_D1); // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров
Low_D1_Level = iLow (_Symbol,PERIOD_D1,1); // Возвращает значение минимальной цены бара D1//--- Min_D_Leve //for(int i = 1; i<ArrayRange(Bar_data_D1,0) ;i++)for(int i = 1; ;i++)
{
Print(" i = ",i," Bar_data_D1 [i][2] = ",Bar_data_D1 [i][2]);
if(Bar_data_D1 [i][2]>=0)
{
if( Bar_data_D1 [i][2] < Low_D1_Level)
{
Min_D_Level = Bar_data_D1 [i][2];break;
}
}
}
//+-------------------------Low_D1_Level----------------------------+ if(ObjectFind("Low_D1")!=Low_D1_Level)
{
ObjectDelete("Low_D1");
if(ObjectFind("Low_D1")!=0)
{
ObjectCreate("Low_D1",OBJ_HLINE, 0, Time[0],Low_D1_Level);
ObjectSet("Low_D1", OBJPROP_COLOR, clrMaroon);
ObjectSet("Low_D1", OBJPROP_WIDTH, 1);
}
}
if(ObjectFind("Low_D1_label")!=Low_D1_Level)
{
ObjectDelete("Low_D1_label");
if(ObjectFind("Low_D1_label") != 0)
{
ObjectCreate("Low_D1_label", OBJ_TEXT, 0, Time[13], Low_D1_Level);
ObjectSetText("Low_D1_label", "Low_D1: " + DoubleToStr(Low_D1_Level,_Digits), 8,"Verdana", Brown);
}
}
//+-------------------------Min_D_Level----------------------------+ if(ObjectFind("Min_D")!= Min_D_Level)
{
ObjectDelete("Min_D");
if(ObjectFind("Min_D")!=0)
{
ObjectCreate("Min_D",OBJ_HLINE, 0, Time[0],Min_D_Level);
ObjectSet("Min_D", OBJPROP_COLOR, clrMaroon);
ObjectSet("Min_D", OBJPROP_WIDTH, 1);
}
}
if(ObjectFind("Min_D_label")!=Min_D_Level)
{
ObjectDelete("Min_D_label");
if(ObjectFind("Min_D_label") != 0)
{
ObjectCreate("Min_D_label", OBJ_TEXT, 0, Time[30], Min_D_Level);
ObjectSetText("Min_D_label", "Min_D: " + DoubleToStr(Min_D_Level,_Digits), 8,"Verdana", Brown);
}
}
}
//+------------------------------------------------------------------+//| функция удаление всех объектов созданных советником//+------------------------------------------------------------------+void DestroyObject()
{
int tot=ObjectsTotal();
for( int i=tot; i>=0; i--)
{
if(ObjectName(i)=="Low_MN1"){ObjectDelete(0,"Low_MN1");Print("<< Объект Low_MN удалён >>");}
if(ObjectName(i)=="Low_MN1_label"){ObjectDelete(0,"Low_MN1_label");Print("<< Объект Low_MN1_label удалён >>");}
if(ObjectName(i)=="Min_D"){ObjectDelete(0,"Min_D");Print("<< Объект Min_D удалён >>");}
if(ObjectName(i)=="Min_D_label"){ObjectDelete(0,"Min_D_label");Print("<< Объект Min_D_label удалён >>");}
}
}
//+-------------------------------------------------------------------------+ // функция Timer //+-------------------------------------------------------------------------+void On_Timer()
{
if(Day()!= Time_Day)
{
Level();
Time_Day = Day();
}
}
Der Algorithmus zeichnet und zählt nicht immer wie vorgesehen, sondern wie geschrieben. Das Schreiben in schriftlicher Form ist in der Regel schwierig.
In der Abbildung haben Sie die Minima gezeigt, und in der Bedingung haben Sie den Mindestpreis des täglichen Bar Low. Und der Algorithmus hat ihn in der Trendzone gefunden, und er ist nicht das Minimum zwischen 2 benachbarten Balken.
Die erste Nuance ist, dass der Algorithmus bisher nicht vom Beginn der Geschichte des Testers an zählt, sondern von Anfang an. Daher erscheint das Datum 1970.01.01, das Null ist.
Damit sie von Beginn der Geschichte an zählt, müssen Sie eine Schleife in OnTick einfügen. Etwa so:
datetime time=0, current;
voidOnTick()
{
//текущее время закрытого бара
current=iTime(symbol,frame,1);
do
{
MqlDateTime date;
TimeToStruct(time,date);
//делаем записи каждого периода
day.WriteBar(date.day,symbol,frame,time);
month.WriteBar(date.mon,symbol,frame,time);
year.WriteBar(date.year,symbol,frame,time);
if(time<current) {time=iTime(symbol,frame,(iBarShift(symbol,frame,time)-1));} elsebreak;
}
while(time<=current);
//теперь имеем значения Comment(TimeToString(day.time_max)+" : "+DoubleToString(day.max)+" : "+DoubleToString(day.Arr[day.index].high)+"\n"+TimeToString(day.time_min)+" : "+DoubleToString(day.Arr[day.index].low)+" : "+DoubleToString(day.min));
}
Und fügen Sie in der Funktion des Balkendatensatzes eine Prüfung auf das Datum Null hinzu:
Ich fühle mich wie ein Erstklässler, obwohl ich 42 bin.
:) das kommt alles mit der Erfahrung, ich verstehe auch vieles nicht und lerne nach und nach dazu. Es soll keine Struktur sein, sondern eine Klasse. Wir sind fast auf dem Niveau von OOP. In dem ich immer noch schwebe.
In Bezug auf ArrayCopyRates, Alexey richtig gesagt. Das steht in der Hilfe:
Копирует в двумерный массив вида double RateInfo[][6] данные баров указанного графика и возвращает количество скопированных баров.
Sie müssen es also schreiben:
int total=ArrayCopyRates(Bar_data_D1,_Symbol,PERIOD_D1); // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров
Low_D1_Level = iLow (_Symbol,PERIOD_D1,1); // Возвращает значение минимальной цены бара D1for(int i = 1; i<total ;i++)
{
Ich sitze hier schon eine Weile:
Wir sollten versuchen, unnötige Zyklen zu vermeiden. Wir haben eine Flut von Zitaten, und Sie müssen sofort die richtigen Einträge machen, damit Sie nicht in der Geschichte wühlen und Computerressourcen verschwenden müssen.Ich fühle mich wie ein Erstklässler, obwohl ich 42 bin.
Ich fühle mich wie ein Erstklässler, obwohl ich 42 bin.
Das ist eine gute Sache. Es bedeutet, dass alles vor mir liegt.
Das ist gut. Alles liegt also noch vor uns.
Das Wichtigste ist das Ergebnis!!!
3.47 Ich gehe ins Bett.
Ich werde das alles morgen verdauen, und wenn ich noch Fragen habe, werde ich es Sie wissen lassen!
Vielen Dank an alle!
Omsk?
Sie sitzen eine Zeit lang herum:
Wir sollten versuchen, unnötige Schleifen zu vermeiden. Wir haben Angebote, die in Strömen eingehen, und müssen die richtigen Einträge sofort vornehmen, damit wir nicht in der Historie wühlen und Computerressourcen verschwenden müssen.Ich habe Ihren Code ausgeführt.
Ist hier etwas nicht in Ordnung?
So sieht es aus
1) Low_D1-Pegel des Vortages
2) Min_D nächstgelegenes Tagestief in der Geschichte
Omsk?
Ja
Ja
bei +3 irgendwie nicht viele Städte)
Der Algorithmus zeichnet und zählt nicht immer wie vorgesehen, sondern wie geschrieben. Das Schreiben in schriftlicher Form ist in der Regel schwierig.
In der Abbildung haben Sie die Minima gezeigt, und in der Bedingung haben Sie den Mindestpreis des täglichen Bar Low. Und der Algorithmus hat ihn in der Trendzone gefunden, und er ist nicht das Minimum zwischen 2 benachbarten Balken.
Ich habe Ihren Code ausgeführt.
Ist hier etwas nicht in Ordnung?
Damit sie von Beginn der Geschichte an zählt, müssen Sie eine Schleife in OnTick einfügen. Etwa so:
Und fügen Sie in der Funktion des Balkendatensatzes eine Prüfung auf das Datum Null hinzu:
Und zweitens, in day.Arr[day.index].high ist der aktuelle Tag. Wenn Sie das Gestern wollen, finden Sie es im vorherigen Element:
Ich denke, die Logik sollte jetzt stimmen. Ich habe es nicht genau überprüft, aber es scheint korrekt zu sein.
Ich fühle mich wie ein Erstklässler, obwohl ich 42 bin.
In Bezug auf ArrayCopyRates, Alexey richtig gesagt. Das steht in der Hilfe:
Копирует в двумерный массив вида double RateInfo[][6] данные баров указанного графика и возвращает количество скопированных баров.
Sie müssen es also schreiben:
Aber das ist kein wirtschaftlicher Code.