Дискуссия об управлении капиталом, возникшая на форуме MQLabs, навела на мысли о создании советника, использующего "правильные" методы управления капиталом.
Наиболее распространенным методом управления капиталом является выбор объема сделки в зависимости от размера баланса или свободных средств. Это позволяет увеличить прибыль при росте депозита, но приводит к одному очень неприятному нюансу - размер убыточных сделок в денежном эквиваленте всегда будет больше, чем размер прибыльных сделок, даже если в пересчете на пункты они равны. Такое положение вещей объясняется просто: убыточная сделка оперирует бόльшим депозитом, который после ее закрытия становится меньше. В итоге объем следующей за ней прибыльной сделки рассчитывается, исходя из уменьшенного размера депозита, что приводит к меньшей прибыли в денежном эквиваленте.
Для примера можно рассмотреть следующую последовательность сделок: прибыльная - убыточная - прибыльная. Начальный депозит 10 000 долларов с размером позиции 10% от депозита. Прибыль или убыток примем равными 100 пунктов. Получается, что первая сделка будет совершена объемом 1 лот и принесет 1 000 долларов прибыли, депозит увеличится до 11 000. Вторая сделка будет с объемом 1.1 лот и даст убыток 1 100 долларов, баланс 9 900. Третья сделка будет оперировать объемом 0.99 лота и даст прибыль 990 долларов. Депозит вырос до 10 890 долларов, хотя при равных объемах сделок в 1 лот должно было бы получиться 11 000. То есть такой метод управления капиталом подходит для стратегий с непомерно высоким процентом прибыльных сделок. В реальности таких стратегий нет или очень мало. Поэтому необходимо разрабатывать методики управления капиталом с учетом жизненных реалий.
"Правильное управление капиталом" не может быть основано только на размере депозита. Это целая система, оперирующая несколькими факторами одновременно:
Размер депозита
Допустимый риск в зависимости от размера стопа сделки
Допустимый риск в зависимости от вероятности успешности сделки
Последний пункт можно трактовать по-разному, т.к. расчет вероятности успеха сделки можно развить до разработки полноценной торговой стратегии. Такой подход нельзя считать преувеличением, потому как стратегия торговли и управление капиталом должны согласовываться друг с другом.
Для наглядной демонстрации перечисленных правил управления капиталом возьмем одну из простейших стратегий и добавим к ней блок выбора объема позиции на основании расчета вероятности успеха сделки и размера возможных потерь.
В качестве начальной стратегии можно взять систему, основанную на пробое фракталов. Пробой верхнего фрактала приводит к открытию длинной сделки, а пробой нижнего фрактала - к открытию короткой. В итоге размер стопа сделки будет определяться расстоянием между последними противоположными фракталами, а размер профита - некоторой частью от размера стопа, например 60% (см. рис. 1).
Рис. 1. Открытие и закрытие сделок по пробою фрактала.
На рис. 1 стоп длинной сделки устанавливается по фракталу 20 февраля 15:00, а не по фракталу 20 февраля 22:00, т.к. на момент открытия сделки второй фрактал еще не сформирован. В этой связи необходимо отметить случаи, когда при пробое очередного фрактала противоположный последний фрактал, по которому необходимо установить стоп, также пробит. В дальнейшем на месте пробития, скорее всего, будет сформирован новый фрактал, но на момент принятия решения об уровне стопа такой фрактал еще нельзя считать состоявшимся. В этом случае в качестве ориентира используется максимальное значение цены после фрактала вверх или минимальное значение цены после фрактала вниз, т.е. предполагается, что новый экстремум все же сформируется в виде фрактала (см. рис. 2).
Рис.2. Пробой обоих фракталов без формирования нового фрактала.
Еще одно дополнительное правило пробоя фракталов - пробоем считается пересечение значения фрактала не на один, а на два и более пунктов. Такое правило позволит избежать незначительных нарушений ценой уровней фракталов и, как следствие, уменьшит число убыточных сделок. При этом один лишний пункт в прибыли особой роли не сыграет.
Чтобы снять с эксперта задачу отслеживания пробоя фракталов, открытие сделок будем проводить при помощи отложенных ордеров. Это означает, что с первым же тиком, знаменующим начало очередного бара, цены открытия отложенных ордеров должны быть рассчитаны. По сложившейся традиции значения уровней будут храниться в переменных BuyLevel и SellLevel. Расчет значений переменных возложим на функцию GetSignal, от которой на данный момент приведем лишь первые три блока, отвечающие за поиск фракталов:
// - 1 - =============================== Инициализация переменных ======================= BuyLevel = 0; SellLevel = 0; // Уровни открытия сделок не определены MaxPrice = 0; MinPrice = 0; // Максимальное и минимальное значения цены не определены double UpV = 0, DnV = 0; // Значения фракталов не определены BuyKoef = 0; SellKoef = 0; // Коэффициенты для сделок Buy и Sell не определены // - 1 - ==================================== Окончание блока ===========================
// - 2 - =========================== Поиск последней пары фракталов ===================== for (int i = 3; i < Bars && (UpV == 0 || DnV == 0); i++) { // - 2.1 - ===================== Поиск "верхнего" фрактала ========================== if (UpV == 0) // Если верхний фрактал еще не найден { double Fr = iFractals(NULL, 0, MODE_UPPER, i); // Получение значения "верхнего" // фрактала на свече №i if (Fr != 0) // Если фрактал найден { UpV = Fr; // Сохраняем значение фрактала MaxPrice = High[iHighest(Symbol(), 0, MODE_HIGH, i)];//Определение максимальной // цены после формирования фрактала if (MaxPrice <= UpV + Point) // Если максимальная цена не достигла фрактала, BuyLevel = UpV + 2*Point; // то фрактал будет уровнем для сделки BUY } } // - 2.1 - ========================== Окончание блока ==============================
// - 2.2 - ===================== Поиск "нижнего" фрактала =========================== if (DnV == 0) // Если нижний фрактал еще не найден { Fr = iFractals(NULL, 0, MODE_LOWER, i); // Получение значения "нижнего" // фрактала на свече №i if (Fr != 0) // Если фрактал найден { DnV = Fr; // Сохраняем значение фрактала MinPrice = Low[iLowest(Symbol(), 0, MODE_LOW, i)]; // Определение минимальной // цены после формирования фрактала if (MinPrice >= DnV - Point) // Если минимальная цена не достигла фрактала, то SellLevel = DnV - 2*Point; // фрактал будет уровнем для сделки SELL } } // - 2.2 - ========================== Окончание блока ============================== // - 2 - ==================================== Окончание блока =========================== }
// - 3 - ===================== Проверка достаточности исторических данных =============== if (i == Bars) // Если достигнут конец истории { Alert(WindowExpertName() + ". Слишком мало исторических данных. Советник отключен."); FatalError = True; // Остановка выполнения советника return(false); } // - 3 - ==================================== Окончание блока ===========================
В первом блоке производится инициализация основных переменных значением 0. Уровни BuyLevel или SellLevel по окончании расчетов так и могут остаться не определенными, что означает пробитие соответствующего последнего фрактала. В таком случае для расчетов цены профита и стопа сделки будут использоваться значения переменных MaxPrice или MinPrice, заменяющие значения BuyLevel и SellLevel при их равенстве нулю. Различие ситуаций заключается в том, что для установки отложенного ордера обязательно наличие сформированного значения BuyLevel или SellLevel. Если соответствующий уровень не определен, то ордер установлен не будет. А для уровня стоп-приказа в качестве "пожарного" варианта используется значение еще не сформированного фрактала.
Переменные UpV и DnV являются локальными. В них фиксируются значения найденных фракталов, верхнего и нижнего соответственно. Переменные BuyKoef и SellKoef в первых трех блоках не используются. Поэтому об их назначении будет рассказано позже.
Во втором блоке производится поиск последней пары фракталов. Для этой цели организуется цикл, который может завершиться по причине нахождения значений обоих фракталов или по причине достижения последнего бара в имеющейся истории котировок. Вложенные блоки 2.1 и 2.2 функционируют сходным образом. При нахождении на баре i одного из фракталов (верхнего или нижнего) производится заполнение соответствующей переменной - UpV или DnV. В дальнейших поисках найденный тип фрактала больше не участвует.
Значения переменных MaxPrice и MinPrice при нахождения фрактала заполняются максимальной и минимальной ценой, зафиксированной после формирования фрактала. Эти значения сравниваются со значением фрактала. Если фрактал не был пробит (пробитие в один пункт не считается пробитием), то активизируется соответствующий уровень - BuyLevel или SellLevel.
Блок 3 срабатывает в случае, если не найдено значение хотя бы одного фрактала до достижения последнего бара в истории. В этом случае функция GetSignal завершается с ошибкой, а дальнейшее выполнение эксперта блокируется истинным (True) значением глобальной переменной FatalError.
Обработка значений BuyLevel, SellLevel, MaxPrice и MinPrice производится в теле функции Trade, совершающей торговые операции:
//+-------------------------------------------------------------------------------------+ //| Открытие позиций и установка ордеров | //+-------------------------------------------------------------------------------------+ bool Trade() { // - 1 - ============================= Установка ордера BuyStop ========================= // - 1.1 - ================== Расчет цены открытия, профита и стопа ================= double Price = NP(BuyLevel + Spread); // Расчет цены открытия Buy Stop if (SellLevel > 0) // Если существует SellLevel, то стоп и профит можно рассчитывать { // в обычном режиме double TP = NP(BuyLevel + (BuyLevel - SellLevel)*ProfitLevel/100); double SL = NP(SellLevel); } else // SellLevel не существует. Вместо него необходимо использовать MinPrice { TP = NP(BuyLevel + (BuyLevel - MinPrice)*ProfitLevel/100); SL = NP(MinPrice); } // - 1.1 - =========================== Окончание блока ==============================
// - 1.2 - ====================== Проверка существования Buy Stop =================== if (BuyType == OP_BUYSTOP) // Присутствует BuyStop if (OrderSelect(BuyTicket, SELECT_BY_TICKET) && OrderCloseTime() == 0) if (MathAbs(OrderOpenPrice() - Price) >= Tick || // Несоответствие цены открытия MathAbs(OrderStopLoss() - SL) >= Tick || // стопа или MathAbs(OrderTakeProfit() - TP) >= Tick || // профита имеющейся цене BuyLevel == 0) // означает необходимость перерасчета всех параметров ордера { DeleteOrder(BuyTicket); // Удаление ордера return(False); // При любом результате удаления вернем ошибку для } // обновления информации по ордерам // - 1.2 - =========================== Окончание блока ==============================
// - 1.3 - ========================= Проверка существования Buy ===================== if (BuyType == OP_BUY && // Присутствует Buy - необходимо проверить уровень стопа SellLevel > 0) // Уровень стопа определен if (!ModifyOrderSL(BuyTicket, SL)) // Изменение уровня стопа return(False); // - 1.3 - =========================== Окончание блока ==============================
// - 1.4 - ========== Установка BuyStop при отсутствии Buy или BuyStop ============== if (BuyType < 0 && BuyLevel > 0) // Нет ордера BuyStop или позиции Buy if (OpenOrderCorrect(OP_BUYSTOP, GetLots(Price, SL, BuyKoef), // Установка ордера Price, SL, TP) != 0) return(False); // - 1.4 - =========================== Окончание блока ============================== // - 1 - =============================== Окончание блока ================================
// - 2 - ============================= Установка ордера SellStop ======================== // - 2.1 - ================== Расчет цены открытия, профита и стопа ================= Price = NP(SellLevel); // Расчет цены открытия SellStop if (BuyLevel > 0) // Если уровень BuyLevel определен, то стоп и профит можно { // рассчитывать в обычном порядке SL = NP(BuyLevel + Spread); TP = NP(SellLevel - (BuyLevel - SellLevel)*ProfitLevel/100 + Spread); } else // Уровень BuyLevel не определен, значит, необходимо использовать MaxPrice { SL = NP(MaxPrice + Spread); TP = NP(SellLevel - (MaxPrice - SellLevel)*ProfitLevel/100 + Spread); } // - 2.1 - =========================== Окончание блока ==============================
// - 2.2 - ====================== Проверка существования SellStop =================== if (SellType == OP_SELLSTOP) // Присутствует SellStop if (OrderSelect(SellTicket, SELECT_BY_TICKET) && OrderCloseTime() == 0) if (MathAbs(OrderOpenPrice() - Price) >= Tick || // Несоответствие цены открытия MathAbs(OrderStopLoss() - SL) >= Tick || // стопа или MathAbs(OrderTakeProfit() - TP) >= Tick || // профита имеющейся цене SellLevel == 0) // означает необходимость перерасчета всех параметров ордера { DeleteOrder(SellTicket); // Удаление ордера return(False); // При любом результате удаления вернем ошибку для } // обновления информации по ордерам // - 2.2 - =========================== Окончание блока ==============================
// - 2.3 - ======================= Проверка существования Sell ====================== if (SellType == OP_SELL && // Присутствует Sell - необходимо проверить уровень стопа BuyLevel > 0) // Уровень BuyLevel определен. Значит, можно рассчитать стоп if (!ModifyOrderSL(SellTicket, SL)) // Изменение уровня стопа return(False); // - 2.3 - =========================== Окончание блока ==============================
// - 2.4 - ========= Установка SellStop при отсутствии Sell или SellStop ============ if (SellType < 0 && SellLevel > 0) // Нет ордера SellStop или позиции Sell if (OpenOrderCorrect(OP_SELLSTOP, GetLots(Price, SL, SellKoef), // Установка ордера Price, SL, TP) != 0) return(False); // - 2.4 - =========================== Окончание блока ============================== // - 2 - =============================== Окончание блока ================================
return(True); }
Блоки 1 и 2 вновь алгоритмически подобны. Первый вложенный блок каждого блока формирует цены открытия отложенных ордеров, уровней профита и стоп-приказов. Для ордера BuyStop (блок 1.1) уровень стоп-приказа рассчитывается по значению переменной SellLevel (цена ближайшего нижнего фрактала). Поэтому, в случае равенства значения SellLevel нулю, вместо него используется значение MinPrice. Подобным образом в блоке 2.1, в случае равенства BuyLevel нулю, используется значение MaxPrice.
Переменная ProfitLevel, значение которой используется в расчетах стопа и профита, является внешней переменной эксперта. С ее помощью пользователь может задавать необходимое соотношение размеров профита и стопа в процентах. По умолчанию эксперт использует значение 60%.
Вторые вложенные блоки (1.2 и 2.2) проверяют наличие отложенного ордера. Если он имеется, то его показатели (цена открытия, стоп-приказ и профит) сравниваются с рассчитанными в предыдущем блоке значениями. В случае неравенства одного из значений соответствующему показателю, ордер удаляется с тем, чтобы быть установленным впоследствии с правильными уровнями.
Удаление ордера с последующей установкой вместо простой модификации применено по той причине, что отличие одного из уровней необходимой величине неминуемо вызовет изменение объема ордера. Объем ордера, как будет показано ниже, находится в прямой зависимости от цены открытия ордера и уровня его стоп-приказа, а косвенно, и профита.
Дополнительной причиной удаления ордера является равенство нулю значения переменной BuyLevel (если ордер Buy Stop) и SellLevel (если ордер Sell Stop). Такая ситуация может случиться при длительном отсутствии связи, после которого успел сформироваться новый фрактал, который впоследствии был пробит.
Третий вложенный блок (1.3 и 2.3) проверяет правильность значения уровня стопа, если найдена позиция. Этот блок позволяет перемещать стоп-приказ за ценой по новым фракталам. При достаточно большом значении ProfitLevel и уверенном тренде уровень стопа может оказаться в прибыльной части сделки. Модификация производится при помощи пользовательской функции ModifyOrderSL, задачей которой является сравнение нового и текущего уровней стоп-приказа сделки, а в случае неравенства изменение последнего. Стоит заметить, что уровень стопа перемещается только в том случае, если уровень открытия противоположного ордера (BuyLevel или SellLevel) не равен нулю.
Четвертый вложенный блок (1.4 и 2.4) совершает установку ордера, если таковой обнаружен не был, а уровень входа ордера определен (не равен нулю). Объем ордера рассчитывается путем вызова функции GetLots. Суть этого расчета будет описана ниже, когда речь пойдет о подсчете вероятности успеха сделки.
Подсчет вероятности успеха сделки невозможен без ввода в стратегию дополнительных методов оценки текущей рыночной ситуации. Сделать это можно множеством способов. В данном случае подходящим инструментом является канал линейной регрессии. Точнее, его средняя прямая. По углу наклона средней линии канала можно судить о состоянии тренда. Во-первых, сам наклон свидетельствует о направлении тренда (восходящий или нисходящий). Во-вторых, угол наклона прямой говорит о силе тренда, что можно использовать в качестве увеличения или уменьшения вероятности продолжения тренда.
Под "углом наклона" прямой имеется в виду не тот угол, который можно наблюдать на экране монитора (видимый угол может изменяться в зависимости от настроек графика), а значение коэффициента b, участвующего в уравнении прямой (y = bx+a). Значение этого коэффициента не зависит от настроек графика, т.к. вычисляется в координатах цена-время.
Для построения канала линейной регрессии необходимо два значения: номера начального и конечного баров. В качестве начального бара всегда будет выступать бар номер 1. А вот конечный бар необходимо каким-то образом указывать или рассчитывать. Зная номера баров, на которых найдены последние фракталы, можно в качестве конечного бара указывать бар наиболее раннего фрактала. В результате участком для расчета канала линейной регрессии выступит диапазон баров, непосредственно повлиявший на решение об уровнях открытия сделок (см. рис. 3). При желании этот участок можно увеличить при помощи настроечного параметра эксперта Mult, который позволяет увеличивать количество баров для построения канала линейной регрессии в два и более раз.
Рис. 3. Построение линейной регрессии.
Красной ломаной линией показаны цены закрытия свечей, по значениям которых строится линейная регрессия. Синяя прямая - линейная аппроксимация кривой цен закрытия. Так как наиболее ранний фрактал - верхний, то бар, на котором он сформирован, является конечным для диапазона расчета линейной регрессии.
Расчет коэффициента b и вероятностей успеха сделок производится в нерассмотренных блоках функции GetSignal:
// - 4 - =============== Расчет коэффициента наклона прямой линейной регрессии ========== // Линейная аппроксимация цен закрытия производится методом наименьших квадратов // Цены закрытия - значения некоторой функции, а номера баров - аргументы
// - 4.1 - ===================== Инициализация переменных ============================== int EndBar = (i-1)*Mult; // Количество расчетных баров double sumy = Close[1], // Сумма значений функции sumx = 0.0, // Сумма аргументов функции sumxy = 0.0, // Сумма произведения аргументов и значений sumx2 = 0.0; // Сумма квадратов аргументов функции // - 4.1 - =========================== Окончание блока =================================
// - 4.2 - ======================== Нахождение необходимых сумм ======================== for (i = 1; i < EndBar; i++) // С первого бара до вычисленного номера { sumy += Close[i+1]; // Суммируем значения функции sumxy += Close[i+1]*i; // Сумма произведений аргументов и значений sumx += i; // Сумма аргументов sumx2 += i*i; // Сумма квадратов значений } // - 4.2 - =========================== Окончание блока =================================
// - 4.3 - ======================== Нахожднение необходимых сумм ======================= double c = sumx2*EndBar - sumx*sumx; // Знаменатель формулы нахождения коэффициента b if (c == 0.0) return(True); // Знаменатель не может быть равен нулю double b = (sumxy*EndBar-sumx*sumy)/c; // Нахождение значения коэффициента b // - 4.3 - =========================== Окончание блока ================================= // - 4 - ==================================== Окончание блока ===========================
// - 5 - =============== Определение вероятностей совершения удачной сделки ============= if (b < 0) // Прямая регрессии наклонена вверх BuyKoef = -b*1000/MaxPrice; // Чем выше угол наклона, тем сильнее восходящий тренд else // Прямая регрессии наклонена вниз SellKoef = b*1000/MinPrice; // Чем выше угол наклона, тем сильнее нисходящий тренд // - 5 - ==================================== Окончание блока ===========================
return(True); }
Цель блока 4 - расчет коэффициента b прямой линейной регрессии. Коэффициенты верхней и нижней линий канала линейной регрессии не рассчитываются.
Во вложенном блоке 4.1 вычисляется номер последнего бара, участвующего в расчете линейной регрессии. К началу четвертого блока в переменной i хранится номер бара, следующего за баром последнего найденного фрактала. Чтобы определить номер нужного бара, из значения переменной i вычитается 1. Полученное число умножается на множитель Mult, в результате чего определяется участок для расчета линейной регрессии.
Остальные переменные, определяемые в блоке 4.1, необходимы для расчета каждого из членов формулы, на основании которой вычисляется коэффициент b:
(1),
где: n - это количество баров, участвующих в расчете; x - номера баров; y - цены закрытия баров.
Значение каждого члена формулы формируется во вложенном блоке 4.2: sumy - второй множитель в произведении числителя, sumxy - первая сумма в числителе, sumx - сумма, заключенная в скобках, в знаменателе и первый множитель в произведении числителя, sumx2 - первая сумма в знаменателе.
Окончательное формирование значения b производится в блоке 4.3. Так как необходимо совершить операцию деления, то до нее производится вычисление значения знаменателя с целью предупреждения равенства знаменателя нулю. Если в знаменателе не ноль, то вычисление значения переменной b проходит успешно. В противном случае функция GetSignal завершается досрочно.
В пятом блоке рассчитываются вероятности успешности длинных и коротких сделок на основании значения коэффициента b. Отрицательное значение коэффициента свидетельствует о растущей прямой регрессии. Соответственно, положительное значение говорит о нисходящей прямой. В итоге, чем больше абсолютное значение переменной b, тем выше угол наклона прямой регрессии и тем больше значение соответствующего коэффициента BuyKoef или SellKoef. Эти коэффициенты напрямую влияют на объем будущей сделки. Их значения не могут быть меньше нуля и в большинстве случаев не бывают больше единицы. То есть можно рассматривать значения BuyKoef и SellKoef в качестве вероятностей, имеющих значение от 0 до 100%. При нулевом значении вероятности успеха сделка будет иметь минимально возможный объем, а при единице и больше - максимально возможный.
Преобразование вероятностей в объем производится в теле функции GetLots:
В первой строке функции рассчитывается процент от суммы свободных средств, которые можно использовать в качестве залога для осуществления сделки. Расчет ведется на основании коэффициента вероятности Koef, который передается в функцию третьим аргументом. При нулевом значении параметра Koef переменная Risk примет значение MinRisk, а при значении Koef, равном 1 и более, значение переменной Risk будет равно MaxRisk. MinRisk и MaxRisk - это настроечные параметры эксперта, при помощи которых пользователь может указывать минимальную и максимальную часть от свободных средств, которые участвуют в сделке. Части указываются в процентах.
Вторая строка (состоящая из двух строк) - это непосредственный расчет объема сделки. В числителе дроби (AccountEquity()*(Risk/100)) рассчитывается размер средств, которые станут залогом после открытия сделки. В знаменателе дроби (перенесена на другую строку) рассчитывается размер средств, которые могут быть потеряны при достижении ценой уровня стоп-приказа. Расчет производится, исходя из объема сделки 1 лот.
Деление размера залоговых средств на размер потерь даст искомый объем сделки.
Тестирование советника
Реагируя на здравую критику, прозвучавшую в той же ветке форума, один из постов которой стал побудительной причиной написания рассматриваемого советника, изменен порядок подготовки исторических данных для проведения тестирования. Теперь вместо загрузки истории путем закачки данных из History Centre MetaQuotes (Сервис - Архив котировок - валютная пара - 1 Минута- Загрузить), которая действительно имеет ощутимые "дыры", необходимо воспользоваться сторонними файлами данных, которые не содержат указанной проблемы. Для текущих нужд потребуются данные только по трем валютным парам: EURUSD, GBPUSDи USDJPY.
После закачки каждого из файлов (это архивы, которые нужно распаковать) необходимо импортировать из них котировки в архив котировок MetaTrader 4 (Сервис - Архив котировок - валютная пара - 1 Минута- Импорт). В качестве разделителя нужно указать запятую ",". В файлах доступна качественная минутная история с 01.01.2009 до 10.09.2010.
После импортирования котировок необходимо закрыть графики валют, по которым добавлена история, и увеличить количество исторических баров до 1 100 000 (Сервис - Настройки - Графики, окна "Макс. баров в истории" и "Макс. баров в окне"). После этого перезагрузить MetaTrader 4. С загрузкой терминала открыть используемые графики валют и установить период графиков М1. Для генерации нужного временного периода из минутного необходимо воспользоваться скриптом period_converter, входящим в стандартную поставку MT4. В качестве значения единственного параметра скрипта ExtPeriodMultiplier указать значение 60 (для H1). Для D1 это будет 1440 - столько минут в одном дне. Для генерации нового файла истории обычно требуется не более 10 секунд, по прошествии которых скрипт необходимо удалить с графика.
В результате описанных действий будет получена качественная история для периода Н1 с 01.01.2009 до 10.09.2010. На этом историческом периоде и был протестирован советник FractalsAndRegression. Все значения настроечных параметров, кроме Mult и ProfitLevel, использовались по умолчанию (см. рис. 4-6).
Рис. 4. Результаты тестирования эксперта FractalsAndRegression на валютной паре EURUSD.
EURUSD. Значения параметров: Mult = 1,ProfitLevel = 110. Кривая баланса не отличается стабильностью, но ее рост можно назвать стабильным. Чистая прибыль 13 075 долларов против максимальной просадки 5 142 доллара, что дает фактор восстановления 2.54. Учитывая, что тестирование производилось не фиксированным объемом сделки, а зависящим от размера депозита (не забываем, что это только один из критериев), то правильнее было бы рассматривать показатель относительной просадки в процентах от баланса, который составил 30.12%. Такую просадку нельзя считать допустимой, но это близко к допустимым пределам 10 - 20%.
Рис. 5. Результаты тестирования эксперта FractalsAndRegression на валютной паре GBPUSD.
GBPUSD. Значения параметров: Mult = 1,ProfitLevel = 60. Кривая баланса вновь не блещет стабильностью, но показывает уверенный рост. Чистая прибыль 50 613 долларов при максимальной просадке 19 702 доллара. Фактор восстановления 2.57. Относительная просадка 34.93%, что выше, чем у евро.
Рис. 6. Результаты тестирования эксперта FractalsAndRegression на валютной паре USDJPY.
USDJPY.Значения параметров: Mult = 3, ProfitLevel = 60. Кривая баланса нестабильна, но показывает явное стремление к росту. Чистая прибыль 23 073 доллара против максимальной просадки 12 177 доллара, фактор восстановления 1.89. Относительная просадка в данном случае совпадает с максимальной - 34.43%.
Доработка стратегии для использования в AutoGraf 4.0
Отличительной особенностью созданного советника является отсутствие настроечного параметра Lots, который до этого присутствовал во всех экспертах. Такое стало возможным, благодаря расчету объема позиции самим экспертом, исходя из целого ряда факторов. В итоге регулирование объема сделки путем изменения значения Lot на панели управления AG 4 ни к чему не приведет.
Во входные параметры AG 4 для управления стратегией FractalsAndRegression перенесено четыре параметра: Mult, MinRisk, MaxRisk и ProfitLevel. В таком же порядке им соответствуют параметры AT_1, AT_2, AT_3 и AT_4.
Запуск стратегии FractalsAndRegression в среде AutoGraf 4.0 состоит из следующих шагов:
Получить файл по ссылке Файлы стратегий для AutoGraf 4.0 и распаковать полученный архив в папку MT4\experts\libraries (с перезаписью файлов AG_AT.ex4 и AG_AT.mq4).
Запустить AutoGraf.
Для работы стратегии в ключе приведенных результатов в окне настроек AutoGraf (закладка "Входные параметры") установить нужные значения параметров AT_1 - AT_4. Полное повторение результатов при этом не гарантируется.
Выбрать стратегию №5. Для этого необходимо передвинуть вверх значок So и среди названий стратегий найти значок S5, который также потянуть вверх.
Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.
Использование полученного советника рекомендуется только в полуавтоматическом режиме под присмотром трейдера и после всестороннего изучения слабых и сильных сторон стратегии.
Комментарии
Отправить комментарий