
Полная версия
10 роботов для автоматической торговли на Форекс
(MathAbs(BC_AB – fib_0382) < FiboTolerance ||
MathAbs(BC_AB – fib_0886) < FiboTolerance) &&
(MathAbs(CD_BC – fib_1272) < FiboTolerance ||
MathAbs(CD_BC – fib_1618) < FiboTolerance) &&
MathAbs(XD_XA – fib_0786) < FiboTolerance)
{
return PATTERN_GARTLEY;
}
// Проверяем паттерн Бабочка (Butterfly)
// AB = 0.786 XA, BC = 0.382-0.886 AB, CD = 1.618-2.24 BC, XD = 1.272-1.618 XA
if(MathAbs(AB_XA – fib_0786) < FiboTolerance &&
(MathAbs(BC_AB – fib_0382) < FiboTolerance ||
MathAbs(BC_AB – fib_0886) < FiboTolerance) &&
(MathAbs(CD_BC – fib_1618) < FiboTolerance ||
MathAbs(CD_BC – fib_2240) < FiboTolerance) &&
(MathAbs(XD_XA – fib_1272) < FiboTolerance ||
MathAbs(XD_XA – fib_1618) < FiboTolerance))
{
return PATTERN_BUTTERFLY;
}
// Проверяем паттерн Краб (Crab)
// AB = 0.382-0.618 XA, BC = 0.382-0.886 AB, CD = 2.618-3.618 BC, XD = 1.618 XA
if((MathAbs(AB_XA – fib_0382) < FiboTolerance ||
MathAbs(AB_XA – fib_0618) < FiboTolerance) &&
(MathAbs(BC_AB – fib_0382) < FiboTolerance ||
MathAbs(BC_AB – fib_0886) < FiboTolerance) &&
(MathAbs(CD_BC – fib_2618) < FiboTolerance ||
MathAbs(CD_BC – 3.618) < FiboTolerance) &&
MathAbs(XD_XA – fib_1618) < FiboTolerance)
{
return PATTERN_CRAB;
}
// Проверяем паттерн Летучая мышь (Bat)
// AB = 0.382-0.5 XA, BC = 0.382-0.886 AB, CD = 1.618-2.618 BC, XD = 0.886 XA
if((MathAbs(AB_XA – fib_0382) < FiboTolerance ||
MathAbs(AB_XA – fib_0500) < FiboTolerance) &&
(MathAbs(BC_AB – fib_0382) < FiboTolerance ||
MathAbs(BC_AB – fib_0886) < FiboTolerance) &&
(MathAbs(CD_BC – fib_1618) < FiboTolerance ||
MathAbs(CD_BC – fib_2618) < FiboTolerance) &&
MathAbs(XD_XA – fib_0886) < FiboTolerance)
{
return PATTERN_BAT;
}
// Проверяем паттерн Акула (Shark)
// 0X = 1.13-1.618 XA, AB = 1.13-1.618 0X, BC = 0.886-1.13 AB
// Специфический паттерн, требует особой логики
return PATTERN_NONE;
}
//+–+
//| Отображение паттерна на графике |
//+–+
void DrawPattern(const PatternPoints &pattern)
{
// Удаляем старые линии
DeletePatternLines();
// Создаем уникальные имена для объектов
string prefix = "HP_"+IntegerToString(MagicNumber)+"_";
// Рисуем линии паттерна
ObjectCreate(0, prefix+"X_A", OBJ_TREND, 0, pattern.timeX, pattern.X, pattern.timeA, pattern.A);
ObjectSetInteger(0, prefix+"X_A", OBJPROP_COLOR, PatternColor);
ObjectSetInteger(0, prefix+"X_A", OBJPROP_WIDTH, 2);
ObjectSetInteger(0, prefix+"X_A", OBJPROP_RAY, false);
ObjectCreate(0, prefix+"A_B", OBJ_TREND, 0, pattern.timeA, pattern.A, pattern.timeB, pattern.B);
ObjectSetInteger(0, prefix+"A_B", OBJPROP_COLOR, PatternColor);
ObjectSetInteger(0, prefix+"A_B", OBJPROP_WIDTH, 2);
ObjectSetInteger(0, prefix+"A_B", OBJPROP_RAY, false);
ObjectCreate(0, prefix+"B_C", OBJ_TREND, 0, pattern.timeB, pattern.B, pattern.timeC, pattern.C);
ObjectSetInteger(0, prefix+"B_C", OBJPROP_COLOR, PatternColor);
ObjectSetInteger(0, prefix+"B_C", OBJPROP_WIDTH, 2);
ObjectSetInteger(0, prefix+"B_C", OBJPROP_RAY, false);
ObjectCreate(0, prefix+"C_D", OBJ_TREND, 0, pattern.timeC, pattern.C, pattern.timeD, pattern.D);
ObjectSetInteger(0, prefix+"C_D", OBJPROP_COLOR, PatternColor);
ObjectSetInteger(0, prefix+"C_D", OBJPROP_WIDTH, 2);
ObjectSetInteger(0, prefix+"C_D", OBJPROP_RAY, false);
// Добавляем точки
CreatePoint(prefix+"X", pattern.timeX, pattern.X, 218);
CreatePoint(prefix+"A", pattern.timeA, pattern.A, 218);
CreatePoint(prefix+"B", pattern.timeB, pattern.B, 218);
CreatePoint(prefix+"C", pattern.timeC, pattern.C, 218);
CreatePoint(prefix+"D", pattern.timeD, pattern.D, 218);
// Добавляем метки
CreateLabel(prefix+"Label_X", "X", pattern.timeX, pattern.X);
CreateLabel(prefix+"Label_A", "A", pattern.timeA, pattern.A);
CreateLabel(prefix+"Label_B", "B", pattern.timeB, pattern.B);
CreateLabel(prefix+"Label_C", "C", pattern.timeC, pattern.C);
CreateLabel(prefix+"Label_D", "D", pattern.timeD, pattern.D);
// Добавляем название паттерна
string patternName = GetPatternName(pattern.type);
CreateLabel(prefix+"PatternName", patternName + " " + ((pattern.direction == 1) ? "Bullish" : "Bearish"),
pattern.timeD, pattern.D, 12, clrRed);
}
//+–+
//| Создание точки на графике |
//+–+
void CreatePoint(string name, datetime time, double price, int code)
{
ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code);
ObjectSetInteger(0, name, OBJPROP_COLOR, PatternColor);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 3);
}
//+–+
//| Создание метки на графике |
//+–+
void CreateLabel(string name, string text, datetime time, double price, int fontSize = 8, color clr = clrBlack)
{
ObjectCreate(0, name, OBJ_TEXT, 0, time, price);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontSize);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_UPPER);
}
//+–+
//| Удаление линий паттерна |
//+–+
void DeletePatternLines()
{
string prefix = "HP_"+IntegerToString(MagicNumber)+"_";
for(int i = ObjectsTotal(0)-1; i >= 0; i–)
{
string name = ObjectName(0, i);
if(StringFind(name, prefix) == 0)
{
ObjectDelete(0, name);
}
}
}
//+–+
//| Получение названия паттерна |
//+–+
string GetPatternName(PATTERN_TYPE type)
{
switch(type)
{
case PATTERN_GARTLEY: return "Gartley";
case PATTERN_BUTTERFLY: return "Butterfly";
case PATTERN_CRAB: return "Crab";
case PATTERN_BAT: return "Bat";
case PATTERN_SHARK: return "Shark";
case PATTERN_CYPHER: return "Cypher";
default: return "Unknown";
}
}
//+–+
//| Открытие сделки по паттерну |
//+–+
void OpenPatternTrade(const PatternPoints &pattern)
{
// Получаем текущую цену
MqlTick lastTick;
if(!SymbolInfoTick(_Symbol, lastTick)) return;
// Определяем направление сделки
ENUM_ORDER_TYPE orderType;
double entryPrice;
double slPrice, tpPrice;
if(pattern.direction == 1) // Бычий паттерн – покупаем
{
orderType = ORDER_TYPE_BUY;
entryPrice = lastTick.ask;
// Стоп-лосс ниже точки D
slPrice = pattern.D – StopLoss_Points * _Point;
// Тейк-профит на уровне точки B или A (в зависимости от паттерна)
if(pattern.type == PATTERN_GARTLEY || pattern.type == PATTERN_BAT)
tpPrice = entryPrice + (pattern.B – pattern.D);
else
tpPrice = entryPrice + TakeProfit_Points * _Point;
}
else // Медвежий паттерн – продаем
{
orderType = ORDER_TYPE_SELL;
entryPrice = lastTick.bid;
// Стоп-лосс выше точки D
slPrice = pattern.D + StopLoss_Points * _Point;
// Тейк-профит на уровне точки B или A
if(pattern.type == PATTERN_GARTLEY || pattern.type == PATTERN_BAT)
tpPrice = entryPrice – (pattern.D – pattern.B);
else
tpPrice = entryPrice – TakeProfit_Points * _Point;
}
// Открываем сделку
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = orderType;
request.price = entryPrice;
request.sl = slPrice;
request.tp = tpPrice;
request.deviation = 10;
request.magic = MagicNumber;
request.comment = GetPatternName(pattern.type);
if(!OrderSend(request, result))
{
Print("Ошибка открытия позиции по паттерну: ", GetLastError());
}
else
{
Print("Позиция открыта по паттерну: ", GetPatternName(pattern.type),
" (", (pattern.direction == 1) ? "Bullish" : "Bearish", ")");
}
}
//+–+
//| Функция для ручного тестирования паттернов |
//+–+
void TestPatternRecognition()
{
// Эта функция может быть использована для тестирования
// алгоритма распознавания паттернов на исторических данных
Print("Начинаем тестирование распознавания паттернов…");
for(int i = 100; i < Bars(_Symbol, _Period) – 100; i += 10)
{
// Здесь можно добавить код для тестирования на разных участках истории
}
}
```
Дополнительные функции для расширенного распознавания:
```mq5
//+–+
//| Улучшенная функция распознавания паттернов (опционально) |
//+–+
PatternPoints AdvancedPatternScan()
{
PatternPoints result;
result.type = PATTERN_NONE;
// Используем алгоритм поиска экстремумов без ZigZag
// для более точного распознавания
// 1. Ищем swing highs и swing lows
double swingHighs[], swingLows[];
datetime swingHighTimes[], swingLowTimes[];
FindSwingPoints(swingHighs, swingHighTimes, swingLows, swingLowTimes);
// 2. Комбинируем экстремумы в правильном порядке
// 3. Проверяем больше типов паттернов
// 4. Добавляем фильтры по объему и времени
return result;
}
//+–+
//| Поиск точек разворота (swing points) |
//+–+
void FindSwingPoints(double &highs[], datetime &highTimes[],
double &lows[], datetime &lowTimes[],
int lookback = 5)
{
ArrayResize(highs, 0);
ArrayResize(highTimes, 0);
ArrayResize(lows, 0);
ArrayResize(lowTimes, 0);
for(int i = lookback; i < Bars(_Symbol, _Period) – lookback; i++)
{
// Проверяем swing high
bool isSwingHigh = true;
for(int j = 1; j <= lookback; j++)
{
if(iHigh(_Symbol, _Period, i) <= iHigh(_Symbol, _Period, i+j) ||
iHigh(_Symbol, _Period, i) <= iHigh(_Symbol, _Period, i-j))
{
isSwingHigh = false;
break;
}
}
if(isSwingHigh)
{
int size = ArraySize(highs);
ArrayResize(highs, size + 1);
ArrayResize(highTimes, size + 1);
highs[size] = iHigh(_Symbol, _Period, i);
highTimes[size] = iTime(_Symbol, _Period, i);
}
// Проверяем swing low
bool isSwingLow = true;
for(int j = 1; j <= lookback; j++)
{
if(iLow(_Symbol, _Period, i) >= iLow(_Symbol, _Period, i+j) ||
iLow(_Symbol, _Period, i) >= iLow(_Symbol, _Period, i-j))
{
isSwingLow = false;
break;
}
}
if(isSwingLow)
{
int size = ArraySize(lows);
ArrayResize(lows, size + 1);
ArrayResize(lowTimes, size + 1);
lows[size] = iLow(_Symbol, _Period, i);
lowTimes[size] = iTime(_Symbol, _Period, i);
}
}
}
//+–+
//| Фильтр паттернов по дополнительным критериям |
//+–+
bool ValidatePattern(const PatternPoints &pattern)
{
// 1. Проверяем объемы в точках разворота
// 2. Проверяем временные соотношения
// 3. Проверяем наличие дивергенций
// 4. Проверяем контекст рынка
// Пример: проверяем, что в точке D объем выше среднего
int barD = iBarShift(_Symbol, _Period, pattern.timeD);
long volumeD = iVolume(_Symbol, _Period, barD);
long avgVolume = iMA(_Symbol, _Period, 20, 0, MODE_SMA, VOLUME_TICK, barD);
if(volumeD < avgVolume * 0.8) return false;
// Проверяем временные соотношения
double timeAB = double(pattern.timeB – pattern.timeA);
double timeBC = double(pattern.timeC – pattern.timeB);
double timeCD = double(pattern.timeD – pattern.timeC);
// Время CD не должно быть меньше времени BC (для большинства паттернов)
if(timeCD < timeBC * 0.5) return false;
return true;
}
```
Ключевые особенности робота:
1. Алгоритм распознавания:
· Использует индикатор ZigZag для поиска экстремумов
· Проверяет соотношения Фибоначчи с заданным допуском
· Распознает 6 основных гармонических паттернов
2. Точность распознавания:
· Настраиваемый допуск для уровней Фибо
· Фильтры по времени и количеству баров
· Проверка чередования экстремумов
3. Визуализация:
· Отображение паттерна на графике
· Подписанные точки X, A, B, C, D
· Разные цвета для бычьих и медвежьих паттернов
4. Торговая логика:
· Вход в точке завершения паттерна (D)
Конец ознакомительного фрагмента.
Текст предоставлен ООО «Литрес».
Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.
Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.









