Всем добрый день. Помогите пожалуйста разобраться с МТ5. Робот на реальном счете торгует как положено и без нареканий. Но когда начинаю прогонять через тестер стратегий то ничего не показывает. Что делать? ПОМОГИТЕ.
// globals
int g_hMA1Handle = 0;
int g_hMA2Handle = 0;
double g_fMA1[];
double g_fMA2[];
CTrade g_oTrade;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(i_nMA1Period == 0 || i_nMA2Period == 0 || i_nMA1Period > i_nMA2Period)
{
string sErr = «Периоды обеих МА должны быть больше нуля, и период МА1 должен быть меньше периода МА2. \nОткорректируйте введённые значения.»;
MessageBox(sErr, «Некорректные параметры!»);
Print(sErr);
return(INIT_FAILED);
}
gagarin, прошу прощение, я наверное должен писать более подробно.
Не конкретно после Print, а каждая строчка должна заканчиваться точкой с запятой. Как это сделано везде.
Уже не первый раз встречаю такое от пользователей и писателей на мт5, что как ни патч, то некоторые роботы ломаются (в том числе и на реал.торговле). И так постоянно. Специально вносятся такие правки, чтобы усложнить людям жизнь, чтобы побольше и почаще хомячков загонять в их фирменный маркет.
блент, дык в коде же все и написано — если один из входных параметров будет 0, то инициализации не получится. Просто надо крутить оптимизатор без нулей в МА-периодах, и период первой должен быть меньше второй.
Или, вероятно, диапазоны значений оптимизации указаны так, что период первой часто\всегда больше второй.
Но раз вы не программист, вы сами точно не справитесь.
Наверняка там какие то индикаторы пытаются открыться и не могут
enum ENUM_SIGNAL
{
SHORT = -1,
NONE = 0,
LONG = 1
};
// inputs
sinput string i_sMA1Settings = "=== Параметры МА1 ==="; //
input uint i_nMA1Period = 10; // Период
input ENUM_MA_METHOD i_eMA1Method = MODE_SMA; // Тип
input ENUM_APPLIED_PRICE i_eMA1Price = PRICE_CLOSE; // Цена для расчёта
sinput string i_sSeparator1 = ""; //
sinput string i_sMA2Settings = "=== Параметры МА2 ==="; //
input uint i_nMA2Period = 20; // Период
input ENUM_MA_METHOD i_eMA2Method = MODE_SMA; // Тип
input ENUM_APPLIED_PRICE i_eMA2Price = PRICE_CLOSE; // Цена для расчёта
sinput string i_sSeparator2 = ""; //
sinput string i_sEASettings = "=== Параметры советника ==="; //
input double i_fLot = 0.1; // Лот
input int i_nMagic = 3245; // Идентификатор (Magic Number)
// globals
int g_hMA1Handle = 0;
int g_hMA2Handle = 0;
double g_fMA1[];
double g_fMA2[];
CTrade g_oTrade;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(i_nMA1Period == 0 || i_nMA2Period == 0 || i_nMA1Period > i_nMA2Period)
{
string sErr = «Периоды обеих МА должны быть больше нуля, и период МА1 должен быть меньше периода МА2. \nОткорректируйте введённые значения.»;
MessageBox(sErr, «Некорректные параметры!»);
Print(sErr);
return(INIT_FAILED);
}
g_hMA1Handle = iMA(Symbol(), Period(), i_nMA1Period, 0, i_eMA1Method, i_eMA1Price);
g_hMA2Handle = iMA(Symbol(), Period(), i_nMA2Period, 0, i_eMA2Method, i_eMA2Price);
ArrayResize(g_fMA1, 3);
ArrayResize(g_fMA2, 3);
ZeroMemory(g_fMA1);
ZeroMemory(g_fMA2);
ArraySetAsSeries(g_fMA1, true);
ArraySetAsSeries(g_fMA2, true);
g_oTrade.SetDeviationInPoints(200);
g_oTrade.SetExpertMagicNumber(i_nMagic);
g_oTrade.SetTypeFilling(OrderTypeFilling(Symbol()));
NewBar(0, true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
datetime dtTime[1];
CopyTime(Symbol(), Period(), 0, 1, dtTime);
// совершаем сделки только на опен бара
if(NewBar(dtTime[0]) == true)
{
// копируем значения мувингов
CopyBuffer(g_hMA1Handle, 0, 0, 3, g_fMA1);
CopyBuffer(g_hMA2Handle, 0, 0, 3, g_fMA2);
// вычисляем сигнал (пересечение мувингов)
ENUM_SIGNAL eSignal = NONE;
if(g_fMA1[1] > g_fMA2[1] && g_fMA1[2] <= g_fMA2[2])
eSignal = LONG;
else if(g_fMA1[1] < g_fMA2[1] && g_fMA1[2] >= g_fMA2[2])
eSignal = SHORT;
if(eSignal == NONE)
return;
// проверяем, есть ли уже открытая сделка
bool bBuyIsOpen = false;
bool bSellIsOpen = false;
if(PositionSelect(Symbol()) == true)
{
if(HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)) == true)
{
ulong nLastDealTicket = 0;
for(int i = 0; i < HistoryDealsTotal(); i++)
{
ulong nDealTicket = HistoryDealGetTicket(i);
if(HistoryDealGetInteger(nDealTicket, DEAL_MAGIC) == i_nMagic && nDealTicket > nLastDealTicket)
{
if(HistoryDealGetInteger(nDealTicket, DEAL_TYPE) == DEAL_TYPE_BUY)
{
bBuyIsOpen = true;
bSellIsOpen = false;
}
else if(HistoryDealGetInteger(nDealTicket, DEAL_TYPE) == DEAL_TYPE_SELL)
{
bBuyIsOpen = false;
bSellIsOpen = true;
}
else continue;
nLastDealTicket = nDealTicket;
}
}
}
}
// сигнал на покупку, и нет открытой покупки
if(eSignal == LONG && bBuyIsOpen == false)
{
double fLot = i_fLot;
// если открыт шорт — переворачиваем позицию (покупаем удвоенным лотом)
if(bSellIsOpen == true)
fLot *= 2;
MqlTick oTick;
ZeroMemory(oTick);
SymbolInfoTick(Symbol(), oTick);
// покупаем
if(g_oTrade.Buy(fLot, Symbol(), oTick.ask) == true && g_oTrade.ResultOrder() > 0)
{
// дожидаемся результата сделки
WaitForOrderInHistory(g_oTrade.ResultOrder());
}
}
// сигнал на продажу, и нет открытой продажи
if(eSignal == SHORT && bSellIsOpen == false)
{
double fLot = i_fLot;
// если открыт шорт — переворачиваем позицию (покупаем удвоенным лотом)
if(bBuyIsOpen == true)
fLot *= 2;
MqlTick oTick;
ZeroMemory(oTick);
SymbolInfoTick(Symbol(), oTick);
// продаём
if(g_oTrade.Sell(fLot, Symbol(), oTick.bid) == true && g_oTrade.ResultOrder() > 0)
{
// дожидаемся результата сделки
WaitForOrderInHistory(g_oTrade.ResultOrder());
}
}
}
}
//+------------------------------------------------------------------+
bool NewBar(const datetime dtTime, const bool bReset = false)
{
bool bRetVal = false;
static datetime s_dtLastBarTime = 0;
if(bReset == true)
{
s_dtLastBarTime = 0;
return(false);
}
if(dtTime > s_dtLastBarTime && s_dtLastBarTime > 0)
bRetVal = true;
s_dtLastBarTime = dtTime;
return(bRetVal);
}
//+------------------------------------------------------------------+
// разрешённый тип заливки ордеров
ENUM_ORDER_TYPE_FILLING OrderTypeFilling(const string sSymbol)
{
ENUM_ORDER_TYPE_FILLING eRetVal;
int nFillingFlags = (int)SymbolInfoInteger(sSymbol, SYMBOL_FILLING_MODE);
if((nFillingFlags & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK)
eRetVal = ORDER_FILLING_FOK;
else if((nFillingFlags & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC)
eRetVal = ORDER_FILLING_IOC;
else
eRetVal = ORDER_FILLING_RETURN;
return(eRetVal);
}
//+------------------------------------------------------------------+
void WaitForOrderInHistory(ulong nResultOrder)
{
if(nResultOrder > 0)
{
// дождёмся появления ордера nResultOrder в истории
while(!IsStopped())
{
if(HistoryOrderSelect(nResultOrder) == true)
break;
Sleep(10);
}
}
}
//+------------------------------------------------------------------+
После каждой строчки.
Например:
как локализуете ошибку, будем думать.
не такие <<, а такие "
Не конкретно после Print, а каждая строчка должна заканчиваться точкой с запятой. Как это сделано везде.
вот так надо:
Print («какой то текст»);
только ковычки "
Или, вероятно, диапазоны значений оптимизации указаны так, что период первой часто\всегда больше второй.