Наводимо порядок і додаємо tralling stop

Спонсор цієї статі - сайт Richinvest.biz - торгуйте бінарніми опціонами з максимальним прибутком!

Дана стаття є продовженням раніше розпочатого циклу про створення торгового експерта (див. 61 і 63 номери журналу ForTrader. Org). На жаль, як мене, так і багатьох читачів, робота в даному напрямку була припинена на декілька місяців. Причин для того було досить багато, але головне, що я знову повертаюся до цієї роботи.

Підсумки виконаної роботи

Той короткий період тестування, який мав місце бути, зміг продемонструвати деяку живучість ідеї. Прибуток склав незначну величину, проте більш важливо те, що не було отримано збиток. У цій статті я постараюся зробити деякі дії для поліпшення результативності роботи програми. Але для початку я спробую уточнити деякі незрозумілі місця в коді, а також виправити незначні помилки.

Помилки і неясні місця в коді експрта

Рядок 18 коду:
Pause_Of_Trade_Try = 2; // пауза між спробами відкриття ордера (в секундах)

Тут пауза вказується не в секундах, а в десятих частках секунди, т. Е. 2 ​​= 0. 2 секунди.

Рядки 118.. 119 (і аналогічний код далі в роботі):
return (OrderTicket ());
break; // виходимо з циклу

Тут може бути не зовсім зрозуміло, для чого варто break , адже ми вже вийшли з циклу, повернувши значення функції, а значить, цей оператор не виконується.Це скоріше просто моя звичка, всюди, де потрібно виходити з циклу, ставити оператор break. Але, якщо мені не зраджує пам'ять, я стикався з мовами програмування, де цикл залишиться активним без break, навіть після return. Ну і все програмісти знають, що, наприклад, в switch відбувається «провалювання» на наступний оператор, якщо не поставити breal в мові C. Ставити його конкретно тут зовсім не обов'язково .

