Читать книгу 10 роботов для автоматической торговли на Форекс - - Страница 1

Робот 1: «Следователь за трендом» (Trend Follower) – MQL5 Код

Оглавление

Вот полный код советника для MetaTrader 5, реализующий стратегию следования за трендом:


```mql5

//+–+

//| TrendFollower.mq5 |

//| Автор: Алготрейдинг Книга |

//| https://example.com |

//+–+

#property copyright "Алготрейдинг Книга"

#property link "https://example.com"

#property version "1.00"


//+–+

//| Входные параметры советника |

//+–+

input double LotSize = 0.1; // Размер лота

input int FastMAPeriod = 50; // Период быстрой MA

input int SlowMAPeriod = 200; // Период медленной MA

input int ADXPeriod = 14; // Период ADX

input double ADXThreshold = 25.0; // Пороговое значение ADX для силы тренда

input int StopLoss = 200; // Стоп-лосс в пунктах

input int TakeProfit = 400; // Тейк-профит в пунктах

input bool UseTrailingStop = false; // Использовать трейлинг-стоп

input int TrailingStop = 100; // Размер трейлинг-стопа в пунктах

input int MagicNumber = 123456; // Магический номер для идентификации ордеров

input string OrderComment = "TrendFollower"; // Комментарий к ордерам


//+–+

//| Глобальные переменные |

//+–+

int fastMAHandle; // Хэндл для быстрой MA

int slowMAHandle; // Хэндл для медленной MA

int adxHandle; // Хэндл для ADX


double prevFastMA = 0; // Значение быстрой MA на предыдущем баре

double prevSlowMA = 0; // Значение медленной MA на предыдущем баре


//+–+

//| Функция инициализации советника |

//+–+

int OnInit()

{

// Проверка входных параметров

if(FastMAPeriod >= SlowMAPeriod)

{

Alert("Ошибка: Период быстрой MA должен быть меньше периода медленной MA");

return INIT_PARAMETERS_INCORRECT;

}


if(LotSize <= 0 || LotSize > 100)

{

Alert("Ошибка: Неверный размер лота");

return INIT_PARAMETERS_INCORRECT;

}


// Создание хэндлов для индикаторов

fastMAHandle = iMA(_Symbol, _Period, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

slowMAHandle = iMA(_Symbol, _Period, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);

adxHandle = iADX(_Symbol, _Period, ADXPeriod);


// Проверка создания хэндлов

if(fastMAHandle == INVALID_HANDLE || slowMAHandle == INVALID_HANDLE || adxHandle == INVALID_HANDLE)

{

Alert("Ошибка создания индикаторов");

return INIT_FAILED;

}


// Получение начальных значений индикаторов

double fastMA[1], slowMA[1];

if(CopyBuffer(fastMAHandle, 0, 1, 1, fastMA) < 1 || CopyBuffer(slowMAHandle, 0, 1, 1, slowMA) < 1)

{

Alert("Ошибка копирования данных индикаторов");

return INIT_FAILED;

}


prevFastMA = fastMA[0];

prevSlowMA = slowMA[0];


Print("Советник TrendFollower успешно инициализирован");

return INIT_SUCCEEDED;

}


//+–+

//| Функция деинициализации советника |

//+–+

void OnDeinit(const int reason)

{

// Освобождение хэндлов индикаторов

if(fastMAHandle != INVALID_HANDLE)

IndicatorRelease(fastMAHandle);

if(slowMAHandle != INVALID_HANDLE)

IndicatorRelease(slowMAHandle);

if(adxHandle != INVALID_HANDLE)

IndicatorRelease(adxHandle);


Print("Советник деинициализирован, причина: ", reason);

}


//+–+

//| Функция обработки тиков |

//+–+

void OnTick()

{

// Проверяем, есть ли уже открытые позиции этим советником

if(PositionsTotal() > 0)

{

CheckForClose(); // Проверяем условия для закрытия

ManageTrailingStop(); // Управляем трейлинг-стопом

return;

}


// Проверяем условия для открытия новой позиции

CheckForOpen();

}


//+–+

//| Проверка условий для открытия позиции |

//+–+

void CheckForOpen()

{

// Получаем значения индикаторов на текущем и предыдущем барах

double fastMA[2], slowMA[2], adxValue[2];


if(CopyBuffer(fastMAHandle, 0, 0, 2, fastMA) < 2) return;

if(CopyBuffer(slowMAHandle, 0, 0, 2, slowMA) < 2) return;


// Получаем значение линии ADX (индекс направленного движения)

if(CopyBuffer(adxHandle, 0, 0, 2, adxValue) < 2) return;


// Проверяем условия для BUY (покупки)

// 1. Быстрая MA пересекла медленную MA снизу вверх

// 2. ADX выше порогового значения (сильный тренд)

if(fastMA[1] <= slowMA[1] && fastMA[0] > slowMA[0] && adxValue[0] > ADXThreshold)

{

OpenPosition(ORDER_TYPE_BUY);

}

// Проверяем условия для SELL (продажи)

// 1. Быстрая MA пересекла медленную MA сверху вниз

// 2. ADX выше порогового значения (сильный тренд)

else if(fastMA[1] >= slowMA[1] && fastMA[0] < slowMA[0] && adxValue[0] > ADXThreshold)

{

OpenPosition(ORDER_TYPE_SELL);

}


// Сохраняем текущие значения для следующего сравнения

prevFastMA = fastMA[0];

prevSlowMA = slowMA[0];

}


//+–+

//| Открытие позиции |

//+–+

void OpenPosition(ENUM_ORDER_TYPE orderType)

{

// Подготовка данных для торгового запроса

MqlTradeRequest request;

MqlTradeResult result;

ZeroMemory(request);

ZeroMemory(result);


// Установка символа

request.symbol = _Symbol;

request.volume = LotSize;

request.magic = MagicNumber;

request.comment = OrderComment;


// Установка типа ордера

request.type = orderType;


// Расчет цены входа

if(orderType == ORDER_TYPE_BUY)

{

request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

request.sl = request.price – StopLoss * _Point;

request.tp = request.price + TakeProfit * _Point;

}

else if(orderType == ORDER_TYPE_SELL)

{

request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

request.sl = request.price + StopLoss * _Point;

request.tp = request.price – TakeProfit * _Point;

}


// Установка отклонения от цены

request.deviation = 10;

request.type_filling = ORDER_FILLING_FOK;


// Отправка торгового запроса

if(OrderSend(request, result))

{

if(result.retcode == TRADE_RETCODE_DONE)

{

Print("Позиция открыта успешно. Тикет: ", result.order);

}

else

{

Print("Ошибка открытия позиции. Код: ", result.retcode, " Комментарий: ", result.comment);

}

}

else

{

Print("Ошибка OrderSend. Код ошибки: ", GetLastError());

}

}


//+–+

//| Проверка условий для закрытия позиции |

//+–+

void CheckForClose()

{

// Получаем значения индикаторов на текущем баре

double fastMA[1], slowMA[1];


if(CopyBuffer(fastMAHandle, 0, 0, 1, fastMA) < 1) return;

if(CopyBuffer(slowMAHandle, 0, 0, 1, slowMA) < 1) return;


// Проверяем все открытые позиции

for(int i = PositionsTotal() – 1; i >= 0; i–)

{

if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)

{

long positionType = PositionGetInteger(POSITION_TYPE);


// Закрываем BUY позицию если быстрая MA пересекла медленную сверху вниз

if(positionType == POSITION_TYPE_BUY && fastMA[0] < slowMA[0])

{

ClosePosition(i);

}

// Закрываем SELL позицию если быстрая MA пересекла медленную снизу вверх

else if(positionType == POSITION_TYPE_SELL && fastMA[0] > slowMA[0])

{

ClosePosition(i);

}

}

}

}


//+–+

//| Закрытие позиции |

//+–+

void ClosePosition(int positionIndex)

{

// Получаем информацию о позиции

ulong ticket = PositionGetTicket(positionIndex);

if(ticket <= 0) return;


// Подготовка торгового запроса

MqlTradeRequest request;

MqlTradeResult result;

ZeroMemory(request);

ZeroMemory(result);


request.action = TRADE_ACTION_DEAL;

request.position = ticket;

request.symbol = _Symbol;

request.volume = PositionGetDouble(POSITION_VOLUME);

request.magic = MagicNumber;

request.comment = "Close by signal";


// Установка цены закрытия

if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

{

request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

request.type = ORDER_TYPE_SELL;

}

else

{

request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

request.type = ORDER_TYPE_BUY;

}


request.deviation = 10;

request.type_filling = ORDER_FILLING_FOK;


// Отправка запроса на закрытие

if(OrderSend(request, result))

{

if(result.retcode == TRADE_RETCODE_DONE)

{

Print("Позиция закрыта успешно. Тикет: ", result.order);

}

else

{

Print("Ошибка закрытия позиции. Код: ", result.retcode);

}

}

}


//+–+

//| Управление трейлинг-стопом |

//+–+

void ManageTrailingStop()

{

if(!UseTrailingStop) return;


for(int i = PositionsTotal() – 1; i >= 0; i–)

{

if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)

{

ulong ticket = PositionGetTicket(i);

if(ticket <= 0) continue;


double currentSL = PositionGetDouble(POSITION_SL);

double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);

double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);

long positionType = PositionGetInteger(POSITION_TYPE);


// Для длинной позиции (BUY)

if(positionType == POSITION_TYPE_BUY)

{

double newSL = currentPrice – TrailingStop * _Point;

if(newSL > currentSL && newSL > openPrice)

{

ModifyStopLoss(ticket, newSL);

}

}

// Для короткой позиции (SELL)

else if(positionType == POSITION_TYPE_SELL)

{

double newSL = currentPrice + TrailingStop * _Point;

if(newSL < currentSL && newSL < openPrice)

{

ModifyStopLoss(ticket, newSL);

}

}

}

}

}


//+–+

//| Модификация стоп-лосса |

//+–+

void ModifyStopLoss(ulong ticket, double newStopLoss)

{

MqlTradeRequest request;

MqlTradeResult result;

ZeroMemory(request);

ZeroMemory(result);


request.action = TRADE_ACTION_SLTP;

request.position = ticket;

request.symbol = _Symbol;

request.sl = newStopLoss;

request.magic = MagicNumber;


// Сохраняем текущий тейк-профит

request.tp = PositionGetDouble(POSITION_TP);


if(OrderSend(request, result))

{

if(result.retcode == TRADE_RETCODE_DONE)

{

Print("Стоп-лосс модифицирован. Новый SL: ", newStopLoss);

}

}

}


//+–+

//| Функция для логов |

//+–+

void PrintStatus()

{

double fastMA[1], slowMA[1], adxValue[1];


if(CopyBuffer(fastMAHandle, 0, 0, 1, fastMA) < 1) return;

if(CopyBuffer(slowMAHandle, 0, 0, 1, slowMA) < 1) return;

if(CopyBuffer(adxHandle, 0, 0, 1, adxValue) < 1) return;


Print("Текущие значения: FastMA=", fastMA[0], " SlowMA=", slowMA[0], " ADX=", adxValue[0]);

}

```


