вот ваш код с Stop Loss и Take Profit (всё работает)
так стоп и тейк не ставятся, если у меня инет пропадет, то робот позиции не сможет закрыть. и стопы с тейками у мня ставятся 50% дневного атр
тейк, и 16% атр стоп. в вашем коде меняла эти значения ничего не изменилось.
вот как у меня реализовано это было, типа стоп и тейк. точнее закрытие по рынку на уровне цены стопа и тейка
//----------------------------ПОКУПКИ-------------------------------------------------// if (!PositionSelect(_Symbol)) //если нет открытой позиции
{
if (TC == TCtime) //если время равно 10:01:00
{
if (cl>op) //если открыти 1ой свечи > закрытия 1ой свечи
{
trader.Buy(Lots); //то вход в лонг
}
}
}
else
{
if (PositionGetInteger(POSITION_TYPE)== POSITION_TYPE_BUY)
{ pointlo = (SymbolInfoDouble(_Symbol,SYMBOL_LAST) - PositionGetDouble(POSITION_PRICE_OPEN)); //когда цена идет вверх
pointhr = (PositionGetDouble(POSITION_PRICE_OPEN) - SymbolInfoDouble(_Symbol,SYMBOL_LAST)); //когда цена идет внизif (pointlo>=TP) // закрытие по стопу и тейку, с расчетом от % атр
{
trader.PositionClose(_Symbol); //закрытие позы
}
if (pointhr>=SL)
{
trader.PositionClose(_Symbol);
}
}
}
//+------------------------------------------------------------------+//| 1ый.mq5 |//| Copyright 2019, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2019, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//---#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CPositionInfo m_position; // trade position object
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object//--- input parametersinputdouble Lots = 1.0;
inputint TPpr = 50;
inputint SLpr = 10;
inputint DDpr=40; // цена прошла 40% запрет входа//---int ATRy; // указатель на индикато атрdouble ATRm[]; // массив для атр//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---if(!m_symbol.Name(Symbol())) // sets symbol namereturn(INIT_FAILED);
RefreshRates();
//---
ATRy=iATR(m_symbol.Name(),PERIOD_D1,5);
if(ATRy==INVALID_HANDLE)
{
Print("не удалось создать описатель индикатора XLO");
return(INIT_FAILED);
}
ArraySetAsSeries(ATRm,true);
//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
IndicatorRelease(ATRy);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
MqlDateTime STimeCurrent; // структура для хранения времениTimeToStruct(TimeCurrent(),STimeCurrent);
//---MqlRates rates[];
ArraySetAsSeries(rates,true);
if(CopyRates(m_symbol.Name(),Period(),0,3,rates)!=3)
return;
if(CopyBuffer(ATRy,0,0,3,ATRm)!=3)
return;
double cl = rates[1].close;
double op = rates[1].open;
double high = rates[0].high;
double low = rates[0].low;
double ATR = ATRm[1]; // значение дневного АТР вчерашнего дняdouble TP = ATR/100*TPpr; //double SL = ATR/100*SLpr; // значение от атр 50% double DD = ATR/100*DDpr; //int count=0;
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positionsif(m_position.SelectByIndex(i)) // selects the position by index for further access to its propertiesif(m_position.Symbol()==m_symbol.Name())
{
count++;
double PR=m_position.PriceOpen();
if(m_position.PositionType()==POSITION_TYPE_BUY)
{
}
else
{
}
}
//---if(count==0) //если нет открытой позиции
{
if(STimeCurrent.hour==10 && STimeCurrent.min==01) //если время равно 10:01:00
{
if(!RefreshRates()) // получаем текущие ценыreturn;
//--- ПОКУПКИ if(cl>op) //если открыти 1ой свечи > закрытия 1ой свечи
{
double SL_BUY=m_symbol.Ask()-SL; // цена для стопа лонгаdouble TP_BUY=m_symbol.Ask()+TP; // цена для тейка лонга
m_trade.Buy(Lots,m_symbol.Name(),m_symbol.Ask(),
m_symbol.NormalizePrice(SL_BUY),
m_symbol.NormalizePrice(TP_BUY)); // то вход в лонг
}
//--- ПРОДАЖИelseif(cl<op) //если закрытие 1ой свечи < открытия 1ой свечи
{
double SL_SELL=m_symbol.Bid()+SL; // цена для стопа шортаdouble TP_SELL=m_symbol.Bid()-TP; // цена для тейка шорта
m_trade.Sell(Lots,m_symbol.Name(),m_symbol.Bid(),
m_symbol.NormalizePrice(SL_SELL),
m_symbol.NormalizePrice(TP_SELL)); // то вход в шорт
}
}
}
}
//+------------------------------------------------------------------+//| Refreshes the symbol quotes data |//+------------------------------------------------------------------+bool RefreshRates(void)
{
//--- refresh ratesif(!m_symbol.RefreshRates())
{
Print("RefreshRates error");
return(false);
}
//--- protection against the return value of "zero"if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
return(false);
//---return(true);
}
//+------------------------------------------------------------------+
Чтобы не путаться, сначала рассчитывайте Стоп лосс, а потом Тейк профит (у вас изначально было наоборот и я даже попался на этом - дело в том, что
CTrade отдаёт торговый приказ в формате ***, Стоп лосс, Тейк профит).
Пришлось добавить класс CSymbolInfo - для получения текущей цены и (главное!) - для нормализации цен подставляемых в Стоп лосс и Тейк
профит.
Чтобы не путаться, сначала рассчитывайте Стоп лосс, а потом Тейк профит (у вас изначально было наоборот и я даже попался на этом - дело в том,
что CTrade отдаёт торговый приказ в формате ***, Стоп лосс, Тейк профит).
Пришлось добавить класс CSymbolInfo - для получения
текущей цены и (главное!) - для нормализации цен подставляемых в Стоп лосс и Тейк профит.
классно, работает. тока мне нужно понять этот весь код. завтра займусь. не против если я у вас спрошу чего не смогу понять сама?
здравствуйте. я не только вопросы написала, но и свое понимание кода. в виде комментариев к каждой строке. так вроде проще и легче будет читать.
//+------------------------------------------------------------------+//| 1ый.mq5 |//| Copyright 2019, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2019, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//---#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CPositionInfo m_position; // trade position object
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object//--- input parametersinputdouble Lots = 1.0;
inputint TPpr = 50;
inputint SLpr = 10;
inputint DDpr=40; // цена прошла 40% запрет входа//---int ATRy; // указатель на индикато атрdouble ATRm[]; // массив для атр//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---if(!m_symbol.Name(Symbol())) // sets symbol name 1. не могу понять этой иницилизации. ЕСЛИ НЕТ СИМВОЛА ТОreturn(INIT_FAILED); //ПРЕКРАЩАЕМ РАБОТУ. так что ли?
RefreshRates(); //иницилизация функции bool RefreshRates(void)
ATRy=iATR(m_symbol.Name(),PERIOD_D1,5); // 2. m_symbol.Name()? ПОЧЕМУ НЕ NULL?if(ATRy==INVALID_HANDLE)
{
Print("не удалось создать описатель индикатора XLO");
return(INIT_FAILED);
}
ArraySetAsSeries(ATRm,true); // МАССИВЫ ТОЖЕ НАДО ИНИЦИЛИЗИРОВАТЬ?//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
IndicatorRelease(ATRy);
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
MqlDateTime STimeCurrent; /* структура для хранения времени. НАКОНЕЦ ТО ПОНЯЛА КАК ЭТО ЕДЯТ)))), ТИПА ИСПОЛЬЗОВАНИЕ
КЛАССА ПОЛУЧАЕТСЯ. STimeCurrent И БЕРЕМ ИЗ СТРУКТУРЫ ЧТО НУЖНО. STimeCurrent.hour ТАК? ТОКА НЕ СОВСЕМ ПОНЯТНО ЗАЧЕМ
НУЖНО КОНВЕРТАЦИЯ TimeToStruct. В МОЕМ ПОНИМАНИИ ИЗ СТРУКТУРЫ МОЖНО ВЫТАЩИТЬ ЧТО ХОЧЕШЬ */TimeToStruct(TimeCurrent(),STimeCurrent); // конвертация текущего времени, и результат вносится в STimeCurrent,//--- MqlRates rates[]; //присваивание название массиву ArraySetAsSeries(rates,true);
if(CopyRates(m_symbol.Name(),Period(),0,3,rates)!=3) // 4. если CopyRates не равен 3 то возврат. почему 3? return; //потому что в массиве 3 элемента. плохо понимаю принцип. return? понимаю что это возврат, но прям //точного понятие нет, что, куда возвращает? if(CopyBuffer(ATRy,0,0,3,ATRm)!=3) // 5. если меньше 3, почему не меньше 0?return;
double cl = rates[1].close;
double op = rates[1].open;
double high = rates[0].high;
double low = rates[0].low;
double ATR = ATRm[1]; // значение дневного АТР вчерашнего дняdouble TP = ATR/100*TPpr; //double SL = ATR/100*SLpr; // значение от атр 50% double DD = ATR/100*DDpr; //int count=0;
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positionsif(m_position.SelectByIndex(i)) // selects the position by index for further access to its propertiesif(m_position.Symbol()==m_symbol.Name()) //если символ позиции равен имени инструмента
{
count++; //то+1, значит есть открытая позицияdouble PR=m_position.PriceOpen(); //PR правниваем цену открытияif(m_position.PositionType()==POSITION_TYPE_BUY) // если позиция бай
{
// а тут чего? у меня тут было закрытие позы по рынку при достижении цены TP, SL. мне для примера?
}
else
{
}
}
//---if(count==0) //если нет открытой позиции
{
if(STimeCurrent.hour==10 && STimeCurrent.min==01) //если время равно 10:01:00
{
if(!RefreshRates()) // получаем текущие цены ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?return;
//--- ПОКУПКИ if(cl>op) //если открыти 1ой свечи > закрытия 1ой свечи
{
double SL_BUY=m_symbol.Ask()-SL; // цена для стопа лонга. ПОЧЕМУ ОТ АСК, А НЕ ОТ ЦЕНЫ ОТКРЫТИЯ ПОЗИЦИИ?double TP_BUY=m_symbol.Ask()+TP; // цена для тейка лонга. НАПРИМЕР TP_BUY=m_position.PriceOpen()+TP
m_trade.Buy(Lots,m_symbol.Name(),m_symbol.Ask(),
m_symbol.NormalizePrice(SL_BUY),
m_symbol.NormalizePrice(TP_BUY)); // то вход в лонг
}
//--- ПРОДАЖИelseif(cl<op) //если закрытие 1ой свечи < открытия 1ой свечи
{
double SL_SELL=m_symbol.Bid()+SL; // цена для стопа шортаdouble TP_SELL=m_symbol.Bid()-TP; // цена для тейка шорта
m_trade.Sell(Lots,m_symbol.Name(),m_symbol.Bid(),
m_symbol.NormalizePrice(SL_SELL), //ТОЛЬКО НЕ ПОНЯЛА КАК ОН ЕЕ НОРМАЛИЗУЕТ
m_symbol.NormalizePrice(TP_SELL)); // то вход в шорт
}
}
}
}
//+------------------------------------------------------------------+//| Refreshes the symbol quotes data |//+------------------------------------------------------------------+bool RefreshRates(void)
{
//--- refresh ratesif(!m_symbol.RefreshRates()) // если нет обновления котировок
{
Print("RefreshRates error"); // то выводим в журнал ошибкуreturn(false); // и возвращаем ложь
}
//--- protection against the return value of "zero"if(m_symbol.Ask()==0 || m_symbol.Bid()==0) //НЕПОНЯТНО ЧТО ТУТ ДЕЛАЕТСЯ. если аск или бид равен 0 return(false); // то возвращаем ложь. если вернет ложь то сова перестанет работать?//---return(true);
}
//+------------------------------------------------------------------+
if(!m_symbol.Name(Symbol())) // sets symbol name 1. не могу понять этой иницилизации. ЕСЛИ НЕТ СИМВОЛА ТОreturn(INIT_FAILED); //ПРЕКРАЩАЕМ РАБОТУ. так что ли?
Не совсем так: если вдруг не прошла инициализация текущим символом - тогда выходим
ArraySetAsSeries(ATRm,true); // МАССИВЫ ТОЖЕ НАДО ИНИЦИЛИЗИРОВАТЬ?
Это не инициализация, а установка флага AS_SERIES динамическому массиву, индексация элементов массива будет производиться как в
таймсериях - в общем после этого в массиве элемент с индексом [0] будет соответствовать самому правому бару на графике.
int count=0;
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positionsif(m_position.SelectByIndex(i)) // selects the position by index for further access to its propertiesif(m_position.Symbol()==m_symbol.Name()) //если символ позиции равен имени инструмента
{
count++; //то+1, значит есть открытая позицияdouble PR=m_position.PriceOpen(); //PR правниваем цену открытияif(m_position.PositionType()==POSITION_TYPE_BUY) // если позиция бай
{
// а тут чего? у меня тут было закрытие позы по рынку при достижении цены TP, SL. мне для примера?
}
else
{
}
}
Это заготовка для правильного обхода списка позиций (ДАЖЕ ЕСЛИ ЕСТЬ ВСЕГО ОДНО ПОЗИЦИЯ) и модификации
if(!RefreshRates()) // получаем текущие цены ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?return;
//--- ПОКУПКИ if(cl>op) //если открыти 1ой свечи > закрытия 1ой свечи
{
double SL_BUY=m_symbol.Ask()-SL; // цена для стопа лонга. ПОЧЕМУ ОТ АСК, А НЕ ОТ ЦЕНЫ ОТКРЫТИЯ ПОЗИЦИИ?double TP_BUY=m_symbol.Ask()+TP; // цена для тейка лонга. НАПРИМЕР TP_BUY=m_position.PriceOpen()+TP
m_trade.Buy(Lots,m_symbol.Name(),m_symbol.Ask(),
m_symbol.NormalizePrice(SL_BUY),
m_symbol.NormalizePrice(TP_BUY)); // то вход в лонг
}
//--- ПРОДАЖИelseif(cl<op) //если закрытие 1ой свечи < открытия 1ой свечи
{
double SL_SELL=m_symbol.Bid()+SL; // цена для стопа шортаdouble TP_SELL=m_symbol.Bid()-TP; // цена для тейка шорта
m_trade.Sell(Lots,m_symbol.Name(),m_symbol.Bid(),
m_symbol.NormalizePrice(SL_SELL), //ТОЛЬКО НЕ ПОНЯЛА КАК ОН ЕЕ НОРМАЛИЗУЕТ
m_symbol.NormalizePrice(TP_SELL)); // то вход в шорт
}
"ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?" - это проверка того, что: удалось ли обновить текущие цены. Если не удалось - то в цикл
открытия позиции не входим
Не совсем так: если вдруг не прошла инициализация текущим символом - тогда выходим
Это не инициализация, а установка флага AS_SERIES динамическому
массиву, индексация элементов массива будет производиться как в таймсериях - в общем после этого в массиве элемент с
индексом [0] будет соответствовать самому правому бару на графике.
Это заготовка для правильного обхода списка позиций (ДАЖЕ ЕСЛИ ЕСТЬ ВСЕГО ОДНО ПОЗИЦИЯ) и модификации
"ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?" - это проверка того, что: удалось ли обновить текущие цены. Если не удалось - то в
цикл открытия позиции не вхоспасибо
спасибо, много понятно стало.
вот еще чего спросить хотела, здесь меняю параметры, в тестере в журнале пишет все равно стоп 10, тейк 50. и считает также стоп и тейк. а при
оптимизации нормально, перебирает их. это нормально? или нет?
вот еще чего спросить хотела, здесь меняю параметры, в тестере в журнале пишет все равно стоп 10, тейк 50. и считает также стоп и тейк. а при
оптимизации нормально, перебирает их. это нормально? или нет?
Если Вы просто изменили входные параметры (input) во файле mq5 и скомпилировала его - эти новые параметры НЕ ИЗМЕНЯТСЯ В ТЕСТЕРЕ. Хотите
изменений - в тестере правый клик и параметры по умолчанию
вот ваш код с Stop Loss и Take Profit (всё работает)
так стоп и тейк не ставятся, если у меня инет пропадет, то робот позиции не сможет закрыть. и стопы с тейками у мня ставятся 50% дневного атр тейк, и 16% атр стоп. в вашем коде меняла эти значения ничего не изменилось.
вот как у меня реализовано это было, типа стоп и тейк. точнее закрытие по рынку на уровне цены стопа и тейка
Это минимум для открытия позиции:
Чтобы не путаться, сначала рассчитывайте Стоп лосс, а потом Тейк профит (у вас изначально было наоборот и я даже попался на этом - дело в том, что CTrade отдаёт торговый приказ в формате ***, Стоп лосс, Тейк профит).
Пришлось добавить класс CSymbolInfo - для получения текущей цены и (главное!) - для нормализации цен подставляемых в Стоп лосс и Тейк профит.
Это минимум для открытия позиции:
Чтобы не путаться, сначала рассчитывайте Стоп лосс, а потом Тейк профит (у вас изначально было наоборот и я даже попался на этом - дело в том, что CTrade отдаёт торговый приказ в формате ***, Стоп лосс, Тейк профит).
Пришлось добавить класс CSymbolInfo - для получения текущей цены и (главное!) - для нормализации цен подставляемых в Стоп лосс и Тейк профит.
классно, работает. тока мне нужно понять этот весь код. завтра займусь. не против если я у вас спрошу чего не смогу понять сама?
классно, работает. тока мне нужно понять этот весь код. завтра займусь. не против если я у вас спрошу чего не смогу понять сама?
Да. Распишу по каждой строчке.
Да. Распишу по каждой строчке
здравствуйте. я не только вопросы написала, но и свое понимание кода. в виде комментариев к каждой строке. так вроде проще и легче будет читать.
здравствуйте. я не только вопросы написала, но и свое понимание кода. в виде комментариев к каждой строке. так вроде проще и легче будет читать.
Не совсем так: если вдруг не прошла инициализация текущим символом - тогда выходим
Это не инициализация, а установка флага AS_SERIES динамическому массиву, индексация элементов массива будет производиться как в таймсериях - в общем после этого в массиве элемент с индексом [0] будет соответствовать самому правому бару на графике.
Это заготовка для правильного обхода списка позиций (ДАЖЕ ЕСЛИ ЕСТЬ ВСЕГО ОДНО ПОЗИЦИЯ) и модификации
"ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?" - это проверка того, что: удалось ли обновить текущие цены. Если не удалось - то в цикл открытия позиции не входим
Не совсем так: если вдруг не прошла инициализация текущим символом - тогда выходим
Это не инициализация, а установка флага AS_SERIES динамическому массиву, индексация элементов массива будет производиться как в таймсериях - в общем после этого в массиве элемент с индексом [0] будет соответствовать самому правому бару на графике.
Это заготовка для правильного обхода списка позиций (ДАЖЕ ЕСЛИ ЕСТЬ ВСЕГО ОДНО ПОЗИЦИЯ) и модификации
"ЕСЛИ ПОЛУЧИЛИ ТЕКУЩИЕ ЦЕНЫ. КСТАТИ ЗАЧЕМ ЭТА ПРОВЕРКА?" - это проверка того, что: удалось ли обновить текущие цены. Если не удалось - то в цикл открытия позиции не вхоспасибо
спасибо, много понятно стало.
вот еще чего спросить хотела, здесь меняю параметры, в тестере в журнале пишет все равно стоп 10, тейк 50. и считает также стоп и тейк. а при оптимизации нормально, перебирает их. это нормально? или нет?
спасибо, много понятно стало.
вот еще чего спросить хотела, здесь меняю параметры, в тестере в журнале пишет все равно стоп 10, тейк 50. и считает также стоп и тейк. а при оптимизации нормально, перебирает их. это нормально? или нет?
Если Вы просто изменили входные параметры (input) во файле mq5 и скомпилировала его - эти новые параметры НЕ ИЗМЕНЯТСЯ В ТЕСТЕРЕ. Хотите изменений - в тестере правый клик и параметры по умолчанию