Devemos tentar evitar ciclos desnecessários. Temos uma enchente de citações, e você precisa fazer as entradas corretas na hora, para que não tenha que escavar a história e desperdiçar recursos do computador.
Eu me sinto como um aluno de 1ª série, mesmo tendo 42 anos.
Devemos tentar evitar loops desnecessários. Temos citações que vêm em fluxo e precisamos fazer as entradas certas na hora certa, para não termos que cavar a história e desperdiçar recursos computacionais.
Eu analisei seu código.
Há algo um pouco errado aqui?
#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));
}
Veja como fica
1) Nível baixo_D1 do dia anterior
2) Min_D mais próximo diariamente de um mínimo histórico
//+------------------------------------------------------------------+//| 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();
}
}
O algoritmo nem sempre desenha e conta como pretendido, mas como escrito. Escrever como escrito geralmente é difícil.
Na figura você mostrou os mínimos, e na condição de ter o preço mínimo da barra diária Baixo. E o algoritmo o encontrou na zona de tendência, e não é o mínimo entre 2 barras adjacentes.
A primeira nuance, até agora o algoritmo não conta desde o início da história do testador, mas desde o início. Portanto, a data 1970.01.01.01, que é zero, aparece.
Para que isso conte desde o início da história, é preciso inserir um laço no OnTick. Algo parecido com isto:
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));
}
E na função de registro de barra adicionar um cheque para data zero:
Eu me sinto como um aluno de 1ª série, embora tenha 42 anos.
:) tudo isso vem com experiência, eu também não entendo muitas coisas e estou aprendendo à medida que vou avançando. Não é suposto ser uma estrutura, é suposto ser uma classe. Estamos quase no nível do OOP. No qual eu ainda estou flutuando.
Com relação ao ArrayCopyRates, Alexey disse corretamente. Está escrito na ajuda:
Копирует в двумерный массив вида double RateInfo[][6] данные баров указанного графика и возвращает количество скопированных баров.
Portanto, você tem que escrevê-lo:
int total=ArrayCopyRates(Bar_data_D1,_Symbol,PERIOD_D1); // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров
Low_D1_Level = iLow (_Symbol,PERIOD_D1,1); // Возвращает значение минимальной цены бара D1for(int i = 1; i<total ;i++)
{
Para login e uso do site MQL5.com, você deve ativar o uso de cookies.
Ative esta opção no seu navegador, caso contrário você não poderá fazer login.
Você entrou na conta. A autenticação de dois fatores foi desativada. Configure-a novamente e escaneie um novo código QR ou continue com a autenticação de dois fatores desativada.
Já faz um tempo que estou aqui sentado:
Devemos tentar evitar ciclos desnecessários. Temos uma enchente de citações, e você precisa fazer as entradas corretas na hora, para que não tenha que escavar a história e desperdiçar recursos do computador.Eu me sinto como um aluno de 1ª série, mesmo tendo 42 anos.
Eu me sinto como um aluno de 1ª série, mesmo tendo 42 anos.
Isso é uma coisa boa. Isso significa que tudo está à minha frente.
Isso é bom. Portanto, tudo está à nossa frente.
O mais importante é o resultado!!!
3.47 Vou para a cama.
Eu vou digerir tudo amanhã e se eu tiver alguma pergunta, eu avisarei você!
Muito obrigado a todos!
Omsk?
Ficar sentado por um tempo:
Devemos tentar evitar loops desnecessários. Temos citações que vêm em fluxo e precisamos fazer as entradas certas na hora certa, para não termos que cavar a história e desperdiçar recursos computacionais.Eu analisei seu código.
Há algo um pouco errado aqui?
Veja como fica
1) Nível baixo_D1 do dia anterior
2) Min_D mais próximo diariamente de um mínimo histórico
Omsk?
Sim
Sim
em +3, de alguma forma não muitas cidades)
O algoritmo nem sempre desenha e conta como pretendido, mas como escrito. Escrever como escrito geralmente é difícil.
Na figura você mostrou os mínimos, e na condição de ter o preço mínimo da barra diária Baixo. E o algoritmo o encontrou na zona de tendência, e não é o mínimo entre 2 barras adjacentes.
Eu analisei seu código.
Há algo de um pouco errado aqui?
Para que isso conte desde o início da história, é preciso inserir um laço no OnTick. Algo parecido com isto:
E na função de registro de barra adicionar um cheque para data zero:
E segundo, no dia.Arr[day.index].high é o dia atual. Se você quiser ontem, está no elemento anterior:
Acho que a lógica deve estar correta agora. Não foi muito difícil verificá-lo, mas parece estar correto.
Eu me sinto como um aluno de 1ª série, embora tenha 42 anos.
Com relação ao ArrayCopyRates, Alexey disse corretamente. Está escrito na ajuda:
Копирует в двумерный массив вида double RateInfo[][6] данные баров указанного графика и возвращает количество скопированных баров.
Portanto, você tem que escrevê-lo:
Mas isso não é um código econômico.