Инструкция по установке и использованию:


1. Установка советника:


· Сохраните код в файл TrendFollower.mq5

· Поместите файл в папку MQL5/Experts/ вашего терминала MetaTrader 5

· Перезапустите MetaTrader 5 или обновите список экспертов (Навигатор -> Эксперты -> Обновить)


2. Настройка параметров:


Основные параметры:


· LotSize = 0.1 – Размер лота (рекомендуется начинать с 0.01)

· FastMAPeriod = 50 – Период быстрой скользящей средней

· SlowMAPeriod = 200 – Период медленной скользящей средней

· ADXPeriod = 14 – Период индикатора ADX

· ADXThreshold = 25.0 – Минимальное значение ADX для силы тренда

· StopLoss = 200 – Стоп-лосс в пунктах

· TakeProfit = 400 – Тейк-профит в пунктах


Дополнительные параметры:


· UseTrailingStop = false – Включить трейлинг-стоп

· TrailingStop = 100 – Размер трейлинг-стопа в пунктах

· MagicNumber = 123456 – Уникальный идентификатор ордеров


3. Рекомендации по использованию:


Оптимизация параметров:


```mql5

// Для разных таймфреймов рекомендуются разные настройки:


// Дневной график (D1):

FastMAPeriod = 20

SlowMAPeriod = 50

StopLoss = 300

TakeProfit = 600


// Четырехчасовой график (H4):

FastMAPeriod = 14

SlowMAPeriod = 50

StopLoss = 150

TakeProfit = 300


// Часовой график (H1):

FastMAPeriod = 10

SlowMAPeriod = 30

StopLoss = 100

TakeProfit = 200

```


