SuhanovDM94 #: Bonne journée à tous. Pourriez-vous m'indiquer si la fonction Sleep() est exécutée dans le mode de test de l'Expert Advisor (test sur des ticks réels, bien sûr) ?
En cours - le temps du Testeur est modifié d'une quantité appropriée.
Wizard #: Est-il possible de trouver la taille du tick même dans mql5, après lequel une position a été ouverte?
Il s'avère que vous le pouvez. La boucle for est insérée dans une fonction distincte, dans la fonction OnTick() ou à votre guise. Je suis intéressé par l'opinion des autres. Par exemple, j'en ai besoin pour créer un système ultra-précis. Par conséquent, j'écris sans bibliothèques, y compris les fonctions d'ouverture et de fermeture des positions. Qui que ce soit, les bibliothèques mqh ralentissent le travail, par exemple la compilation prend 1,5 fois plus de temps. Il est préférable de tout écrire dans un seul fichier. Le style, OOP ou procédural, n'a pas d'importance. MQL5 ne deviendra jamais un langage du niveau de C++, il est limité. Le point est dans les bibliothèques.
#define EXPERT_MAGIC 261// MagicNumber экспертаinputstring Symbol_T = "XAUUSD"; // глобальная переменная для задаваемого символа
..............
for(int i = PositionsTotal()-1; i >= 0; i--)
{
if(PositionGetTicket(i) > 0 && PositionGetString(POSITION_SYMBOL) == Symbol_T && PositionGetInteger(POSITION_MAGIC) == EXPERT_MAGIC)
{
int attempts = 0; // счетчик попытокbool success = false; // флаг успешного выполнения копирования тиковMqlTick tick_array[]; // массив для приема тиков//--- сделаем 3 попытки получить тикиwhile(attempts < 3)
{
//--- замерим время старта перед получением тиковuint start = GetTickCount();
//--- дата, по которую запрашиваются тики (время открытия позиции)datetime Time_Open = (datetime)PositionGetInteger(POSITION_TIME);
//--- дата, с которой запрашиваются тики (достаточно взять на 30 секунд раньше открытия позиции)datetime Time_Start = (datetime)(Time_Open-30);
//--- запросим тиковую историю с момента Time_Start до момента Time_Openint received = CopyTicksRange(Symbol_T, tick_array, COPY_TICKS_ALL, Time_Start*1000, Time_Open*1000);
if(received != -1)
{
//--- выведем информацию о количестве тиков и затраченном времениPrintFormat("%s: received %d ticks in %d ms", Symbol_T, received, GetTickCount()-start);
//--- если тиковая история синхронизирована, то код ошибки равен нулюif(GetLastError()==0)
{
success = true;
break;
}
elsePrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d", Symbol_T, received, GetTickCount()-start, _LastError);
}
//--- считаем попытки
attempts++;
//--- пауза в 1 секунду в ожидании завершения синхронизации тиковой базыSleep(1000);
}
//--- не удалось получить запрошенные тики от самого начала истории с трех попыток if(!success)
{
PrintFormat("Ошибка! Не удалось получить %d тиков по %s с трех попыток", Symbol_T);
//return; (вставить, если цикл находится внутри функции типа void)
}
//--- узнаем количесто элементов в массивеint ticks = ArraySize(tick_array);
//--- выведем bid последнего тика в массиве перед самым открытием позицииdouble last_bid_before_priceopen = tick_array[ticks-1].bid;
Print("BID последнего тика: ", tick_array[ticks-1].bid);
//--- выведем ask последнего тика в массиве перед самым открытием позицииdouble last_ask_before_priceopen = tick_array[ticks-1].ask;
Print("ASK последнего тика: ", tick_array[ticks-1].ask);
//--- узнаем цену, по которой была открыта позицияdouble Position_PriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
//--- вычислим размер последнего тика, на котором была открыта позиция (для BUY позиции открытие было по цене ASK)double size_last_tick_ASK = NormalizeDouble(fabs(Position_PriceOpen - last_ask_before_priceopen), _Digits);
}
elseif((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{
//--- вычислим размер последнего тика, на котором была открыта позиция (для SELL позиции открытие было по цене BID)double size_last_tick_BID = NormalizeDouble(fabs(last_bid_before_priceopen - Position_PriceOpen), _Digits);
}
}
}
J'en ai marre de ce bug - il y a un indicateur, il y a un expert qui travaille dessus. Je modifie l'indicateur et le recompile. Les modifications de l'indicateur sont clairement visibles sur le graphique - le conseiller expert est exécuté dans le testeur - mais c'est comme s'il n'avait rien changé. Le même résultat.
Si je redémarre le terminal et passe le testeur après cela, il générera un nouveau code.
Qu'est-ce que c'est que ce piratage, je ne comprends pas.
J'ai supprimé l'indicateur ex5. Le testeur continue à fonctionner comme si rien ne s'était passé. Où trouve-t-on le fichier à exécuter ? ? ???
au tick sur la même barre limite = 0 donc la première valeur i = -1 et la condition i>=0 c'est pourquoi il ne va pas dans la boucle.
Merci, j'ai raté celui-là.
Mais maintenant, le tampon indicateur IndBuff[i] fait des siennes, le tableau étant hors de portée. De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initiale i=limite ?
//+------------------------------------------------------------------+//| Simple.mq5 |//| Copyright 2021, MetaQuotes Ltd. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2021, MetaQuotes Ltd."#property link"https://www.mql5.com"#property version"1.00"#property indicator_chart_window#property indicator_buffers1#property indicator_plots1//indicator buffersdouble IndBuff[];
double c = 0;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
SetIndexBuffer(0, IndBuff, INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE); //тип отрисовкиPlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID); //стиль отрисовкиPlotIndexSetInteger(0, PLOT_LINE_COLOR, clrAqua); //цвет отрисовкиPlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1); //толщина отрисовкиPlotIndexSetString(0, PLOT_LABEL,"K"); //меткаPlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); //нулевые значения считать пустымиreturn(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate (constint rates_total,
constint prev_calculated,
constint begin,
constdouble& price[])
{
ArraySetAsSeries(IndBuff, true);
//-------------------------------------------------------------------------//Проверка и расчёт количества просчитываемых баровint limit = rates_total-prev_calculated;
//-------------------------------------------------------------------------//Расчёт индикатораfor(int i=limit; i>=0; i--)
{
c = iClose(_Symbol,PERIOD_CURRENT,i);
IndBuff[i] = c; //на этой строке array out of range
}
return(rates_total);
}
Mais maintenant le tampon indicateur IndBuff[i] fait le cerveau, array out of range. De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initial i=limite ?
//Проверка и расчёт количества просчитываемых баровint limit = rates_total-prev_calculated;
if(limit==1)
limit=2;
//-------------------------------------------------------------------------//Расчёт индикатораfor(int i=limit-1; i>=0; i--)
{
c = iClose(_Symbol,PERIOD_CURRENT,i);
IndBuff[i] = c; //на этой строке array out of range
}
C'est parce que IndBuff n'est pas alloué à rates_total + 1 Et ArrayResize ne lui est pas applicable. Ils ont cassé la pour construire. Maintenant on doit tout faire par des "si" ?
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate (constint rates_total,
constint prev_calculated,
constint begin,
constdouble& price[])
{
ArraySetAsSeries(IndBuff, true);
//-------------------------------------------------------------------------//Проверка и расчёт количества просчитываемых баровint limit = rates_total-prev_calculated;
if(limit > 1)
{
Print(rates_total,": rates_total");
Print(limit,": limit");
Print(ArraySize(IndBuff),": IndBuff");
}
//-------------------------------------------------------------------------//Расчёт индикатораfor(int i=limit; i>=0; i--)
{
c = iClose(_Symbol,PERIOD_CURRENT,i);
IndBuff[i] = c; //array out of range
}
return(rates_total);
}
100686: rates_total
100686: limit
100686: IndBuff
array out of range in 'Simple.mq5' (82,15)
C'est parce que IndBuff n'est pas alloué à rates_total + 1 Et ArrayResize ne lui est pas applicable. Ils ont cassé la pour construire. Devons-nous utiliser des if-arses maintenant ?
Bonne journée à tous. Pourriez-vous m'indiquer si la fonction Sleep() est exécutée dans le mode de test de l'Expert Advisor (test sur des ticks réels, bien sûr) ?
En cours - le temps du Testeur est modifié d'une quantité appropriée.
Exécuté - le temps du Testeur est modifié d'une quantité appropriée.
Merci beaucoup !
Est-il possible de trouver la taille du tick même dans mql5, après lequel une position a été ouverte?
Il s'avère que vous le pouvez. La boucle for est insérée dans une fonction distincte, dans la fonction OnTick() ou à votre guise. Je suis intéressé par l'opinion des autres. Par exemple, j'en ai besoin pour créer un système ultra-précis. Par conséquent, j'écris sans bibliothèques, y compris les fonctions d'ouverture et de fermeture des positions. Qui que ce soit, les bibliothèques mqh ralentissent le travail, par exemple la compilation prend 1,5 fois plus de temps. Il est préférable de tout écrire dans un seul fichier. Le style, OOP ou procédural, n'a pas d'importance. MQL5 ne deviendra jamais un langage du niveau de C++, il est limité. Le point est dans les bibliothèques.
J'en ai marre de ce bug - il y a un indicateur, il y a un expert qui travaille dessus. Je modifie l'indicateur et le recompile. Les modifications de l'indicateur sont clairement visibles sur le graphique - le conseiller expert est exécuté dans le testeur - mais c'est comme s'il n'avait rien changé. Le même résultat.
Si je redémarre le terminal et passe le testeur après cela, il générera un nouveau code.
Qu'est-ce que c'est que ce piratage, je ne comprends pas.
J'ai supprimé l'indicateur ex5. Le testeur continue à fonctionner comme si rien ne s'était passé. Où trouve-t-on le fichier à exécuter ? ? ???
3184
Comportement étrange de l'indicateur.
La boucle for entre dans le corps, non pas à chaque tick, mais une seule fois à chaque nouvelle bougie.
Mais i == 0 et la condition donnée permet i>=0
sur le tick de la même barre limite = 0
donc la première valeur de i = -1 et la condition i>=0
c'est pourquoi il ne va pas dans la boucle.
au tick sur la même barre limite = 0
donc la première valeur i = -1 et la condition i>=0
c'est pourquoi il ne va pas dans la boucle.
Merci, j'ai raté celui-là.
Mais maintenant, le tampon indicateur IndBuff[i] fait des siennes, le tableau étant hors de portée.
De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initiale i=limite ?
Merci, j'ai raté celui-là.
Mais maintenant le tampon indicateur IndBuff[i] fait le cerveau, array out of range.
De quoi a-t-il besoin ? Pourquoi n'alloue-t-il pas à l'initial i=limite ?
Ainsi, à chaque barre, il entre dans une boucle, alors qu'il doit entrer dans une boucle à chaque tick.
Cela fonctionnait comme suit
pour les ticks i>=0,
pour les barres i>0
Maintenant, je ne sais pas comment travailler avec le tampon.
C'est parce que IndBuff n'est pas alloué à rates_total + 1
Et ArrayResize ne lui est pas applicable.
Ils ont cassé la pour construire. Maintenant on doit tout faire par des "si" ?
C'est parce que IndBuff n'est pas alloué à rates_total + 1
Et ArrayResize ne lui est pas applicable.
Ils ont cassé la pour construire. Devons-nous utiliser des if-arses maintenant ?
for(int i=limit - 1;....
au moins...