Министерство образования и науки Российской Федерации
РЕКЛАМНО-ТЕХНИЧЕСКОЕ ОПИСАНИЕ
Программа Fx-Libra для торговли на рынке Форекс
..00853
Листов 27
Разработчики:
_________________//
_________________/ /
23.01.2013 <пусто>
1. Функциональное назначение программы Fx-Libra, область
применения программы и ограничения по ее использованию
Программа Fx-Libra (ver. 1.0) – выполняется под управлением торгового терминала MT4 и предназначена для получения прибыли от проведения операций с валютными инструментами на рынке Форекс (Forex).
Принцип работы программы. Программа работает, строя свою стратегию на показаниях индикатора расчета скользящего среднего, представленного функцией iMA, значения которой присваиваются переменной indikator: indikator = iMA(Symbol(), 0, period, 0, MODE_SMA, PRICE_CLOSE, 1);. Период, на котором тестировалась программа – 15 минутный таймфрейм (М15).
Используется простое скользящее среднее MODE_SMA. Для расчёта индикатора используется цена закрытия PRICE_CLOSE.

Рисунок 1 – выставление и срабатывание отложенных ордеров
Алгоритм программы, основываясь на показаниях индикатора, определяет направление краткосрочного тренда (используется 15 минутный диапазон). Коррекционные колебания направлены в сторону противоположную тренду. Программа выставляет серию отложенных ордеров типа SELL LIMIT, если тренд медвежий или BUY LIMIT, если тренд бычий. На коррекционном движении цена “зацепляет” ордер, он открывается и далее цена движется по тренду, после чего ордер закрывается по заданному уровню прибыли. Уровень прибыли рассчитывается автоматически или может быть назначен глобальной настройкой – значение переменной globaltakeprofit. К сожалению, не представляется возможным абсолютно точно определить, когда закончится коррекция. Можно выставить серию отложенных ордеров (рис. 1), число которых определяется трейдером с учетом нагрузки на депозит. Если цена затем движется по планируемому сценарию, то наличие нескольких открытых ордеров позволяет или получить большую прибыль или закрыть ордера с общей прибылью, если трейдер опасается, что коррекция будет продолжаться дальше после “коррекции к коррекции”. Во втором случае часть ордеров закрывается с убытком, но сумма получается положительной.
Трейдер может задать отрицательное значение для переменной globalloss, отвечающей за контроль совокупного убытка по всем открытым ордерам. Всегда следует учитывать возможность разворота рынка, то есть смену тренда. В этом случае убытки будут только нарастать, если не закрыть ордера с убытком. Видится целесообразным для депозита в 5000 устанавливать значение переменной -500. То есть риск 10-15% приемлем. Из большей просадки потребуется больше времени для выхода. Следует учесть, что если ордера не закрыть (или не залокировать), то нарастание убытков при продолжении сменившегося тренда приведет к полной потере депозита трейдером. Использование переменной restar со значением 1 позволяет автоматически "перезапускать" программу после фиксации по срабатыванию в ситуациях, определенных globaltakeprofit или globalloss.
Трейдер может разрешить программе открывать ордера только в том случае, если направление тренда на М15 совпадает с направлением тренда на старших таймфреймах. Для этого следует выбрать в настройках советника открытие ордеров только для длинных или коротких позиций (рис. 2).

