Новый шаблон советника. Отличается от оптимизированного варианта, опубликованного как Шаблон советникав Code Base, блоком вывода информации об ордерах из Истории в файл .../tester/files/Имя_файла.csv.
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подгобнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
rotstern:
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Были такие мысли, постараюсь в ближайшие пару месяцев (не могу строго обещать). На данный момент пока есть другие нереализованные статьи, надо с ними сначала закончить.
Немного изменен шаблон. Вставлены три новые функции, которые могут быть полезны при необходимости учитывать результаты последних закрытых сделок:
//+------------------------------------------------------------------+//| результат последнего закрытого ордера в валюте депозита |//+------------------------------------------------------------------+doubleLastProfit(double & lots){doubleres = 0;
lots = 0;
inttickets = OrdersHistoryTotal();
//----if(tickets > 0){if(OrderSelect(tickets-1,SELECT_BY_POS,MODE_HISTORY)){res = OrderProfit();
lots = OrderLots();
}}//----return(res);
}//+------------------------------------------------------------------+//| комментарий в тикете последнего закрытого ордера |//+------------------------------------------------------------------+stringLastOrderComment(){stringres = "";
intpos = OrdersHistoryTotal();
//----if(pos > 0){if(OrderSelect(pos-1,SELECT_BY_POS, MODE_HISTORY))res = OrderComment();
}//----return(res);
}//+------------------------------------------------------------------+//| прибыль последних N закрытых ордеров |//+------------------------------------------------------------------+doubleSummLastOrder(intN){doubleres = 0;
intcounter =0,pos = OrdersHistoryTotal()-1;
//----for(inti = pos ; i > 0;i--){if(OrderSelect(pos-1,SELECT_BY_TICKET)){res += OrderProfit();
counter++;
if(counter >=N)break;
}}//----return(res);
}
В связи с этим, блоки по вычислению параметров для новых ордеров перемещены за блок закрытия рыночных и удаления отложенных ордеров. Теперь структура функции start() выглядит таким образом (нумерация блоков намеренно оне была изменена, чтобы было видно что и куда переехало):
//+------------------------------------------------------------------+//| expert start function |//+------------------------------------------------------------------+intstart(){// всегда обнуляем размер массива перед первым использованиемInitCounters();
// получим массивы наших ордеровPrepareTickets(Tickets,CommentsTicket,ExpertMagicNumber);
//----/**
1. Trade Signals . Получение торговых сигналов
a) Каждый тик (TradeSignalEveryTick=true)
б) Каждый бар заданного периода (TradeSignalBarPeriod=...)
OP_BUY - в покупку
OP_SELL - в продажу
OP_BALANCE - нет сигнала
*/inttrSignal=getTradeSignal(TradeDay,ReversDay,
TradeSignalEveryTick,TradeSignalBarPeriod);
/**
3.
а) Модификация каждого открытого ордера на каждый тик (SL и TP)
(ModifyMarketOrderEveryTick = true)
б) Модификация каждого отложенного ордера на каждый тик (OpenPrice, SL и TP)
(ModifyPendingEveryTick = true)
в) Модификация каждого открытого ордера на каждом новом баре выбранного периода (SL и TP)
(ModifyMarketBarPeriod = ...)
г) Модификация каждого отложенного ордера на каждом новом баре выбранного периода (OpenPrice, SL и TP)
(ModifyPendingBarPeriod = ...)
*/if(SL_TP_Counter>0)ModifyMarkets(ReversTradeSignal,ModifyMarketOrderEveryTick,ModifyMarketBarPeriod,newSL_and_TP);
if(SL_TP_Counter>0)ModifyPendings(ReversTradeSignal,ModifyPendingEveryTick,ModifyPendingBarPeriod,newSL_and_TP);
/**
4.
а) Закрыть открытый ордер по времени
б) Закрыть открытый ордер по сигналу
*/// тикеты ордеров, которые нужно закрытьintticketsToClose[100][2];
doublelotsToClose[100];
// приготовим массив тикетов для закрытияif(trSignal!=OP_BALANCE)PrepareTicketsToClose(trSignal,ReversTradeSignal,ticketsToClose,lotsToClose,Tickets);
// закроем указанные ордераif(OrdersToCloseCounter>0)CloseMarketOrders(ticketsToClose,lotsToClose);
/**
5.
а) Удалить отложенный ордер по времени
б) Удалить отложенный ордер по условию
*/// тикеты ордеров, которые нужно удалитьintticketsToDelete[100];
// приготовим массив тикетов для удаленияif(trSignal!=OP_BALANCE)PrepareTicketsToDelete(trSignal,ReversTradeSignal,ticketsToDelete,Tickets);
// удалим указанные ордераif(OrdersToDeleteCounter>0)DeletePendingOrders(ticketsToDelete);
/**
2.
а) Вычислить SL и TP для каждого открытого ордера
б) Вычислить OpenPrice, SL, TP, и Lots для нового ордера
в) Вычислить OpenPrice, SL и TP для каждого отложенного ордера
*/if(OurTicketsCounter>0)CalculateSL_and_TP(ReversTradeSignal,Tickets,newSL_and_TP);
doublemarketLots,marketSL,marketTP;
intmarketType, pendingType;
stringmarketComment, pendingComment;
doublependingOpenPrice, pendingLots, pendingSL, pendingTP;
CalculateNewMarketValues(trSignal, marketType, marketLots,marketSL,marketTP,marketComment);
CalculateNewPendingValues(trSignal, pendingType, pendingOpenPrice, pendingLots, pendingSL, pendingTP, pendingComment);
/**
6.
а) Открыть ордер по рынку
б) Выставить отложенный ордер без ограничения времени
в) Выставить отложенный ордер с истечением по времени
*/if(trSignal!=OP_BALANCE)OpenMarketOrder(ReversTradeSignal,marketType,marketLots,marketSL,marketTP,marketComment);
if(trSignal!=OP_BALANCE)SendPendingOrder(ReversTradeSignal,pendingType,pendingOpenPrice, pendingLots, pendingSL, pendingTP,pendingComment);
//----return(0);
}//+------------------------------------------------------------------+
rotstern:
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Были такие мысли, постараюсь в ближайшие пару месяцев (не могу строго обещать). На данный момент пока есть другие нереализованные статьи, надо с ними сначала закончить.
Сделать Trailing Stop в этом шаблоне очень просто, определите функцию getNewSL(). Вот пример для трейлинга по параболику:
//+------------------------------------------------------------------+//| вычисляет уровень Stop Loss |//+------------------------------------------------------------------+doublegetNewSL(inttype, // тип ордера, для которого вычисляемdoublelots, // объем, может понадобитьсяdoubleopenPrice, // цена открытияdoublestopLoss, // текущий уровень Stop LossdoubletakeProfit// текущий уровень Take Profit){doubleres=-1;
//----// здесь код вычисления Stop Lossif(type == OP_BUY)res = NormalizeDouble(iSAR(NULL,0,0.02,0.2,1),Digits);
if(type == OP_SELL)res = NormalizeDouble(iCustom(NULL,0,0.02,0.2,2,1)+MarketInfo(Symbol(),MODE_SPREAD)*Point,Digits);
//----return(res);
}
Компилируете и запускаете тестирование, все происходит автоматически:
В шаблоне не определена реакция на неправильные значения нового SL (или тейкпрофита), в данном случае видна ошибка #1 на попытку модификации - это означает что новое значение SL не отличается от уже установленного. Но там, где уровень вычислен допустимо, стоплосс подтягивается.
rotstern:
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Были такие мысли, постараюсь в ближайшие пару месяцев (не могу строго обещать). На данный момент пока есть другие нереализованные статьи, надо с ними сначала закончить.
Сделать Trailing Stop в этом шаблоне очень просто, определите функцию getNewSL(). Вот пример для трейлинга по параболику:
//+------------------------------------------------------------------+//| вычисляет уровень Stop Loss |//+------------------------------------------------------------------+doublegetNewSL(inttype, // тип ордера, для которого вычисляемdoublelots, // объем, может понадобитьсяdoubleopenPrice, // цена открытияdoublestopLoss, // текущий уровень Stop LossdoubletakeProfit// текущий уровень Take Profit){doubleres=-1;
//----// здесь код вычисления Stop Lossif(type == OP_BUY)res = NormalizeDouble(iSAR(NULL,0,0.02,0.2,1),Digits);
if(type == OP_SELL)res = NormalizeDouble(iCustom(NULL,0,0.02,0.2,2,1)+MarketInfo(Symbol(),MODE_SPREAD)*Point,Digits);
//----return(res);
}
Компилируете и запускаете тестирование, все происходит автоматически:
В шаблоне не определена реакция на неправильные значения нового SL (или тейкпрофита), в данном случае видна ошибка #1 на попытку модификации - это означает что новое значение SL не отличается от уже установленного. Но там, где уровень вычислен допустимо, стоплосс подтягивается.
У меня не заработал в данном примере трал. Подскажите пожалуйста в чем может быть дело. Можно ли увидеть рабочий пример. А еще нет условия на проверку количества открытых ордеров, тот пример что здесь - при наступлении сигнала ордера открываются до бесконечности. А хотелось бы ограничить как по количеству так и по времени. Например не больше 3 и не ольше одного в час (при работе на минутном графике). Пожалуйста помогите, очень понравилась статья. еще бы до конца довести а то я только учусь программировать.
Новый шаблон советника. Отличается от оптимизированного варианта, опубликованного как Шаблон советника в Code Base, блоком вывода информации об ордерах из Истории в файл .../tester/files/Имя_файла.csv.
Видео:
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Немного изменен шаблон. Вставлены три новые функции, которые могут быть полезны при необходимости учитывать результаты последних закрытых сделок:
В связи с этим, блоки по вычислению параметров для новых ордеров перемещены за блок закрытия рыночных и удаления отложенных ордеров. Теперь структура функции start() выглядит таким образом (нумерация блоков намеренно оне была изменена, чтобы было видно что и куда переехало):
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Сделать Trailing Stop в этом шаблоне очень просто, определите функцию getNewSL(). Вот пример для трейлинга по параболику:
Компилируете и запускаете тестирование, все происходит автоматически:
В шаблоне не определена реакция на неправильные значения нового SL (или тейкпрофита), в данном случае видна ошибка #1 на попытку модификации - это означает что новое значение SL не отличается от уже установленного. Но там, где уровень вычислен допустимо, стоплосс подтягивается.
Слижком уж сложное написание функции нового бара. Предлагаю так:
Усложненный вариант: Через указатель и подсчет новых баров на любой валюте и ТФ
Вариант упрощенный: Работает только на текущем ТФ и валюте...
Слижком уж сложное написание функции нового бара. Предлагаю так:
bool IsNewBar(string vCurrency,int vTimeframe, int &vMaxBars)
Слижком уж сложное написание функции нового бара. Предлагаю так:
Усложненный вариант: Через указатель и подсчет новых баров на любой валюте и ТФ
Очень полезная статья, возвращаюсь к ней в который раз. Не могли ли Вы немного по подробнее остановиться на функциях принудительного закытия ордеров и и трилингстопе (с примером). Был бы Вам очень благодарен.
Сделать Trailing Stop в этом шаблоне очень просто, определите функцию getNewSL(). Вот пример для трейлинга по параболику:
Компилируете и запускаете тестирование, все происходит автоматически:
В шаблоне не определена реакция на неправильные значения нового SL (или тейкпрофита), в данном случае видна ошибка #1 на попытку модификации - это означает что новое значение SL не отличается от уже установленного. Но там, где уровень вычислен допустимо, стоплосс подтягивается.