Sometimes, you would get an OrderSend Error 3 message in your experts log in MetaTrader 4. This can be a rather frustrating error because it prevents the order from executing (and the position from opening). If you are an MQL4 coder, you should learn how to fix it because it signifies that there is an error in the logic of your expert advisor. If you are just a Forex trader, then there are some simple steps that you can follow to fix this error if you have an .mq4 file of the EA. Here you will find out why OrderSend Error 3 occurs and how to fix it in MetaTrader 4.
The OrderSend Error 3 is called ERR_INVALID_TRADE_PARAMETERS
(invalid trade parameters) internally in MT4 platform.
Why does OrderSend Error 3 appear?
ERR_INVALID_TRADE_PARAMETERS
means that some of the parameters passed to OrderSend() function aren’t correct. By the way, this error may also appear with the OrderModify() function (appears as OrderModify Error 3). The most popular cases are the following:
- Incorrect operation type passed to the
OrderSend()
function. Remember that there are only 6 operation types available in MetaTrader 4. - Negative slippage passed to the
OrderSend()
function. Remember that slippage can only be 0 or greater. - Incorrect order ticket passed to the
OrderModify()
function. Make sure the order with the given ticket exists in the system before calling this function.
How to fix OrderSend Error 3?
So, what can you do when you spot this OrderSend Error 3? First, check that the operation passed to the function is one of the following:
OP_BUY
(Open long position).OP_SELL
(Open short position).OP_BUYLIMIT
(Buy limit order).OP_SELLLIMIT
(Sell limit order).OP_BUYSTOP
(Buy stop order).OP_SELLSTOP
(Sell stop order).
Then make sure that the slippage passed to the OrderSend()
function isn’t negative. Slippage is often given as an input parameter, so you just enter some positive value there. Finally, if the error appears as OrderModify Error 3, make sure that the EA deals with the correct ticket (perhaps, it is trying to use 0 or -1?). Just add this condition in front of the OrderModify()
function call in the .mq4 file of the expert advisor:
where ticket
is your variable for ticket used in the function. It will cut all attempts to pass the most popular incorrect ticket values.
If you have any thoughts, comments, or questions regarding MT4 Error 3 and the ways to get rid of it, feel free to join a discussion on our Forex forum.
Группа функций, предназначенных для управления торговой деятельностью.
Торговые функции OrderSend(), OrderClose(), OrderCloseBy(), OrderDelete() и OrderModify() не могут быть вызваны из пользовательских индикаторов.
Торговые функции могут использоваться в экспертах и скриптах. Торговые функции могут быть вызваны только в том случае, если в свойствах соответствующего эксперта или скрипта включена галочка «Разрешить советнику торговать».
Для проведения торговых операций из экспертов и скриптов предусмотрен всего один поток, который запускается в программном торговом контексте (контекст автоматической торговли из экспертов и скриптов). Поэтому, если этот контекст занят торговой операцией какого-либо эксперта, то другой эксперт или скрипт не может в этот момент вызывать торговые функции из-за ошибки 146 (ERR_TRADE_CONTEXT_BUSY). Для определения возможности выполнять торговые операции необходимо использовать функцию IsTradeAllowed(). Для чёткого разделения доступа к торговому контексту можно использовать семафор на основе глобальной переменной, значение которой необходимо менять при помощи функции GlobalVariableSetOnCondition().
OrderClose
bool OrderClose(int ticket, double lots, double price, int slippage, color Color=CLR_NONE)
Закрытие позиции. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().
Параметры:
ticket — Уникальный порядковый номер ордера.
lots — Количество лотов для закрытия.
price — Цена закрытия.
slippage — Значение максимального проскальзывания в пунктах.
Color — Цвет стрелки закрытия на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображается.
Пример:
if(iRSI(NULL,0,14,PRICE_CLOSE,0)>75) { OrderClose(order_id,1,Ask,3,Red); return(0); }
OrderCloseBy
bool OrderCloseBy(int ticket, int opposite, color Color=CLR_NONE)
Закрытие одной открытой позиции другой позицией, открытой по тому же самому инструменту, но в противоположном направлении. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().
Параметры:
ticket — Уникальный порядковый номер закрываемого ордера.
opposite — Уникальный порядковый номер противоположного ордера.
Color — Цвет стрелки закрытия на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображается.
Пример:
if(iRSI(NULL,0,14,PRICE_CLOSE,0)>75) { OrderCloseBy(order_id,opposite_id); return(0); }
OrderClosePrice
double OrderClosePrice()
Возвращает цену закрытия выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); if(ctm>0) Print("Open time for the order 10 ", ctm); ctm=OrderCloseTime(); if(ctm>0) Print("Close time for the order 10 ", ctm); } else Print("OrderSelect failed error code is",GetLastError());
OrderCloseTime
datetime OrderCloseTime()
Возвращает время закрытия для выбранного ордера. Только закрытые ордера имеют время закрытия, не равное 0. Открытые или отложенные ордера имеют время закрытия, равное 0.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); int ticket=OrderTicket(); if(ctm>0) Print("Время открытия ордера ? ",ticket," ",ctm); ctm=OrderCloseTime(); if(ctm>0) Print("Время закрытия ордера ? ",ticket," ",ctm); } else Print("OrderSelect() вернул ошибку ",GetLastError());
OrderComment
string OrderComment()
Возвращает комментарий для выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
string comment; if(OrderSelect(10,SELECT_BY_TICKET)==false) { Print("OrderSelect() вернул ошибку - ",GetLastError()); return(0); } comment = OrderComment(); // ...
OrderCommission
double OrderCommission()
Возвращает значение рассчитанной комиссии для выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10,SELECT_BY_POS)==true) Print("Commission for the order 10 ",OrderCommission()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderDelete
bool OrderDelete(int ticket, color arrow_color=CLR_NONE)
Удаляет ранее установленный отложенный ордер. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().
Параметры:
ticket — Уникальный порядковый номер ордера.
arrow_color — Цвет стрелки на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображаются.
Пример:
if(Ask > var1) { OrderDelete(order_ticket); return(0); }
OrderExpiration
datetime OrderExpiration()
Возвращает дату истечения для выбранного отложенного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10, SELECT_BY_TICKET)==true) Print("Order expiration for the order #10 is ",OrderExpiration()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderLots
double OrderLots()
Возвращает количество лотов для выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10,SELECT_BY_POS)==true) Print("lots for the order 10 ",OrderLots()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderMagicNumber
int OrderMagicNumber()
Возвращает идентификационное («магическое») число для выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10,SELECT_BY_POS)==true) Print("Magic number for the order 10 ", OrderMagicNumber()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderModify
bool OrderModify(int ticket, double price, double stoploss, double takeprofit, datetime expiration, color arrow_color=CLR_NONE)
Изменяет параметры ранее открытых позиций или отложенных ордеров. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().
Замечания: цену открытия и время истечения можно изменять только у отложенных ордеров.
Если в качестве параметров функции передать неизмененные значения, то в этом случае будет сгенерирована ошибка 1 (ERR_NO_RESULT).
На некоторых торговых серверах может быть установлен запрет на применение срока истечения отложенных ордеров. В этом случае при попытке задать ненулевое значение в параметре expiration будет сгенерирована ошибка 147 (ERR_TRADE_EXPIRATION_DENIED).
Параметры:
ticket — Уникальный порядковый номер ордера.
price — Новая цена открытия отложенного ордера.
stoploss — Новое значение StopLoss.
takeprofit — Новое значение TakeProfit.
expiration — Время истечения отложенного ордера.
arrow_color — Цвет стрелок модификации StopLoss и/или TakeProfit на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелки на графике не отображаются.
Пример:
if(TrailingStop>0) { OrderSelect(12345, SELECT_BY_TICKET); if(Bid-OrderOpenPrice()>Point*TrailingStop) { if(OrderStopLoss()<Bid-Point*TrailingStop) { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue); return(0); } } }
OrderOpenPrice
double OrderOpenPrice()
Возвращает цену открытия для выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10, SELECT_BY_POS)==true) Print("open price for the order 10 ",OrderOpenPrice()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderOpenTime
datetime OrderOpenTime()
Возвращает время открытия выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10, SELECT_BY_POS)==true) Print("open time for the order 10 ", OrderOpenTime()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderPrint
void OrderPrint()
Выводит данные ордера в журнал в виде строки следующего формата:
номер тикета; время открытия; торговая операция; количество лотов; цена открытия; стоп лосс; тейк профит; время закрытия; цена закрытия; комиссия; своп; прибыль; комментарий; магическое число; дата истечения отложенного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10, SELECT_BY_TICKET)==true) OrderPrint(); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderProfit
double OrderProfit()
Возвращает значение чистой прибыли (без учёта свопов и комиссий) для выбранного ордера. Для открытых позиций это — текущая нереализованная прибыль. Для закрытых ордеров — зафиксированная прибыль.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(10, SELECT_BY_POS)==true) Print("Profit for the order 10 ",OrderProfit()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderSelect
bool OrderSelect(int index, int select, int pool=MODE_TRADES)
Функция выбирает ордер для дальнейшей работы с ним. Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().
Параметр pool игнорируется, если ордер выбирается по номеру тикета. Номер тикета является уникальным идентификатором ордера. Чтобы определить, из какого списка выбран ордер, необходимо проанализировать его время закрытия. Если время закрытия ордера равно 0, то ордер является открытым или отложенным и взят из списка открытых позиций терминала. Отличить открытую позицию от отложенного ордера можно по типу ордера. Если время закрытия ордера не равно 0, то ордер является закрытым или удаленным отложенным и был выбран из истории терминала. Отличить закрытый ордер от удаленного отложенного также можно по типу ордера.
Параметры:
index — Позиция ордера или номер ордера в зависимости от второго параметра.
select — Флаг способа выбора. Mожет быть одним из следующих величин:
SELECT_BY_POS — в параметре index передается порядковый номер позиции в списке,
SELECT_BY_TICKET — в параметре index передается номер тикета.
pool — Источник данных для выбора. Используется, когда параметр select равен SELECT_BY_POS. Mожет быть одной из следующих величин:
MODE_TRADES (по умолчанию) — ордер выбирается среди открытых и отложенных ордеров,
MODE_HISTORY — ордер выбирается среди закрытых и удаленных ордеров.
Пример:
if(OrderSelect(12470, SELECT_BY_TICKET)==true) { Print("order #12470 open price is ", OrderOpenPrice()); Print("order #12470 close price is ", OrderClosePrice()); } else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderSend
int OrderSend(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment=NULL, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)
Основная функция, используемая для открытия позиции или установки отложенного ордера.
Возвращает номер тикета, который назначен ордеру торговым сервером или -1 в случае неудачи. Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError().
Замечания: При открытии рыночного ордера (OP_SELL или OP_BUY) в качестве цены открытия могут использоваться только самые последние цены Bid (для продажи) или Ask (для покупки). Если операция проводится по финансовому инструменту, отличному от текущего, то для получения последних котировок по этому инструменту необходимо воспользоваться функцией MarketInfo() с параметром MODE_BID или MODE_ASK. Нельзя использовать расчетную либо ненормализованную цену. Если запрашиваемой цены открытия не было в ценовом потоке либо запрашиваемая цена не нормализована в соответствии с количеством знаков после десятичной точки, то будет сгенерирована ошибка 129 (ERR_INVALID_PRICE). Если запрашиваемая цена открытия сильно устарела, то независимо от значения параметра slippage будет сгенерирована ошибка 138 (ERR_REQUOTE). Если же запрашиваемая цена устарела, но ещё присутствует в ценовом потоке, то позиция открывается по текущей цене и только в том случае, если текущая цена попадает в диапазон price+-slippage.
Цены StopLoss и TakeProfit не могут располагаться слишком близко к рынку. Минимальное расстояние стопов в пунктах можно получить, используя функцию MarketInfo() с параметром MODE_STOPLEVEL. В случае ошибочных, а также ненормализованных стопов генерируется ошибка 130 (ERR_INVALID_STOPS).
При установке отложенного ордера цена открытия не может быть слишком близкой к рынку. Минимальное расстояние отложенной цены от текущей рыночной цены в пунктах также можно получить, используя функцию MarketInfo() с параметром MODE_STOPLEVEL. В случае неправильной цены открытия отложенного ордера будет сгенерирована ошибка 130 (ERR_INVALID_STOPS).
На некоторых торговых серверах может быть установлен запрет на применение срока истечения отложенных ордеров. В этом случае при попытке задать ненулевое значение в параметре expiration будет сгенерирована ошибка 147 (ERR_TRADE_EXPIRATION_DENIED).
На некоторых торговых серверах может быть установлен лимит на общее количество открытых и отложенных ордеров. При превышении этого лимита новая позиция открыта не будет (отложенный ордер не будет установлен), и торговый сервер вернет ошибку 148 (ERR_TRADE_TOO_MANY_ORDERS).
Параметры:
symbol — Наименование финансового инструмента, с которым проводится торговая операция.
cmd — Торговая операция. Может быть любым из значений торговых операций.
volume — Количество лотов.
price — Цена открытия.
slippage — Максимально допустимое отклонение цены для рыночных ордеров (ордеров на покупку или продажу).
stoploss — Цена закрытия позиции при достижении уровня убыточности (0 в случае отсутствия уровня убыточности).
takeprofit — Цена закрытия позиции при достижении уровня прибыльности (0 в случае отсутствия уровня прибыльности).
comment — Текст комментария ордера. Последняя часть комментария может быть изменена торговым сервером.
magic — Магическое число ордера. Может использоваться как определяемый пользователем идентификатор.
expiration — Срок истечения отложенного ордера.
arrow_color — Цвет открывающей стрелки на графике. Если параметр отсутствует или его значение равно CLR_NONE, то открывающая стрелка не отображается на графике.
Пример:
int ticket; if(iRSI(NULL,0,14,PRICE_CLOSE,0) < 25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green); if(ticket<0) { Print("OrderSend failed with error #", GetLastError()); return(0); } }
OrdersHistoryTotal
int OrdersHistoryTotal()
Возвращает количество закрытых позиций и удаленных ордеров в истории текущего счета, загруженной в клиентском терминале. Размер списка истории зависит от текущих настроек вкладки «История счета» терминала.
Пример:
// retrieving info from trade history int i,accTotal=OrdersHistoryTotal(); for(i=0;i<accTotal;i++) { //---- check selection result if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Ошибка при доступе к исторической базе (", GetLastError(),")"); break; } // работа с ордером ... }
OrderStopLoss
double OrderStopLoss()
Возвращает значение цены закрытия позиции при достижении уровня убыточности (stop loss) для текущего выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(ticket,SELECT_BY_POS)==true) Print("Stop loss value for the order 10 ", OrderStopLoss()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrdersTotal
int OrdersTotal()
Возвращает общее количество открытых и отложенных ордеров.
Пример:
int handle=FileOpen("OrdersReport.csv",FILE_WRITE|FILE_CSV,"t"); if(handle<0) return(0); // запишем заголовок в файл FileWrite(handle,"#","Цена открытия","Время открытия","Символ","Лоты"); int total=OrdersTotal(); // записываем в файл только открытые ордера for(int pos=0;pos<total;pos++) { if(OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)==false) continue; FileWrite(handle,OrderTicket(),OrderOpenPrice(),OrderOpenTime(),OrderSymbol(),OrderLots()); } FileClose(handle);
OrderSwap
double OrderSwap()
Возвращает значение свопа для текущего выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(order_id, SELECT_BY_TICKET)==true) Print("Swap for the order #", order_id, " ",OrderSwap()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderSymbol
string OrderSymbol()
Возвращает наименование финансового инструмента для текущего выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(12, SELECT_BY_POS)==true) Print("symbol of order #", OrderTicket(), " is ", OrderSymbol()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderTakeProfit
double OrderTakeProfit()
Возвращает значение цены закрытия позиции при достижении уровня прибыльности (take profit) для текущего выбранного ордера
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(12, SELECT_BY_POS)==true) Print("Order #",OrderTicket()," profit: ", OrderTakeProfit()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderTicket
int OrderTicket()
Возвращает номер тикета для текущего выбранного ордера.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
if(OrderSelect(12, SELECT_BY_POS)==true) Print("Order #",OrderTicket()," profit: ", OrderTakeProfit()); else Print("OrderSelect() вернул ошибку - ",GetLastError());
OrderType
int OrderType()
Возвращает тип операции текущего выбранного ордера. Mожет быть одной из следующих величин:
OP_BUY — позиция на покупку,
OP_SELL — позиция на продажу,
OP_BUYLIMIT — отложенный ордер на покупку по достижении заданного уровня, текущая цена выше уровня,
OP_BUYSTOP — отложенный ордер на покупку по достижении заданного уровня, текущая цена ниже уровня,
OP_SELLLIMIT — отложенный ордер на продажу по достижении заданного уровня, текущая цена ниже уровня,
OP_SELLSTOP — отложенный ордер на продажу по достижении заданного уровня, текущая цена выше уровня.
Ордер должен быть предварительно выбран с помощью функции OrderSelect().
Пример:
int order_type; if(OrderSelect(12, SELECT_BY_POS)==true) { order_type=OrderType(); // ... } else Print("OrderSelect() вернул ошибку - ",GetLastError());
Посмотрел измененную версию.
Вообще у меня довольно интересная ситуация — прошлая версия сливает на моих котировках при идентичных параметрах, как в отчетах с тестера у Мастера.
Но я в принципе грешу на некачественные котировки.
Это так — отступление лирическое.
Теперь по теме:
Взял прогон с января 2017 по сейчас.
Вижу некоторые огрехи в работе алгоритма.
Например входы 27 января 2017 (сэт прогона в аттаче).
Вход в 13-45 на селл. По идее тут входа быть не должно (по первичному алгоритму), так как макд выше ноля.
Спойлер
Теперь более подробно об алгоритме.
Опять повторюсь , что основной враг этого советника- флет.
Предсказывать на постоянной основе направление движения цены не получится, да и не нужно.
Значит нам надо сосредоточиться на алгоритме переворота и первого входа.
На данный момент алгоритм не совсем гибок и при флете получаем или слив или огромную просадку, а это некомфортно как минимум.)
Текущий алгоритм все еще использует мою прошлую задумку, о входе в импульс максимально близко к его началу, из за этого и были основные проблемы.
Сейчас же получается что переворот становится ровно на оси флета, который формируется индикатором X2 PZ.
При отсутствии направленного движения цены, мы в любом случае получаем первый вход и цена начинает накручивать шаги мартина по границам жестко заданной торговой зоны, образуемой каналом X2PZ и пунктирным каналом АТР.
Если дневная свеча в итоге формируется как мелкий доджик, то получаем накрутку на 7-8 колен. А это уже красная зона — если повезет то закроем, если не повезет то сольем.
На рисунке отмечен не такой катастрофичный торговый коридор, но там ясно видны проблемы ТС.
Спойлер
Попадаем во флет, и начинаем крутить, если следующий день, цена так же не будет смещаться на новые уровни, то будет слив.
Что из этого следует?
Нам нужно каким то образом фильтровать флет, можно конечно добавить фильтрацию индикатором ADX, но там проблема в установке уровня,ниже которого считается что цена не имеет направления движения.
Так же первичный алгоритм, который не дает делать первый вход за пределами пунктирного канала ATR будет мешать эффективной работе алгоритма.
Конечно можно добавить адх в советник и посмотреть что будет, но явно будет уменьшено количество первых входов (активация торгового коридора).
Спойлер
Конечно это все касается именно алгоритма первого входа.
Что же по поводу алгоритма переворота (торгового коридора)?
Можно попробовать «прорядить» точки активации позиций с множителем. Сейчас алгоритм работает так (грубо) — есть первый вход, есть параметры переворота:
Переворотный ордер должен находиться внутри канала АТР.
Остальные ордера открываются при касании «границ» торгового коридора (с учетом алгоритма). Если флет, то имеем довольно печальный пинг понг.
Как же прорядить эти самые шарики «пинг понга»?
Можно пробовать добавить индикатор, который не даст открывать сделки по упрощенному алгоритму.
Например добавить модифицированный CCI.
И активировать переворот только при соответствующих показателях этого индикатора.
1,2,3 шаг открываем как сейчас — ничего не меняем, а вот после активации 3-го шага уже вступает в работу сси.
Для активации бай переворота CCI должен быть выше уровня 90.
Для активации селл переворота CCI должен быть ниже уровня -90.
Если такое введение не нарушит алгоритм переворота, то может стоит рассмотреть?
Я сейчас ищу более менее оптимальные способы растянуть количество переворотов по флету, не дать набрать критическую массу переворотов.
По переворотам получается примерно так (грубо):
Спойлер
1-й шаг
2-й шаг
3-й шаг
самые безопасные
4-й шаг
5-й шаг
самые прибыльные шаги
6-й шаг
7-й шаг
опасный уровень (значительная просадка)
8-й шаг
9-й шаг
критический диапазон, большая просадка и возможен слив при неудачном стечении обстоятельств
Пока мысли такие чтобы снизить вероятность появления 8-9 шагов.
Для этого надо растянуть во времени шаги с 3-го по 7-й.
Конечно можно ввести еще временнЫе задержки на активацию шагов, но тут пока ничего кроме мыслей нет, надо каким то образом собирать статистику и смотреть в целом, как такие идеи могут повлиять на алгоритм.
Как резюме:
1.Если изменить алгоритм первого входа на тот каким он был изначально (фильтр MACD) выше ниже нуля и сигнальной линии, то мы можем уменьшить количество первых входов которые начинают торговый коридор прямо перед началом флета.
2. Если мы добавим ADX для дополнительной фильтрации, то можем (теоретически) улучшить статистику торгового коридора (но может упасть количество входов).
3. Если мы добавим индикатор CCI (модификация), то вероятно мы сможем уменьшить количество переворотов на длинном флете.
Я еще рассматривал сам MACD, как фильтр переворотов. Можно и его рассмотреть.
Если макд ниже ноля и ниже уровня -0,005 (для usd/jpy) и цена внутри пунктирного канала АТР то переворот активируется.
Спойлер
тут сразу есть проблема усреднения ценового ряда, цена может дать импульс и оказаться за пределами пунктирного канала, для этого должно работать правило
» предела торговой зоны», например если цена выскочила за предел пунктирного канала, то на следующем атр уровне должен быть безусловный переворот.
Это конечно же сместит уровень безубытка и мы можем оказаться в ситуации, когда нам может не хватить импульса цены для фиксации прибыли. Требуется исследование на достаточной истории в тестере. На тестовом сове.
Ну и конечно временнЫе параметры активации, тут надо думать.
Piranha_v.1.2._usdjpy_test_2017.set
CCI_НУФ_v5a.mq4
Изменено 26 марта, 2017 пользователем PiKG