Рисунок 2 – открытие ордеров только для длинных или коротких позиций
Использование такого подхода позволяет повысить прибыль за счет сокращения размера возможных просадок советника. Данный подход можно рекомендовать во время выраженного тренда на старших таймфреймах. Если отмечается флэт, то можно разрешить советнику самому определяться с открытием длинных (на покупку) или коротких (на продажу) позиций.
Разработанная программа позволяет использовать 16 разных настроек. Для эффективного использования необходима оптимизация значений параметров с учетом используемой валютной пары, размера депозита и стратегии поведения трейдера (консервативная, умеренная, агрессивная).
Технические ограничения, накладываемые на использование программы, вытекают из ограничений, установленных на эксплуатацию терминала MT4, так как программа выполняется под управлением MT4. Торговые ограничения, то есть ограничения на минимально используемое значение лота для открытия позиции, минимальное значение отступа выставления отложенного ордера типа Limit от текущего значения Bid или Ask, максимальное количество выставляемых ордеров – эти значения зависят от настроек того Центра (ДЦ) у которого пользователь открыл свой счет.
Оптимизация и настройки программы
Для повышения скорости тестирования в программу была добавлена переменная test_only, если значение ее установлено равным 1, то отключаются все дополнительные проверки, в том числе проверки ограничений globaltakeprofit и globalloss, что ускоряет время тестирования.
Результаты тестирования на часто используемом трейдерами депозите $5000. Интервал с 3 декабря по 24 декабря 2012 г. Чистая прибыль $1181.91
Данные для тестирования: Символ GBPUSD (Great Britain Pound vs US Dollar). Период 15 Минут (M0:09:00 (2012.12). Модель Все тики (наиболее точный метод на основе всех наименьших доступных таймфреймов). Параметры Lots=0.01; yes_Мах_Lots=0; Мах_Lots=20; lim_step=100; Op_step=120; period=144; MN=12345; n_orders=30; klot=1; Yes_Friday=0; koef_martingale=1; maxerror=30; globaltakeprofit=500; globalloss=-500; restart=1; test_only=0;
Результаты:
Баров в истории 2518
Смоделировано тиков 652908
Качество моделирования 90.00%
Ошибки рассогласования графиков 0
Начальный депозит 5000.00
Чистая прибыль 1181.91

Рисунок 3 – тестирование программы на сверхбольшом депозите.
Общая прибыль 1737.68
Общий убыток -555.77
Прибыльность 3.13
Матожидание выигрыша 24.62
Абсолютная просадка 2700.26
Максимальная просадка 3166%)
Относительная просадка 57.92% (3166.00)
Всего сделок 48
Короткие позиции (% выигравших)%)
Длинные позиции (% выигравших)%)

Рисунок 4 – тестирование программы на депозите $5000
Прибыльные сделки (% от всех)%)
Убыточные сделки (% от всех)%)
Самая большая
прибыльная сделка 285.20
убыточная сделка -47.27
Средняя
прибыльная сделка 69.51
убыточная сделка -24.16
Максимальное количество
непрерывных выигрышей (прибыль)
непрерывных проигрышей (убыток)
Максимальная
непрерывная прибыль (число выигрышей) 1572
непрерывный убыток (число проигрышей) -430
Средний
непрерывный выигрыш 8
непрерывный проигрыш 8
Время выполнения задачи оптимизации составило 46 часов 16 минут 24 секунды.
Оптимизировались параметры:
lim_step: начальное значение – 100 , конечное значение – 500, шаг – 50 ;
Op_step: начальное значение – 100 , конечное значение – 300 , шаг – 10;
period: начальное значение – 100 , конечное значение – 160, шаг – 5;
n_orders: начальное значение – 3 , конечное значение – 50, шаг – 1.
Используемые не оптимизируемые значения переменных:
Lots 0.01; yes_Max_Lots 0; Max_Lots 20; MN 12345; klot 1; Yes_Friday 0; koef_martingale 1; maxerror 30; globaltakeprofit 0; globalloss 0; restart 1;test_only. Для ускорения тестирования были полностью убраны из программного кода строки, составляющие блок: if (test_only==1) { ... }.
Операторы блока отвечали за дополнительный контроль работающей программы и использование манименеджмента, поэтому их удаление на стадии тестирования целесообразно. Депозит $5000 USD. Допустимые позиции: Long & Short. Используется генетический алгоритм, моделирование проводилось с использованием всех тиков (наиболее точный метод на основе всех наименьших доступных таймфремов для генерации каждого типа). Рабочий таймфрейм программы М15.
Моделирование проводилось на интервале с 01.01.2010 по 31.12.2012 г. Для полученных результатов приведены следующие поля:
· Проход
· Прибыль
· Всего сделок
· Прибыльность
· Просадка
· Просадка %
· Матожидание
· Параметры

