| / | Статьи |
Cтатьи
Торговые системы
Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота
Авторизуйтесь или зарегистрируйтесь , чтобы добавить новую статью
|
Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота [ en ]ВведениеБольшинство учебников по торговле на финансовых рынках обычно предлагает в качестве учебного материала для реальной торговли простейшие торговые системы. Но на сегодняшний день эти системы существуют только в виде общих руководств, без должного воплощения подобных торговых стратегий в виде готовых к употреблению экспертов. И поэтому на сегодняшний день не представляется возможным оценить - есть ли от них какая-нибудь практическая польза. Если сделать беглый обзор многочисленных форумов, посвящённых написанию экспертов, то можно сделать вывод, что едва ли не каждый начинающий экспертописатель вынужден изобретать велосипед и проектировать своих первых экспертов на основе простейших торговых систем заново. Мне лично целесообразность такого труда представляется весьма сомнительной, и так думается, что давно назрела необходимость сделать доступными для любого начинающего трейдера один раз правильно написанные советники на основе этих торговых систем, и избавить его от необходимости всё начинать с нуля. В данной статье я хотел бы представить свой вариант решения подобной задачи. Для построения экспертов я буду брать индикаторы из своей библиотеки, которую я уже использовал в cтатье Эффективные алгоритмы усреднения с минимальным лагом и их использование в индикаторах Общая схема строения экспертовПрежде чем приступить к изложению материала, мне следовало бы пояснить, что все эксперты, которые будут предложены в данной статье, построены по одной и той же схеме:
Торговая система на основе изменения направления движения мувингаТеперь я постараюсь достаточно подробно объяснить суть предложенной схемы строения эксперта на примере готового эксперта, детально изложив все тонкости работы с ним. В данной системе в качестве сигналов для покупки будет смена направления движения мувинга с падающего на возрастающее:
а сигналов для продажи - смена направления движения мувинга с возрастающего на падающее:
Для расчётов трендовых сигналов используются значения мувинга на третьем, втором и первом барах. Значения мувинга на нулевом баре в расчётах не используются, то есть торговая система работает только на закрытых барах. В качестве мувинга используется пользовательский индикатор JFATL, представляющий собой обычный цифровой фильтр FATL с дополнительным JMA сглаживанием. В интернете можно очень часто встретить утверждения, что вход в сделку при смене направления движения иникатора FATL всегда сулит определённое количество пунктов прибыли, так что теперь у любого читателя есть хорошая возможность самому убедиться в том, насколько состоятельны данные заявления в действительности! Вот вариант реализации данной торговой системы в виде эксперта: Код эксперта//+==================================================================+ //| Exp_1.mq4 | //| Copyright © 2007, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2007, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ BUY СДЕЛОК extern bool Test_Up = true;//фильтр направления расчётов сделок extern int Timeframe_Up = 240; extern double Money_Management_Up = 0.1; extern int Length_Up = 4; // глубина сглаживания extern int Phase_Up = 100; // параметр, изменяющийся в пределах //-100 ... +100, влияет на качество переходного процесса; extern int IPC_Up = 0;/* Выбор цен, по которым производится расчёт индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Up = 50; // стоплосс extern int TAKEPROFIT_Up = 100; // тейкпрофит extern bool ClosePos_Up = true; // разрешение принудительного закрывания позиции //---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ SELL СДЕЛОК extern bool Test_Dn = true;//фильтр направления расчётов сделок extern int Timeframe_Dn = 240; extern double Money_Management_Dn = 0.1; extern int Length_Dn = 4; // глубина сглаживания extern int Phase_Dn = 100; // параметр, изменяющийся в пределах // -100 ... +100, влияет на качество переходного процесса; extern int IPC_Dn = 0;/* Выбор цен, по которым производится расчёт индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Dn = 50; // стоплосс extern int TAKEPROFIT_Dn = 100; // тейкпрофит extern bool ClosePos_Dn = true; // разрешение принудительного закрывания позиции //---- Целые переменные для минимума расчётных баров int MinBar_Up, MinBar_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //---- Проверка значения переменной Timeframe_Up на корректность if (Timeframe_Up != 1) if (Timeframe_Up != 5) if (Timeframe_Up != 15) if (Timeframe_Up != 30) if (Timeframe_Up != 60) if (Timeframe_Up != 240) if (Timeframe_Up != 1440) Print(StringConcatenate("Параметр Timeframe_Up не может ", "быть равным ", Timeframe_Up, "!!!")); //---- Проверка значения переменной Timeframe_Dn на корректность if (Timeframe_Dn != 1) if (Timeframe_Dn != 5) if (Timeframe_Dn != 15) if (Timeframe_Dn != 30) if (Timeframe_Dn != 60) if (Timeframe_Dn != 240) if (Timeframe_Dn != 1440) Print(StringConcatenate("Параметр Timeframe_Dn не может ", "быть равным ", Timeframe_Dn, "!!!")); //---- Инициализация переменных MinBar_Up = 4 + 39 + 30; MinBar_Dn = 4 + 39 + 30; //---- завершение инициализации return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- Завершение деинициализации эксперта return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Объявление локальных переменных int bar; double Mov[3], dMov12, dMov23; //----+ Объявление статических переменных static int LastBars_Up, LastBars_Dn; static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; //----++ КОД ДЛЯ ДЛИННЫХ ПОЗИЦИЙ if (Test_Up) { int IBARS_Up = iBars(NULL, Timeframe_Up); if (IBARS_Up >= MinBar_Up) { if (LastBars_Up != IBARS_Up) { //----+ Иницмализация переменных BUY_Sign = false; BUY_Stop = false; LastBars_Up = IBARS_Up; //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up, "JFatl", Length_Up, Phase_Up, 0, IPC_Up, 0, bar); //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 < 0) if (dMov12 > 0) BUY_Sign = true; if (dMov12 < 0) BUY_Stop = true; } //----+ СОВЕРШЕНИЕ СДЕЛОК if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up)) return(-1); if (ClosePos_Up) if (!CloseOrder1(BUY_Stop, 1)) return(-1); } } //----++ КОД ДЛЯ КОРОТКИХ ПОЗИЦИЙ if (Test_Dn) { int IBARS_Dn = iBars(NULL, Timeframe_Dn); if (IBARS_Dn >= MinBar_Dn) { if (LastBars_Dn != IBARS_Dn) { //----+ Иницмализация переменных SELL_Sign = false; SELL_Stop = false; LastBars_Dn = IBARS_Dn; //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn, "JFatl", Length_Dn, Phase_Dn, 0, IPC_Dn, 0, bar); //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 > 0) if (dMov12 < 0) SELL_Sign = true; if (dMov12 > 0) SELL_Stop = true; } //----+ СОВЕРШЕНИЕ СДЕЛОК if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn)) return(-1); if (ClosePos_Dn) if (!CloseOrder1(SELL_Stop, 2)) return(-1); } } //----+ return(0); } //+------------------------------------------------------------------+ Для получения сигналов покупки и продажи во всех блоках используются два абсолютно одинаковых независимых алгоритма, каждый из которых имеет свои внешние параметры эксперта для оптимизации. По моим наблюдениям подобный подход к написанию этого эксперта оказывается значительно более прибыльным, чем вариант со всего одним алгоритмом для определения сигналов Buy и Sell сделок. Кому интересен вариант с одним мувингом для лонговых и шортовых позиций, могут заняться этим алгоритмом, который представлен в эксперте EXP_0.mq4, а мы продолжим исследование эксперта с двумя мувингами. Эксперт может открывать всего по одной позиции в Buy и по одной позиции в Sell направлениях одновременно на одной торговой паре. Эксперт совершает сделки с рынка. Сделки закрываются по ордерам стоплосс и тейкпрофит. При возникновении трендовых сигналов против открытых позиций в эксперте имеется возможность принудительно закрывать сделки. Метод получения сигналов для выхода из сделок аналогичен методу получения сигналов для входа, но имеет противоположный характер. Содержание файла Lite_EXPERT1.mqhИсходя из соображений максимальной экономии собственного труда, следует стремиться к тому, чтобы использовать при написании экспертов максимальное количество универсальных пользовательских функций. И в дальшейшем производить сборку кода эксперта, как это делают на современных заводах по производству любой техники, на которых всякое новое изделие содержит максимальное количество унифицированных и стандартных деталей, блоков и модулей! По этой причине во всех экспертах в блоке "Совершение сделок" используется несколько универсальных пользовательских функций, которые включаются в код эксперта директивой #include <Lite_EXPERT1.mqh> : bool OpenBuyOrder1 ( bool BUY_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT ) bool OpenSellOrder1 ( bool SELL_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT ) CountLastTime ( int lastError ) bool CloseOrder1 ( bool Stop_Signal, int MagicNumber ) int StopCorrect ( string symbol, int Stop ) bool MarginCheck ( string symbol, int Cmd, double& Lot ) double GetFreeMargin() bool DeleteOrder1 ( bool& CloseStop, int MagicNumber ) bool OpenBuyLimitOrder1 ( bool& Order_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration ) bool OpenBuyStopOrder1 ( bool& Order_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration ) bool OpenSellLimitOrder1 ( bool& Order_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration ) bool OpenSellStopOrder1 ( bool& Order_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration ) bool OpenBuyOrder2 ( bool BUY_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT ) bool OpenSellOrder2 ( bool SELL_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT ) bool Make_TreilingStop ( int MagicNumber, int TRAILINGSTOP ) Функция OpenBuyOrder1() открывает длинные позиции при обращении к ней, если значение внешней переменной BUY_Signal равно true и отсутствуют открытые позиции, идентификационное ("магическое") число которых равно значению переменной MagicNumber. Значения внешних переменных STOPLOSS и TAKEPROFIT определяют соответственно величину стоплосса и тейкпрофита в пунктах. Значение переменной Money_Management может изменяться от нуля и до единицы. Эта переменная определяет, какая часть средств от всех имеющихся в наличии на депозите расходуется для совершения сделки. Если сделать значение этой переменной меньше нуля, то в этом случае функция OpenBuyOrder1() будет использовать её значение, как величину лота! Абсолютно аналогично открывает короткие позиции при обращении к ней функция OpenSellOrder1(). Обе функции открывают позиции независимо друг от друга, но в течение одиннадцати секунд на сервер может быть подана всего одна команда для совершения сделки. Помимо совершения сделок функции OpenBuyOrder1() и OpenSellOrder1() пишут в лог файл информацию по открываемым сделкам. Функция CloseOrder1() при обращении к ней, если переменная Stop_Signal принимает значение true, закрывает позицию с идентификационным ("магическим") числом, равным значению переменной MagicNumber. Функция StopCorrect() принимает в качестве параметра Stop значение стоплосса или тейкпрофита, проверяет его на минимально допустимое, при необходимости корректирует до минимально допустимого и возвращает его с учётом возможной коррекции. Назначение функции MarginCheck() - это уменьшение величины лота, который используется в открываемой сделке до максимальной величины, при которой на открытие сделки будет ещё достаточно средств, в случае если этих средств с текущей величиной лота оказалось недостаточно. Функции OpenBuyOrder1(), OpenSellOrder1() и CloseOrder1() используются внутри функции start(), в то время как функции StopCorrect() и MarginCheck() предназначены для использования внутри кода функций OpenBuyOrder1() и OpenSellOrder1(). При корректном завершении выполнения функций OpenBuyOrder1(), OpenSellOrder1() и CloseOrder1() любая из них возвращает значение true, при возникновении ошибок при выполнении этих функций возвращаемое значение оказывается равным false. Все три функции OpenBuyOrder1(), OpenSellOrder1() и CloseOrder1() при совершении сделок значения своих внешних переменных BUY_Signal, SELL_Signal и Stop_Signal сбрасывают в false! Функция GetFreeMargin() возвращает размер свободных средств текущем счете с учётом прибылей и убытков, который можно использовать для открывания позиций. Эта функция используется для расчёта величины лота. Функция CountLastTime() делает инициализацию переменной LastTime с учётом ошибки, возникшей при выполнении торговой операции. Обращение к этой функции следует делать сразу после выполнения торговой операции, например: //----+ Открываем позицию на покупку ticket = OrderSend(Symb, OP_BUY, Lot, ask, 3, Stoploss, TakeProfit, NULL, MagicNumber, 0, Lime); //---- Расчёт паузы между торговыми операциями CountLastTime(GetLastError()); Кроме вышеперечисленных функций файл Lite_EXPERT.mqh содержит ещё четыре функции для выставления отложенных ордеров и одну функцию для удаления отложенных ордеров: OpenBuyLimitOrder(), OpenBuyStopOrder1(), OpenSellLimitOrder1(), OpenSellStopOrder1(), DeleteOrder1(). Назначение внешних переменных этих функций абсолютно аналогичное и понятное из названий,. Новые переменные LEVEL и Expiration необходимы для передачи функциям расстояния в пунктах от текущей цены, на котором ставятся отложенные ордера, и время истечения отложенного ордера соответственно. Помимо всех, уже рассмотренных функций в файле имеются ещё две функции: OpenBuylOrder2() и OpenSellOrder2(), являющиеся полными аналогами функций OpenBuyOrder1() и OpenSellOrder1(), за исключением одной детали. Эти функции сначала открывают позиции без ордеров стоплосс и тейкпрофит, а после этого модифицируют уже открытые позиции значениями стоплосса и тейкпрофита. Эти функции необходимы для работы в составе экспертов, предполагающихся для использования с брокерами, в регламенте торговых операций которых при открытии позиции по рынку Клиент не может выставить ордера Stop Loss и Take Profit в связи с типом исполнения «Market Watch». Выставление ордеров типа Stop Loss и Take Profit у таких брокеров происходит по средствам модификации открытой позиции. И последняя функция, которая входит в состав файла - это Make_TreilingStop(). Функия выполняет стандартный трейлинстоп. Помимо функций файл Lite_EXPERT.mqh содержит целую переменную LastTime, которая объявлена на глобальном уровне по причине её одновременного использования во всех функциях для открытия ордеров. На мой взгляд данный набор функций достаточно удобен для их практического применения при написании экспертов, и съэкономит огромное количество времени начинающим экспертописателям, избавив их от необходимости писать этот код самостоятельно. В качестве примера можно взять любую функцию из вышепредложенного набора функций: //+==================================================================+ //| OpenBuyOrder1() | //+==================================================================+ bool OpenBuyOrder1 (bool& BUY_Signal, int MagicNumber, double Money_Management, int STOPLOSS, int TAKEPROFIT) { //----+ if (!BUY_Signal) return(true); //---- Проверка на истечение минимального интервала времени //между двумя торговыми операциями if (TimeCurrent() < LastTime) return(true); int total = OrdersTotal(); //---- Проверка на наличие открытой позиции //с магическим числом равным значению переменной MagicNumber for(int ttt = total - 1; ttt >= 0; ttt--) if (OrderSelect(ttt, SELECT_BY_POS, MODE_TRADES)) if (OrderMagicNumber() == MagicNumber) return(true); string OpderPrice, Symb = Symbol(); int ticket, StLOSS, TkPROFIT; double LOTSTEP, MINLOT, MAXLOT, MARGINREQUIRED; double FreeMargin, LotVel, Lot, ask, Stoploss, TakeProfit; //----+ расчёт величины лота для открывания позиции if (Money_Management > 0) { MARGINREQUIRED = MarketInfo(Symb, MODE_MARGINREQUIRED); if (MARGINREQUIRED == 0.0) return(false); LotVel = GetFreeMargin() * Money_Management / MARGINREQUIRED; } else LotVel = MathAbs(Money_Management); //---- LOTSTEP = MarketInfo(Symb, MODE_LOTSTEP); if (LOTSTEP <= 0) return(false); //---- нормирование величины лота до ближайшего стандартного значения Lot = LOTSTEP * MathFloor(LotVel / LOTSTEP); //----+ проверка лота на минимальное допустимое значение MINLOT = MarketInfo(Symb, MODE_MINLOT); if (MINLOT < 0) return(false); if (Lot < MINLOT) return(true); //----+ проверка лота на максимальное допустимое значение MAXLOT = MarketInfo(Symb, MODE_MAXLOT); if (MAXLOT < 0) return(false); if (Lot > MAXLOT) Lot = MAXLOT; //----+ проверка величины лота на достаточность средств на счёте if (!MarginCheck(Symb, OP_BUY, Lot)) return(false); if (Lot < MINLOT) return(true); //---- ask = NormalizeDouble(Ask, Digits); if (ask == 0.0) return(false); //---- StLOSS = StopCorrect(Symb, STOPLOSS); if (StLOSS < 0) return(false); //---- Stoploss = NormalizeDouble(ask - StLOSS * Point, Digits); if (Stoploss < 0) return(false); //---- TkPROFIT = StopCorrect(Symb, TAKEPROFIT); if (TkPROFIT < 0) return(false); //---- TakeProfit = NormalizeDouble(ask + TkPROFIT * Point, Digits); if (TakeProfit < 0) return(false); Print(StringConcatenate ("Открываем по ", Symb, " позицию на покупку с магическим числом ", MagicNumber)); //----+ Открываем позицию на покупку ticket = OrderSend(Symb, OP_BUY, Lot, ask, 3, Stoploss, TakeProfit, NULL, MagicNumber, 0, Lime); //---- Расчёт паузы между торговыми операциями CountLastTime(GetLastError()); //---- if(ticket > 0) { if (OrderSelect(ticket, SELECT_BY_TICKET)) { BUY_Signal = false; OpderPrice = DoubleToStr(OrderOpenPrice(), Digits); Print(StringConcatenate(Symb, " BUY ордер с тикетом №", ticket, " и магическим числом ", OrderMagicNumber(), " открыт по цене ",OpderPrice)); return(true); } else { Print(StringConcatenate("Не удалось окрыть ", Symb, " BUY ордер с магическим числом ", MagicNumber, "!!!")); return(true); } } else { Print(StringConcatenate("Не удалось окрыть ", Symb, " BUY ордер с магическим числом ", MagicNumber, "!!!")); return(true); } //---- return(true); //----+ } Написать такой код во всех подробностях для начинающего освоение MQL4 без явных и неявных ошибок - это мероприятие достаточно трудоёмкое и продолжительное. Но вот использовать такой универсальный код( написанный специалистом ) в любых других своих экспертах в готовом виде - это дело буквально нескольких секунд: //----+ СОВЕРШЕНИЕ СДЕЛОК if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up)) return(-1); if (ClosePos_Up) if (!CloseOrder1(BUY_Stop, 1)) return(-1); Всего несколько строчек обращений к универсальным пользовательским функциям - и готово! Достаточно один раз внимательно разобраться, как писать обращения к этим функциям. И самое главное при таком подходе то, что код эксперта становится достаточно простым и понятным для восприятия, благодаря чему в кратчайшие сроки в экспертах можно воплотить какие угодно торговые стратегии. В эксперте Exp_1.mq4 функции для открытия отложенных ордеров и трейлинстоп не используются, и поэтому при компиляции этого эксперта MetaEditor выдаст предупреждение об удалении этих функций из советника:
Дополнительные пояснения к коду экспертаТеперь можно перейти к изучению остального кода эксперта. Сам эксперт состоит из двух почти одинаковых алгоритмов, так что для нормального понимания деталей вполне достаточно разобраться, например, с той частью эксперта, которая открывает длинные позиции. В коде эксперта уже есть комментарии, объясняющие назначение отдельных фрагментов кода. Так что давайте поподробнее остановимся на тех вещах, которые не попали в эти комментарии. В блоке инициализации производится инициализация переменной MinBar_Up: //---- Инициализация переменных MinBar_Up = 4 + 39 + 30; Назначение этой переменной - это сохранение в памяти эксперта минимального количества баров, меньше которого работа эксперта в лонговом направлении невозможна. Это значение определяется из алгоритма пользовательского индикатора JFATL.mq4. Для расчёта всего одного значения цифрового фильтра FATL требуется 39 баров графика. Для получения сглаженного алгоритмом JMA индикатора JFATL требуется как минимум 30 значений FATL и в экспертном алгоритме определения сигналов для сделок используется три предпоследних бара графика и плюс четвёртый, нулевой, последний. Сама проверка на достаточность количества баров для дальнейшего расчёта выглядит следующим образом: if (IBARS_Up >= MinBar_Up) Проверка if (LastBars_Up != IBARS_Up) необходима для того, чтобы эксперт не занимался пересчётом сигналов для входа в рынок на каждом тике, а делал это только при смене бара, что весьма серьёзно экономит ресурсы компьютера и значительно сокращает время оптимизации эксперта. Именно по этой причине переменная LastBars_Up объявлена как статическая, для запоминания количества баров на предыдущем тике функции int start(). Инициализация переменных BUY_Sign, BUY_Stop для входа и выхода из рынка происходит всего один раз при смене бара, а значение они должны держать, пока не будет совершена или закрыта сделка, либо пока не произойдёт ещё одна смена бара. По этой причине эти переменные объявлены как статические. Я так полагаю, что остальные подробности строения эксперта вполне понятны из его кода и в дальнейших комментариях не нуждаются. Замена мувинга в эксперте
|
![]() Использование платформы MetaTrader 4 для выявления благоприятных временных окон (паттернов времени)
Анализ паттернов времени может применяться для рынка Форекс с целью определения наилучшего времени для открытия сделок, а также периодов, когда не следует торговать вовсе. В данном случае мы используем торговую платформу MetaTrader 4 для анализа истории и оптимизации результатов, которые могут быть использованы в механических торговых системах. |
![]() Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота (Продолжение)
В данной статье автор продолжает обзор алгоритмов реализации простейших торговых систем и знакомит с некоторыми, актуальными подробностями использования результатов оптимизаций. Статья будет полезна начинающим трейдерам и начинающим экспертописателям |
| Предыдущая | Следующая |
У меня даже самый первый эксперт не работает!
Выдает кучу вот таких сообщений:
2009.03.29 13:39:39 2009.03.02 04:30 JFatl EURUSD,M15: JJMASeries number =0. Ошибка!!! Параметр nJMA.limit функции JJMASeries() меньше, чем необходимоПросмотрел все комментарии. Самое главное в статье никто не оценил:
1. Файлу с универсальными функциями (Lite_EXPERT1.mqh) просто цены нет. Учтены практически все ситуации, которые могут возникнуть при взаимодействии с торговым сервером - посмотрите, например, как вычисляется размер лота ! Или корректируется стоплосс, тэйкпрофит ! Да и много всякого другого тонкого и упреждающего. Часто и густо, даже опытные программисты ловятся на таких, на первый взгляд, мелочах, теряя, при этом, время, силы и нервную энергию. А как продуманы, лаконичны и осмысленны все обозначения переменных !
2. Второй очень ценный момент - раз и навсегда отделена алгоритмическая часть стратегии от части, отвечающей за взаимодействие с ТС.
Причем, это разделение выполнено очень тонко, рационально и со всей возможной экономией вычислительных ресурсов.
Вот такая светлая и ясная голова у Н.К !. И все свое богатство он выкладывает всем бесплатно !
Странно, никто не обратил внимания на опечатку:
сигнал на покупку должен быть - if (Mov2-Mov3 < 0) && (Mov1-Mov2 >0) BuySignal = true, аналогичная опечатка для сигнала на продажу.
Иначе говоря, условия на покупку и продажу надо поменять местами...
В самих программных кодах всех трех экспертов, эти места написаны верно: покупка, когда
(Mov2-Mov3) < 0 && (Mov1-Mov2) > 0 и т.д.
timbo! Вы вообще-то определитесь, что вам конкретно надо! Просто buy(количество) и всё или бесконечные ковыряния в программном коде ради самих этих ковыряний со всеми этими Hello World! И, кстати, на этом форуме присутствуют прежде всего трейдеры, а не программисты! Со стороны выглядит достаточно нелогично, как вы в одном топике говорите одно, а в другом абсолютно всё выворачиваете наизнанку!
timbo! Вы вообще-то определитесь, что вам конкретно надо! Просто buy(количество) и всё или бесконечные ковыряния в программном коде ради самих этих ковыряний со всеми этими Hello World! И, кстати, на этом форуме присутствуют прежде всего трейдеры, а не программисты! Со стороны выглядит достаточно нелогично, как вы в одном топике говорите одно, а в другом абсолютно всё выворачиваете наизнанку!
СТРАННО КАКТО ПОЛУЧАЕТСЯ ПО НАЧАЛУ ВСЁ СУПЕР НО КОГДА НАЧИНАЕШ ТЕСТИРОВАТЬ ПО ВТОРОМУ КРУГУ ЧЁТО ОТРУБАЕТСЯ СОВЕТНИК А ТАКЖЕ ФУНКЦИИ В ЛИТЛЕ ДАЮТ СБОЙ ПРИ ВСЁМ ЭТОМ ТРАФИК ВАЛИТ КАК БЕШАННЫЙ ..... К ЧЕМУ БЫ ЭТО ???
ПОХОЖЕ НА 12.03.2008 02:02 allexdav
СТРАННО КАКТО ПОЛУЧАЕТСЯ ПО НАЧАЛУ ВСЁ СУПЕР НО КОГДА НАЧИНАЕШ ТЕСТИРОВАТЬ ПО ВТОРОМУ КРУГУ ЧЁТО ОТРУБАЕТСЯ СОВЕТНИК А ТАКЖЕ ФУНКЦИИ В ЛИТЛЕ ДАЮТ СБОЙ ПРИ ВСЁМ ЭТОМ ТРАФИК ВАЛИТ КАК БЕШАННЫЙ ..... К ЧЕМУ БЫ ЭТО ???
ПОХОЖЕ НА 12.03.2008 02:02 allexdav
timbo! Вы вообще-то определитесь, что вам конкретно надо! Просто buy(количество) и всё или бесконечные ковыряния в программном коде ради самих этих ковыряний со всеми этими Hello World! И, кстати, на этом форуме присутствуют прежде всего трейдеры, а не программисты! Со стороны выглядит достаточно нелогично, как вы в одном топике говорите одно, а в другом абсолютно всё выворачиваете наизнанку!
Вы уж как-то разберитесь внутри самого себя! Иначе это со стороны смотрится ну очень некрасиво! Я сам человек с достаточно нормальной логикой и мне противоречащий друг другу смысл пары ваших топиков сразу бросается в глаза! Тут без обид!