Дополнительные улучшения стратегии:


1. Фильтр волатильности:


```mql5

// Добавить в CheckForOpen():

double atrValue = iATR(_Symbol, _Period, 14, 0);

if(atrValue > 0.005) // Пример фильтра по ATR

{

// Торговать только при достаточной волатильности

}

```


1. Фильтр по времени:


```mql5

// Не торговать во время выхода важных новостей

bool IsTradingTime()

{

MqlDateTime time;

TimeCurrent(time);

// Не торговать с 13:00 до 15:00 (пример)

if(time.hour >= 13 && time.hour < 15)

return false;

return true;

}

```


1. Управление капиталом:


```mql5

// Вместо фиксированного лота использовать процент от депозита

double riskPercent = 2.0; // Риск 2% от депозита

double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100;

double lotSize = riskAmount / (StopLoss * _Point * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE));

```


4. Важные предупреждения:


1. Всегда тестируйте на демо-счете перед использованием на реальных деньгах

2. Адаптируйте параметры под конкретную валютную пару и таймфрейм

3. Мониторьте работу советника, особенно в первые недели торговли

4. Учитывайте спреды и свопы – они могут существенно повлиять на прибыльность

5. Используйте VPS для круглосуточной работы советника


5. Ограничения данной реализации:


1. Советник открывает только одну позицию на символ

2. Не учитывает корреляции между разными инструментами

3. Нет защиты от "зависаний" и сбоев связи

4. Требует постоянного мониторинга и периодической оптимизации параметров


Этот код представляет собой базовую реализацию стратегии следования за трендом. Для профессионального использования рекомендуется добавить дополнительные фильтры, улучшенное управление капиталом и систему мониторинга.

10 роботов для автоматической торговли на Форекс

Подняться наверх