Рисунок 5 – график оптимизации
Наилучшие значения: было найдено 10 вариантов, для которых прибыль составила $ при просадке 89.62%, прибыльность 3.13, математическое ожидание 23.65. Следует отметить, что значение просадки слишком велико для проведения реальных торгов с депозитом $5000, депозит следовало увеличить до $15000-$20000. Если работать с центовыми счетами, то, при вложенных $200 на счет ($1 реальный = $100 на счете), через три года можно было получить $1029, что оценивается, как достаточно хороший показатель. Значения полей: 153 393 89.62% lim_step=150 Op_step=190 period=160 n_orders=37 Lots=0.01 yes_Мах_Lots=0 Мах_Lots=20 MN=12345 klot=1 Yes_Friday=0 koef_martingale=1 maxerror=30 globaltakeprofit=0 globalloss=0 restart=1 test_only=0
Для депозита $5000 при достаточно агрессивной торговле и просадке 42.79% можно отметить получение прибыли $16286.61:3 38 42.79% lim_step=450 Op_step=140 period=110 n_orders=33 Lots=0.01 yes_Мах_Lots=0 Мах_Lots=20 MN=12345 klot=1 Yes_Friday=0 koef_martingale=1 maxerror=30 globaltakeprofit=0 globalloss=0 restart=1 test_only=0.
Наименьшая просадка для моделируемого диапазона составила 34.16%, прибыль $8341.11: 5 34.16% lim_step=350 Op_step=280 period=120 n_orders=3 Lots=0.01 yes_Мах_Lots=0 Мах_Lots=20 MN=12345 klot=1 Yes_Friday=0 koef_martingale=1 maxerror=30 globaltakeprofit=0 globalloss=0 restart=1 test_only=0.
Результаты моделирования показывают, что разработанная программа обладает хорошим потенциалом для получения прибыли, однако это возможно при наличии минимального депозита, который должен составлять минимум 15-20 тыс. долларов США, если торговля ведется на долларовых счетах. Для торговли на центовых счетах минимальный депозит $200 для агрессивной торговли с большими просадками, при депозите $500-$1000 величина просадки, отнесенная к размеру депозита вполне приемлема для торговли без слишком больших рисков. При работе с еще большим депозитом риск сводится к минимуму, но также уменьшается и уровень получаемой прибыли.
Текст программы Fx-Libra:
#property copyright "Anantchenko I. V., Tarasov I. O."
#property link "http://*****/"
// 20.01.2013 Fx-Libra ver. 1.0
// Программа предназначена для работы на таймфрейме H15, оптимизирована
// для торговли по паре GBPUSD.
// Программа работает с пятизначными котировками
string aiv = "FRX_";
extern double Lots = 0.01; // Начальное (стартовое) значение ордера
extern int yes_Мах_Lots=0; // 1 - задействовать ограничение на
// максимальный размер лота, 0 - нет
extern double Мах_Lots = 20; // Максимальный размер лота (если yes_Мах_Lots=1)
extern int lim_step = 100; // Шаг между ордерами
extern int Op_step = 120; // Отступ от скользящей средней
extern int period = 144; // Период скользящей средней
extern int MN = 12345; // Идентификационный номер (magic number)
extern int n_orders = 30; // Количество выставляемых ордеров
extern int klot=1; // Если 0, то лот фиксирован, если 1, то
//увеличивается для каждого последующего отложенного ордера в серии
extern int Yes_Friday=0; // 1 - открывать ордера в пятницу,
//0 - не открывать ордера в пятницу
extern double koef_martingale = 1; // если лот следующего ордера будет больше
// предыдущего, то значение этого коэффициента показывает,
// на какое значение будет домножаться добавляемое значение
extern int maxerror = 30; // Число попыток повтора открытия, закрытия, удаления
//или иного действия, которое закончилось неудачей
extern double globaltakeprofit=500; // Суммарная прибыль по ВСЕМ
//без исключения открытым ордерам, когда фиксируем прибыль
// Если 0, то опция не задействована.
extern double globalloss=-500; // Суммарный убыток по ВСЕМ без
//исключения открытым ордерам, когда фиксируем убыток
// Если 0, то опция не задействована.
//Если депозит 5000 и рискуем не более чем 10%, то устанавливаем -500
extern int restart = 1; // Автоматически "перезапускает" программу
//после фиксации по срабатыванию
// globaltakeprofit или globalloss
extern int test_only = 0; //Если значение равно 1, то отключаются
//все дополнительные проверки, в том числе ограничения globaltakeprofit
//и globalloss. Ускоряется время тестирования.
datetime tek_time; // Время открытия бара
int paramert = 0;
double Lot, Lot1;
int init() {
Lot=Lots;
return (0);
}
int deinit() {
return (0);
}
int start() {
int flag_globaltakeprofit=0;
int flag_globalloss=0;
int tiket;
int k;
bool REZ;
double tprofit=0;
int rez_del_order; // 0 - не удалось удалить ордер, 1 - ордер успешно удален
int oshibka;
if (globalloss>0) globalloss=-globalloss;
DrawLogo(); // Отображаем логотип
DrawStats(); // Выводим статистику
if (test_only==1) {
for (k= 0; k< OrdersTotal(); k++) {
OrderSelect(k, SELECT_BY_POS, MODE_TRADES);
tprofit=tprofit+OrderProfit() ;}
// ============= ФИКСИРУЕМ ПРИБЫЛЬ ПО ВСЕМ ОРДЕРАМ
if (tprofit>=globaltakeprofit && globaltakeprofit!=0 && tprofit!=0) flag_globaltakeprofit=1;
if (flag_globaltakeprofit==1) {
Comment("\n ФИКСИРУЕМ ПРИБЫЛЬ ПО ВСЕМ ОРДЕРАМ -->",tprofit);
Print(" ФИКСИРУЕМ ПРИБЫЛЬ ПО ВСЕМ ОРДЕРАМ -->",tprofit);
// Закрываем и удаляем все ордера
// Закрываем открытые
for (k=0; k< OrdersTotal(); k++) {
OrderSelect(k, SELECT_BY_POS, MODE_TRADES);
if (OrderType()==OP_BUY || OrderType()==OP_SELL )
{
tiket=OrderTicket();
Comment("\n Команда на закрытие ордера tiket=",tiket);
Print(" Команда на закрытие ордера tiket=",tiket);
if (OrderType() == OP_BUY) REZ=OrderClose(tiket, OrderLots(), Bid, 3, Blue);
else REZ=OrderClose(tiket, OrderLots(), Ask, 3, Red);
if(REZ==true){ Comment("\n Ордер tiket=",tiket," успешно закрыт");
Print(" Ордер tiket=",tiket," успешно закрыт");
}
}
// Удаляем отложенные
if (OrderType() > OP_SELL)
{ tiket=OrderTicket();
Comment("\n Команда на удаление ордера tiket=",tiket);
Print(" Команда на удаление ордера tiket=",tiket);
REZ=OrderDelete(tiket);
if(REZ==true){ Comment("\n Ордер tiket=",tiket," успешно удален");
Print(" Ордер tiket=",tiket," успешно удален");
} }
/* for */ }
Print("Зафиксирована общая прибыль ",globaltakeprofit," советник больше не торгует. Надо его закрыть и запустить снова.");
if (restart==1&&REZ==true){ flag_globaltakeprofit=0;
Print("Выполнен автоматический рестарт restart=",restart," Установлено значение флага flag_globaltakeprofit=0");
}
return(0);
//Если зафиксирован глобальный тейкпрофит, то советник больше не торгует. Надо его закрыть и запустить снова.
}
//============================================================
// ============= ФИКСИРУЕМ УБЫТОК ПО ВСЕМ ОРДЕРАМ
if (tprofit<=globalloss && globalloss!=0 && tprofit!=0) flag_globalloss=1;
if (flag_globalloss==1) {
Comment("\n ФИКСИРУЕМ УБЫТОК ПО ВСЕМ ОРДЕРАМ -->",tprofit);
Print(" ФИКСИРУЕМ УБЫТОК ПО ВСЕМ ОРДЕРАМ -->",tprofit);
// Закрываем и удаляем все ордера
// Закрываем открытые
for (k=0; k< OrdersTotal(); k++) {
OrderSelect(k, SELECT_BY_POS, MODE_TRADES);
if (OrderType()==OP_BUY || OrderType()==OP_SELL )
{ tiket=OrderTicket();
Comment("\n Команда на закрытие ордера tiket=",tiket);
Print(" Команда на закрытие ордера tiket=",tiket);
if (OrderType() == OP_BUY) REZ=OrderClose(tiket, OrderLots(), Bid, 3, Blue);
else REZ=OrderClose(tiket, OrderLots(), Ask, 3, Red);
if(REZ==true){ Comment("\n Ордер tiket=",tiket," успешно закрыт");
Print(" Ордер tiket=",tiket," успешно закрыт"); }
}
// Удаляем отложенные
if (OrderType() > OP_SELL)
{ tiket=OrderTicket();
Comment("\n Команда на удаление ордера tiket=",tiket);
Print(" Команда на удаление ордера tiket=",tiket);
REZ=OrderDelete(tiket);
if(REZ==true){ Comment("\n Ордер tiket=",tiket," успешно удален");
Print(" Ордер tiket=",tiket," успешно удален");
}
}
/* for */ }
Print("Зафиксирован общий убыток ",globalloss," советник больше не торгует. Надо его закрыть и запустить снова.");
if (restart==1&&REZ==true){ flag_globalloss=0;
Print("Выполнен автоматический рестарт restart=",restart," Установлено значение флага flag_globalloss=0");
}
return(0);
//Если зафиксирован общий убыток, то советник больше не торгует. Надо его закрыть и запустить снова.
}
//
//============================================================
}
if (Time[0] == tek_time) return (0);
tek_time = Time[0];
int n_orders_minus_1= OrdersTotal() - 1;
double indikator = iMA(Symbol(), 0, period, 0, MODE_SMA, PRICE_CLOSE, 1);
int count_open_orders = 0;
// Число открытых ордеров если значение функции OrderType() < OP_BUYLIMIT,
// то ордер открыт (SELL или BUY)
int count_errors = 0;
for (int i = n_orders_minus_1; i >= 0; i--) {
OrderSelect(i, SELECT_BY_POS);
if (OrderMagicNumber() == MN && OrderSymbol() == Symbol())
if (OrderType() < OP_BUYLIMIT) count_open_orders++;
}
if (count_open_orders == 0) {
for (i = n_orders_minus_1; i >= 0; i--) {
OrderSelect(i, SELECT_BY_POS);
while (count_errors <= maxerror) {
rez_del_order = OrderDelete(OrderTicket());
oshibka = GetLastError();
if (oshibka == 0) {
Print("Отложенный ордер ",OrderTicket()," успешно удален");
break;
}
Print("Не удается закрыть отложенный ордер ",OrderTicket()," по финансовому инструменту", Symbol(), ". Ошибка: ", GetLastError());
Sleep(500);
RefreshRates();
count_errors++;
} } }
bool flag2 = FALSE;
bool flag1 = FALSE;
double min_stoploss = MarketInfo(Symbol(), MODE_STOPLEVEL);
if (min_stoploss < 15.0) min_stoploss = 15;
if (Ask > indikator + Op_step * Point) flag1 = TRUE;
if (Bid < indikator - Op_step * Point) flag2 = TRUE;
double ld_40 = NormalizeDouble(indikator - Op_step * Point, Digits);
if (ld_40 > Bid - min_stoploss * Point) ld_40 = Bid - min_stoploss * Point;
oshibka = 0;
count_errors = 0;
if (flag2 && count_open_orders == 0) {
Lot1=Lots;
for (i = 0; i < n_orders; i++) {
while (true) {
if (klot==0) Lot=Lots; else {
if ((koef_martingale==1 || koef_martingale==0)&& (klot!=0)) Lot=Lots * (i + 1); else {Lot1=Lot1*koef_martingale ; Lot=Lot1;} }
if (yes_Мах_Lots==1 && Lot>Мах_Lots)Lot=Мах_Lots;
if ((DayOfWeek()!=5)||(DayOfWeek()==5 && Yes_Friday==1)) OrderSend(Symbol(), OP_BUYLIMIT, Lot, ld_40 - lim_step * Point * i, 2, 0, 0, "Fx-Libra ver 1.0", MN, 0, Blue);
oshibka = GetLastError();
if (oshibka == 0) {
Print("Ордер Buy Limit ",OrderTicket(),"успешно установлен");
break;
}
Print("Не удается установить ордер Buy Limit по финасовому инструменту", Symbol(), ". Ошибка: ", GetLastError());
Sleep(5000);
RefreshRates();
count_errors++;
if (count_errors <= maxerror) continue;
break;
} } }
double normaliz_indikator = NormalizeDouble(indikator + Op_step * Point, Digits);
if (normaliz_indikator < Ask + min_stoploss * Point) normaliz_indikator = Ask + min_stoploss * Point;
oshibka = 0;
count_errors = 0;
if (flag1 && count_open_orders == 0) {
Lot1=Lots;
for (i = 0; i < n_orders; i++) {
while (true) {
if (klot==0) Lot=Lots; else {
if ((koef_martingale==1 || koef_martingale==0)&& (klot!=0)) Lot=Lots * (i + 1); else {Lot1=Lot1*koef_martingale ; Lot=Lot1;} }
if (yes_Мах_Lots==1 && Lot>Мах_Lots)Lot=Мах_Lots;
if ((DayOfWeek()!=5)||(DayOfWeek()==5 && Yes_Friday==1)) OrderSend(Symbol(), OP_SELLLIMIT, Lot, normaliz_indikator + lim_step * Point * i, 2, 0, 0, "Fx-Libra ver 1.0", MN, 0, Red);
oshibka = GetLastError();
if (oshibka == 0) {
Print("Ордер Sell Limit ", OrderTicket(), " успешно установлен");
break;
}
Print("Не удается установить ордер Sell Limit по финансовому инструменту", Symbol(), " Номер ошибки: ", GetLastError());
Sleep(5000);
RefreshRates();
count_errors++;
if (count_errors <= maxerror) continue;
Print("Не удается установить ордер Sell Limit по финансовому инструменту", Symbol(), " Номер ошибки: ", GetLastError());
break;
}
}
}
bool flag = FALSE; // логическая переменная
double price_open_order = 1000000;
double open_price = 0;
double tek_Lots = Lots;
if (count_open_orders != paramert) {
if (count_open_orders > paramert) {
paramert = count_open_orders;
flag = TRUE;
}
if (count_open_orders < paramert) paramert = count_open_orders;
}
if (flag == TRUE) {
for (i = n_orders_minus_1; i >= 0; i--) {
OrderSelect(i, SELECT_BY_POS);
if (OrderMagicNumber() == MN && OrderSymbol() == Symbol()) {
if (OrderType() == OP_BUYLIMIT) {
if (OrderOpenPrice() < price_open_order) {
price_open_order = OrderOpenPrice();
tek_Lots = OrderLots();
}
}
if (OrderType() == OP_SELLLIMIT) {
if (OrderOpenPrice() > open_price) {
open_price = OrderOpenPrice();
tek_Lots = OrderLots(); // Функция OrderLots возвращает
// количество лотов для выбранного ордера.
}
}
}
}
oshibka = 0;
count_errors = 0;
if (price_open_order != 1000000.0) {
while (true) {
if (klot==0) Lot=Lots; else Lot=tek_Lots + Lots;
if (yes_Мах_Lots==1 && Lot>Мах_Lots)Lot=Мах_Lots;
if ((DayOfWeek()!=5)||(DayOfWeek()==5 && Yes_Friday==1)) OrderSend(Symbol(), OP_BUYLIMIT, Lot, NormalizeDouble(price_open_order, Digits) - lim_step * Point, 2, 0, 0, "Fx-Libra ver 1.0", MN, 0, Blue);
oshibka = GetLastError(); if (oshibka == 0) Print("Ордер Buy Limit ", OrderTicket(), " успешно установлен");
else {
Print("Не удается установить ордер Buy Limit по финансовому инструменту ", Symbol(), " Ошибка: ", GetLastError());
Sleep(5000);
RefreshRates();
count_errors++;
if (count_errors <= maxerror) continue;
}
break;
}
}
oshibka = 0;
count_errors = 0;
if (open_price!= 0.0) {
while (true) {
if (klot==0) Lot=Lots; else Lot=tek_Lots + Lots;
if (yes_Мах_Lots==1 && Lot>Мах_Lots)Lot=Мах_Lots;
if ((DayOfWeek()!=5)||(DayOfWeek()==5 && Yes_Friday==1)) OrderSend(Symbol(), OP_SELLLIMIT, Lot, NormalizeDouble(open_price, Digits) + lim_step * Point, 2, 0, 0, "Fx-Libra ver 1.0", MN, 0, Red);
oshibka = GetLastError();
if (oshibka == 0) Print("Ордер Sell Limit ", OrderTicket(), " успешно установлен");
else {
Print("Не удается установить ордер Sell Limit по финансовому инструменту ", Symbol(), " Ошибка: ", GetLastError());
Sleep(5000);
RefreshRates();
count_errors++;
if (count_errors <= maxerror) continue;
}
break;
}
}
}
double kuput_1_lot = MarketInfo(Symbol(), MODE_MARGINREQUIRED);
n_orders_minus_1= OrdersTotal() - 1;
double summa_lotov = 0;
double pribil = 0;
if (count_open_orders != 0) {
for (i = n_orders_minus_1; i >= 0; i--) {
OrderSelect(i, SELECT_BY_POS);
if (OrderMagicNumber() == MN && OrderSymbol() == Symbol()) {
if (OrderType() < OP_BUYLIMIT) summa_lotov += OrderLots();
pribil += OrderProfit() + OrderSwap();
}
}
if (pribil >= kuput_1_lot * summa_lotov) {
for (i = n_orders_minus_1; i >= 0; i--) {
OrderSelect(i, SELECT_BY_POS);
if (OrderMagicNumber() == MN && OrderSymbol() == Symbol()) {
if (OrderType() == OP_BUY) CloseBuy();
if (OrderType() == OP_SELL) CloseSell();
if (OrderType() > OP_SELL) CloseLimit();
}
}
}
}
if (DayOfWeek()==5&&Yes_Friday==0)
Comment("\n\n\n\n\n\n\n\n"
+ "\n"
+ "\nСегодня ПЯТНИЦА! По пятницам ордеров не открываем (если значение Yes_Friday равно нулю) "
+ "\nСумарный Лот " + DoubleToStr(summa_lotov, 2)
+ "\nШаг между ордерами " + lim_step + " пунктов"
+ "\nОтступ от скользящей средней " + Op_step + " пунктов"
+ "\nПериод скользящей средней " + period
+ "\nСвободная маржа счета = " + DoubleToStr(AccountFreeMargin(),2)
+ "\nБаланс счета = " + DoubleToStr(AccountBalance(),2)
+ "\nЗначение незафиксированной прибыли (убытка)"
+ "\nдля текущего счета в базовой валюте " + DoubleToStr(AccountProfit(),3)
+ "\nЗначение globaltakeprofit="+globaltakeprofit
+ "\nЗначение globalloss="+globalloss
+ "\n");
else
Comment("\n\n\n\n\n\n\n\n"
+ "\n------"
+ "\nСумарный Лот " + DoubleToStr(summa_lotov, 2)
+ "\nШаг между ордерами " + lim_step + " пунктов"
+ "\nОтступ от скользящей средней " + Op_step + " пунктов"
+ "\nПериод скользящей средней " + period
+ "\nСвободная маржа счета = " + DoubleToStr(AccountFreeMargin(),2)
+ "\nБаланс счета = " + DoubleToStr(AccountBalance(),2)
+ "\nЗначение незафиксированной прибыли (убытка)"
+ "\nдля текущего счета в базовой валюте " + DoubleToStr(AccountProfit(),3)
+ "\nЗначение globaltakeprofit="+DoubleToStr(globaltakeprofit, 2)
+ "\nЗначение globalloss="+DoubleToStr(globalloss, 2)
+ "\n------");
return (0);
}
void CloseBuy() {
int oshibka;
int povtor = 0;
while (true) {
OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID), Digits), 2, White);
oshibka = GetLastError();
if (oshibka == 0) {
Print("Ордер Buy", OrderTicket(), " закрыт");
return;
}
Print("Не удается закрыть ордер Buy ", OrderTicket(), "по финансовому инструменту ", Symbol(), " Ошибка: ", GetLastError());
Sleep(500);
RefreshRates();
povtor++;
if (povtor <= maxerror) continue;
break;
}
}
void CloseSell() {
int oshibka;
int povtor = 0;
while (true) {
OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK), Digits), 2, Red);
oshibka = GetLastError();
if (oshibka == 0) {
Print("Ордер Sell ", OrderTicket(), "закрыт");
return;
}
Print("Не удается закрыть ордер Sell ", OrderTicket(), " по финансовому инструменту ", Symbol(), " Ошибка: ", GetLastError());
Sleep(500);
RefreshRates();
povtor++;
if (povtor <= maxerror) continue;
break;
} }
void CloseLimit() {
int oshibka;
int del_order;
int povtor = 0;
while (true) {
del_order = OrderDelete(OrderTicket());
oshibka = GetLastError();
if (oshibka == 0) {
Print("Limit Order ", OrderTicket(), " закрыт");
return;
}
Print("Не удается закрыть Limit Order по финансовому инструменту ", Symbol(), " Ошибка: ", GetLastError());
Sleep(500);
RefreshRates();
povtor++;
if (povtor <= maxerror) continue;
break;
} }
void DrawLogo() {
string l_name_0 = aiv + "L_1";
if (ObjectFind(l_name_0) == -1) {
ObjectCreate(l_name_0, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_0, OBJPROP_CORNER, 0);
ObjectSet(l_name_0, OBJPROP_XDISTANCE, 390);
ObjectSet(l_name_0, OBJPROP_YDISTANCE, 10);
}
ObjectSetText(l_name_0, " FX-LIBRA ", 28, "Times New Roman",Yellow);
l_name_0 = aiv + "L_2";
if (ObjectFind(l_name_0) == -1) {
ObjectCreate(l_name_0, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_0, OBJPROP_CORNER, 0);
ObjectSet(l_name_0, OBJPROP_XDISTANCE, 423);
ObjectSet(l_name_0, OBJPROP_YDISTANCE, 70);
}
ObjectSetText(l_name_0, "*****", 20, "Times New Roman", Yellow);
l_name_0 = aiv + "L_3";
if (ObjectFind(l_name_0) == -1) {
ObjectSet(l_name_0, OBJPROP_CORNER, 0);
ObjectSet(l_name_0, OBJPROP_XDISTANCE, 423);
ObjectSet(l_name_0, OBJPROP_YDISTANCE, 60);
}
}
//--
void DrawStats() {
double vilichina_profita = GetProfitForDay(0);
string l_name_8 = aiv + "1";
if (ObjectFind(l_name_8) == -1) {
ObjectCreate(l_name_8, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_8, OBJPROP_CORNER, 0);
ObjectSet(l_name_8, OBJPROP_XDISTANCE, 10);
ObjectSet(l_name_8, OBJPROP_YDISTANCE, 15);
}
ObjectSetText(l_name_8, "Прибыль сегодня: " + DoubleToStr(vilichina_profita, 2), 14, "Times New Roman", Red);
vilichina_profita = GetProfitForDay(1);
l_name_8 = aiv + "2";
if (ObjectFind(l_name_8) == -1) {
ObjectCreate(l_name_8, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_8, OBJPROP_CORNER, 0);
ObjectSet(l_name_8, OBJPROP_XDISTANCE, 10);
ObjectSet(l_name_8, OBJPROP_YDISTANCE, 40);
}
//-------//
ObjectSetText(l_name_8, "Прибыль вчера: " + DoubleToStr(vilichina_profita, 2), 14, "Times New Roman", Blue);
vilichina_profita = GetProfitForDay(2);
l_name_8 = aiv + "3";
if (ObjectFind(l_name_8) == -1) {
ObjectCreate(l_name_8, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_8, OBJPROP_CORNER, 0);
ObjectSet(l_name_8, OBJPROP_XDISTANCE, 10);
ObjectSet(l_name_8, OBJPROP_YDISTANCE, 60);
}
//-------//
ObjectSetText(l_name_8, "Прибыль за 2 дня: " + DoubleToStr(vilichina_profita, 2), 14, "Times New Roman", Red);
vilichina_profita = GetProfitForDay(1)+GetProfitForDay(2);
l_name_8 = aiv + "4";
if (ObjectFind(l_name_8) == -1) {
ObjectCreate(l_name_8, OBJ_LABEL, 0, 0, 0);
ObjectSet(l_name_8, OBJPROP_CORNER, 0);
ObjectSet(l_name_8, OBJPROP_XDISTANCE, 10);
ObjectSet(l_name_8, OBJPROP_YDISTANCE, 85);
}
ObjectSetText(l_name_8, "Баланс: " + DoubleToStr(AccountBalance(), 2), 14, "Times New Roman",Chartreuse);
//-------//
}
//
double GetProfitForDay(int ai_0) {
double ld_ret_4 = 0;
for (int l_pos_12 = 0; l_pos_12 < OrdersHistoryTotal(); l_pos_12++) {
if (!(OrderSelect(l_pos_12, SELECT_BY_POS, MODE_HISTORY))) break;
if (OrderSymbol() == Symbol())
if (OrderCloseTime() >= iTime(Symbol(), PERIOD_D1, ai_0) && OrderCloseTime() < iTime(Symbol(), PERIOD_D1, ai_0) + 86400) ld_ret_4 = ld_ret_4 + OrderProfit() + OrderCommission() + OrderSwap();
}
return (ld_ret_4);
}
2. Используемые технические средства
Программа работает в операционной системе типа Microsoft Windows XP/2003/Vista/2008/7 под управлением прикладной пользовательской программы MT4 (MetaTrader 4 Client Termina). MetaTrader 4 Client Terminal - инструмент трейдера, позволяющий проводить технический анализ, торговые операции и работать с экспертами. Тестирование проводилось для сборки Alpari NZ MT4 ver: 4.00 build 451. Клиентский терминал может работать под управлением операционных систем Microsoft Windows XP/2003/Vista/2008/7. Также для работы необходим процессор с поддержкой набора инструкций SSE2. Остальные требования к аппаратной части ограничиваются требованиями к операционным системам.
3. Специальные условия и требования организационного, технического и технологического характера
Для установки программы необходимо поместить исходный файл программы fx-libra. mq4 и/или его скомпилированный вариант fx-libra. ex4 в папку \experts терминала MT4. Если скомпилированный файл fx-libra. ex4 отсутствует, то он будет создан автоматически при запуске советника fx-libra. mq4. После запуска терминала MT4, следует в панели Навигатор выбрать советник fx-libra и перенести его на график. Должен быть установлен режим, разрешающий советникам торговать, выбран пятнадцати минутный таймфрейм (М15) для графика валютной пары GBPUSD. В окне настроек советника fx-libra следует установить настройки, с которыми будет осуществляться торговля, и нажать кнопку ОК.
4. Условия передачи документации на разработку или условия ее продажи
Программа Fx-Libra может бесплатно использоваться для некоммерческих (учебных) целей. Для использования программы для торговли на реальных счетах следует обратиться к авторам программы по электронному адресу *****@***ru или воспользовавшись альтернативными вариантами контактов на странице http://www. *****/about. Разработчиками выполняется оптимизация параметров для торговли на других валютных парах, планируется разработка модифицированной версии программы, которая будет включать в себя обновляемую dll библиотеку с оптимальными значениями параметров торговли для выбранной валютной пары.