Рядок 169 (і тіло функції sl):
double sl (int sl_value, int type, string symb = "NONE», int rmode = 1) {

Тут може бути не зовсім зрозуміло, навіщо потрібен параметр rmode і чому в залежності від його значення, функція вважає ціни SL для покупок або від ціни Ask (при значенні 1), або від ціни Bid (при значенні 2), і для продажу або від Bid, або від Ask, відповідно.

Справа в тому, що часто виникають суперечки, від якої ж ціни потрібно вважати ціну StopLoss . Є думка, що при отриманні стопа, ми повинні отримувати рівно те значення збитку, яке чекаємо (т. Е. Ставимо в параметрі SL = 100 і отримуємо по стопу 100 пунктів збитку). А є думка, що потрібно вважати стоп так, щоб захоплювати спред , це актуально, коли спред не дозволить виставити стоп на вказаній відстані. У другому випадку ми отримуємо стоп, рівний 100+ пунктів.

Я частіше використовую перший варіант, і саме для такого варіанту і працює функція при rmode = 1 (т. Е. За замовчуванням). Введенням цього параметра я демонструю, що в курсі обох точок зору, що в цілому не нав'язую жодну з них (якщо ви прихильник другого варіанту, просто поміняйте 1 на 2 в коді), хоча особисто я використовую у своїй роботі саме перший варіант.

Решта ділянок коду мені бачаться досить логічними і «прозорими», але, швидше за все, в перспективі я буду пояснювати і їх.

Нововведення в торговий експерт

Перший результат, хоч і за короткий час, отриманий. Говорити про зміну / оптимізації алгоритму пошуку торгового сигналу поки рано. А тому додамо пару нових функцій. Перша з них - трейлинг стоп . Для цього я візьму стала вже стандартною функцію для багатьох своїх роботів, і трохи зміню її (щоб було можна використовувати одночасно на різних символах). Функція має кілька вхідних параметрів, які в коді представлені як:

// + ------------------------ +
// + трейлинг-стоп + extern bool UseTrailing = true; // включення / вимикання T-SL
extern int TrailingStop = 50; // Фіксований розмір трала
extern int TrailingStep = 1; // Крок трала
// +
трейлинг-стоп + // + ------------------------ +
Функція для роботи на поточному символі виглядає так:

// + ------------------------------- -------- +

// |
трейлинг стоп лосс | void T_SL () {
if (! UseTrailing) return;
int i = 0;
for (i = 0; i
if (! (OrderSelect (i, SELECT_BY_POS, MODE_TRADES))) continue; if (OrderSymbol ()! = Symbol () || OrderMagicNumber ()! = Magic_Number ) continue;
if (OrderType () == OP_BUY) {

if (NormalizeDouble (Bid-OrderOpenPrice (), Digits)> NormalizeDouble (TrailingStop * Point, Digits)) {
if (NormalizeDouble (OrderStopLoss (), Digits)
OrderModify (OrderTicket (), OrderOpenPrice (), NormalizeDouble (Bid-TrailingStop * Point, Digits), OrderTakeProfit (), 0, CLR_NONE); } // end if (NormalizeDouble (Bid -OrderOpenPrice (), Digits)> NormalizeDouble (TrailingStop * Point, Digits))
} // end if (OrderType () == OP_BUY)
if (OrderType () == OP_SELL) {

if (NormalizeDouble (OrderOpenPrice () - Ask, Digits)> NormalizeDouble (TrailingStop * Point, Digits)) {
if (NormalizeDouble (OrderStopLoss (), Digits)> NormalizeDouble (Ask + (TrailingStop + TrailingStep-1) * Point, Digits ))
OrderModify (OrderTicket (), OrderOpenPrice (), NormalizeDouble (Ask + TrailingStop * Point, Digits), OrderTakeProfit (), 0, CLR_NONE);
} / / End if (NormalizeDouble (OrderOpenPrice () - Ask, Digits)> NormalizeDouble (TrailingStop * Point, Digits))
} // end if (OrderType () == OP_SELL)
} // end for (i = 0; i
} // end void T_SL () // |
трейлинг стоп лосс | // + ---------------- ----------------------- +
Для нашого робота її потрібно привести до виду, при якому вона зможе обробляти всі угоди (з заданим магічним числом) всіх інструментів:

// + --------------------------------------- + // |

трейлинг стоп лосс
| void T_SL () { if (!UseTrailing) return;
string symb = »»;
int i = 0;
double ask = 0. 0, bid = 0. 0, dig = 0. 0, pp = 0. 0;
for (i = 0; i

if (! (OrderSelect (i, SELECT_BY_POS, MODE_TRADES))) continue;
if (OrderMagicNumber ()! = Magic_Number) continue; symb = OrderSymbol ( );
pp = MarketInfo (symb, MODE_POINT);
dig = MarketInfo (symb, MODE_DIGITS);
ask = MarketInfo (symb, MODE_ASK);
bid = MarketInfo (symb, MODE_BID);
if (OrderType () == OP_BUY) {
if (NormalizeDouble (bid-OrderOpenPrice (), dig)> NormalizeDouble (TrailingStop * pp, dig)) {
if (NormalizeDouble (OrderStopLoss (), dig)
OrderModify (OrderTicket (), OrderOpenPrice (), NormalizeDouble (bid-TrailingStop * pp, dig), OrderTakeProfit (), 0, CLR_NONE);
} // end if (NormalizeDouble (Bid-OrderOpenPrice ( ), Digits)> NormalizeDouble (TrailingStop * Point, Digits)) } // end if (OrderType () == OP_BUY)
if (OrderType () == OP_SELL) {
if (NormalizeDouble ( OrderOpenPrice () - ask, dig)> NormalizeDouble (TrailingStop * pp, dig)) {

if (NormalizeDouble (OrderStopLoss (), dig)> NormalizeDouble (ask + (TrailingStop + TrailingStep-1) * pp, dig)) OrderModify (OrderTicket (), OrderOpenPrice (), NormalizeDouble (ask + TrailingStop * pp, dig), OrderTakeProfit (), 0, CLR_NONE);
} // end if (NormalizeDouble (OrderOpenPrice () - Ask, Digits)> NormalizeDouble (TrailingStop * Point, Digits))
} // end if (OrderType () == OP_SELL)
} / / end for (i = 0; i
} // end void T_SL ()
// |
трейлинг стоп лосс |
// + -------- ------------------------------- + Після цього залишається тільки помістити виклик функції всередину функції start () (див. в кінцевому варіанті). Друга функція, яка може виявитися корисною, і яку я вирішив включити в робота -
подача звукового сигналу при відкритті угоди торговим експертом

. Це буде зовсім маленьке доповнення, так що описувати детально її не буду, посмію реть повний код робота ви можете тут.

Висновок У наступній версії експерта

з'являться більш цікаві, ніж сьогодні, функції. Вони будуть націлені на контроль ризиків та управління обсягами торгових операцій, ну а поки постежимо . Але нам покаже ця версія.