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

Полная версия

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

Настройки чтения
Размер шрифта
Высота строк
Поля
На страницу:
2 из 3

input int Momentum_Period = 3; // Период момента

input double MinTickSpeed = 0.5; // Мин. скорость тиков (тиков/сек)


//+–+

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

//+–+

int handleFastMA, handleSlowMA, handleMomentum;

double fastMA[], slowMA[], momentum[];

datetime lastTradeTime = 0;

int todayTrades = 0;

datetime lastTradeDate = 0;

double initialEquity = 0;

MqlDateTime currentTime;

int tickCounter = 0;

datetime lastTickTime = 0;

double tickSpeed = 0;


// Структура для хранения информации о новостях

struct NewsEvent

{

datetime time;

string currency;

string event;

int impact; // 0=low, 1=medium, 2=high, 3=very high

};


//+–+

//| Expert initialization function |

//+–+

int OnInit()

{

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

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

{

Print("Некорректный размер лота!");

return INIT_PARAMETERS_INCORRECT;

}


if(TakeProfit_Pips <= 0 || StopLoss_Pips <= 0)

{

Print("Некорректные уровни TP/SL!");

return INIT_PARAMETERS_INCORRECT;

}


// Инициализация индикаторов

handleFastMA = iMA(_Symbol, PERIOD_M1, FastMA_Period, 0, MA_Method, PRICE_CLOSE);

handleSlowMA = iMA(_Symbol, PERIOD_M1, SlowMA_Period, 0, MA_Method, PRICE_CLOSE);

handleMomentum = iMomentum(_Symbol, PERIOD_M1, Momentum_Period, PRICE_CLOSE);


if(handleFastMA == INVALID_HANDLE || handleSlowMA == INVALID_HANDLE ||

handleMomentum == INVALID_HANDLE)

{

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

return INIT_FAILED;

}


// Установка массивов как таймсерии

ArraySetAsSeries(fastMA, true);

ArraySetAsSeries(slowMA, true);

ArraySetAsSeries(momentum, true);


// Инициализация начального эквити

initialEquity = AccountInfoDouble(ACCOUNT_EQUITY);


// Сброс счетчика сделок при перезагрузке

ResetDailyTradesCounter();


// Создание таймера для мониторинга скорости тиков

EventSetTimer(1);


return INIT_SUCCEEDED;

}


//+–+

//| Expert deinitialization function |

//+–+

void OnDeinit(const int reason)

{

if(handleFastMA != INVALID_HANDLE) IndicatorRelease(handleFastMA);

if(handleSlowMA != INVALID_HANDLE) IndicatorRelease(handleSlowMA);

if(handleMomentum != INVALID_HANDLE) IndicatorRelease(handleMomentum);

EventKillTimer();

}


//+–+

//| Expert tick function |

//+–+

void OnTick()

{

// Подсчет скорости тиков

tickCounter++;

datetime currentTickTime = TimeCurrent();

if(lastTickTime == 0) lastTickTime = currentTickTime;


// Проверяем ежедневный лимит сделок

CheckDailyTradesLimit();


// Проверяем защиту по эквити

if(UseEquityProtection && !CheckEquityProtection()) return;


// Проверяем фильтр новостей

if(UseNewsFilter && IsNewsTime()) return;


// Проверяем спред

if(!CheckSpread()) return;


// Проверяем скорость тиков

if(!CheckTickSpeed()) return;


// Проверяем наличие открытых позиций

if(PositionSelect(_Symbol)) return;


// Получаем данные индикаторов

if(!UpdateIndicators()) return;


// Получаем тиковые данные

MqlTick lastTick;

if(!SymbolInfoTick(_Symbol, lastTick)) return;


// Получаем данные объемов

long volumeArray[];

ArraySetAsSeries(volumeArray, true);

if(CopyTickVolume(_Symbol, PERIOD_M1, 0, 3, volumeArray) <= 0) return;


// Генерируем сигналы

bool buySignal = GenerateBuySignal(lastTick, volumeArray);

bool sellSignal = GenerateSellSignal(lastTick, volumeArray);


// Открываем позиции

if(buySignal)

{

OpenPosition(ORDER_TYPE_BUY);

}

else if(sellSignal)

{

OpenPosition(ORDER_TYPE_SELL);

}

}


//+–+

//| Timer function для подсчета скорости тиков |

//+–+

void OnTimer()

{

datetime currentTime = TimeCurrent();

double timeDiff = currentTime – lastTickTime;


if(timeDiff > 0)

{

tickSpeed = tickCounter / timeDiff;

tickCounter = 0;

lastTickTime = currentTime;

}

}


//+–+

//| Функция генерации сигнала на покупку |

//+–+

bool GenerateBuySignal(MqlTick &tick, long &volumeArray[])

{

// Сигнал по скользящим средним

bool maSignal = fastMA[0] > slowMA[0] && fastMA[1] <= slowMA[1];


// Сигнал по моменту

bool momentumSignal = momentum[0] > 100 && momentum[1] <= 100;


// Проверка объема

bool volumeSignal = volumeArray[0] > Volume_Threshold;


// Проверка цены (микро-паттерны)

bool pricePattern = CheckBullishMicroPattern();


// Комбинированный сигнал

return (maSignal && momentumSignal && volumeSignal && pricePattern);

}


//+–+

//| Функция генерации сигнала на продажу |

//+–+

bool GenerateSellSignal(MqlTick &tick, long &volumeArray[])

{

// Сигнал по скользящим средним

bool maSignal = fastMA[0] < slowMA[0] && fastMA[1] >= slowMA[1];


// Сигнал по моменту

bool momentumSignal = momentum[0] < 100 && momentum[1] >= 100;


// Проверка объема

bool volumeSignal = volumeArray[0] > Volume_Threshold;


// Проверка цены (микро-паттерны)

bool pricePattern = CheckBearishMicroPattern();


// Комбинированный сигнал

return (maSignal && momentumSignal && volumeSignal && pricePattern);

}


//+–+

//| Проверка бычьего микро-паттерна |

//+–+

bool CheckBullishMicroPattern()

{

// Пример: проверка последовательности из 3 последних тиков

MqlRates rates[];

ArraySetAsSeries(rates, true);


if(CopyRates(_Symbol, PERIOD_M1, 0, 5, rates) < 5) return false;


// Паттерн: снижение-снижение-рост (поглощение)

bool pattern1 = rates[3].close < rates[3].open && // Медвежья свеча

rates[2].close < rates[2].open && // Медвежья свеча

rates[1].close > rates[1].open && // Бычья свеча

rates[1].close > rates[2].close; // Закрытие выше предыдущего закрытия


// Паттерн: молот или доджи после снижения

bool pattern2 = rates[2].close < rates[2].open && // Медвежья свеча

(rates[1].high – rates[1].low) > 3 * (rates[1].close – rates[1].open) && // Длинная тень

rates[1].close > rates[1].open; // Закрытие выше открытия


return pattern1 || pattern2;

}


//+–+

//| Проверка медвежьего микро-паттерна |

//+–+

bool CheckBearishMicroPattern()

{

MqlRates rates[];

ArraySetAsSeries(rates, true);


if(CopyRates(_Symbol, PERIOD_M1, 0, 5, rates) < 5) return false;


// Паттерн: рост-рост-снижение (поглощение)

bool pattern1 = rates[3].close > rates[3].open && // Бычья свеча

rates[2].close > rates[2].open && // Бычья свеча

rates[1].close < rates[1].open && // Медвежья свеча

rates[1].close < rates[2].close; // Закрытие ниже предыдущего закрытия


// Паттерн: повешенный или доджи после роста

bool pattern2 = rates[2].close > rates[2].open && // Бычья свеча

(rates[1].high – rates[1].low) > 3 * (rates[1].open – rates[1].close) && // Длинная тень

rates[1].close < rates[1].open; // Закрытие ниже открытия


return pattern1 || pattern2;

}


//+–+

//| Обновление данных индикаторов |

//+–+

bool UpdateIndicators()

{

if(CopyBuffer(handleFastMA, 0, 0, 3, fastMA) <= 0) return false;

if(CopyBuffer(handleSlowMA, 0, 0, 3, slowMA) <= 0) return false;

if(CopyBuffer(handleMomentum, 0, 0, 3, momentum) <= 0) return false;


return true;

}


//+–+

//| Проверка спреда |

//+–+

bool CheckSpread()

{

MqlTick lastTick;

if(!SymbolInfoTick(_Symbol, lastTick)) return false;


double currentSpread = (lastTick.ask – lastTick.bid) / _Point;


return currentSpread <= MaxSpread_Pips;

}


//+–+

//| Проверка скорости тиков |

//+–+

bool CheckTickSpeed()

{

return tickSpeed >= MinTickSpeed;

}


//+–+

//| Проверка времени новостей |

//+–+

bool IsNewsTime()

{

// В реальной реализации здесь должен быть доступ к календарю новостей

// Это примерная заглушка


TimeToStruct(TimeCurrent(), currentTime);


// Пример: не торговать в 8:30-9:00 и 13:30-14:00 (важные релизы)

bool newsTime1 = (currentTime.hour == 8 && currentTime.min >= 30) ||

(currentTime.hour == 9 && currentTime.min == 0);


bool newsTime2 = (currentTime.hour == 13 && currentTime.min >= 30) ||

(currentTime.hour == 14 && currentTime.min == 0);


return newsTime1 || newsTime2;

}


//+–+

//| Проверка защиты по эквити |

//+–+

bool CheckEquityProtection()

{

double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY);

double drawdownPercent = ((initialEquity – currentEquity) / initialEquity) * 100;


return drawdownPercent < EquityProtectionPercent;

}


//+–+

//| Проверка дневного лимита сделок |

//+–+

void CheckDailyTradesLimit()

{

datetime currentDate = TimeCurrent();

MqlDateTime dateStruct;

TimeToStruct(currentDate, dateStruct);


// Если день сменился, сбрасываем счетчик

if(lastTradeDate != dateStruct.day)

{

todayTrades = 0;

lastTradeDate = dateStruct.day;

}

}


//+–+

//| Сброс счетчика дневных сделок |

//+–+

void ResetDailyTradesCounter()

{

datetime currentDate = TimeCurrent();

MqlDateTime dateStruct;

TimeToStruct(currentDate, dateStruct);


todayTrades = 0;

lastTradeDate = dateStruct.day;

}


//+–+

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

//+–+

void OpenPosition(ENUM_ORDER_TYPE orderType)

{

// Проверяем лимит сделок

if(todayTrades >= MaxDailyTrades) return;


MqlTradeRequest request = {};

MqlTradeResult result = {};


request.action = TRADE_ACTION_DEAL;

request.symbol = _Symbol;

request.volume = LotSize;

request.type = orderType;

request.type_filling = ORDER_FILLING_IOC; // Немедленное исполнение или отмена

request.deviation = 1; // Минимальное отклонение

request.magic = MagicNumber;


// Установка цен

MqlTick lastTick;

SymbolInfoTick(_Symbol, lastTick);


if(orderType == ORDER_TYPE_BUY)

{

request.price = lastTick.ask;

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

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

}

else // ORDER_TYPE_SELL

{

request.price = lastTick.bid;

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

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

}


// Отправка ордера

if(!OrderSend(request, result))

{

Print("Ошибка открытия позиции: ", GetLastError());

}

else

{

todayTrades++;

Print("Позиция открыта. Сегодня сделок: ", todayTrades);

}

}


//+–+

//| Функция закрытия всех позиций |

//+–+

void CloseAllPositions()

{

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

{

ulong ticket = PositionGetTicket(i);

if(PositionSelectByTicket(ticket))

{

if(PositionGetString(POSITION_SYMBOL) == _Symbol &&

PositionGetInteger(POSITION_MAGIC) == MagicNumber)

{

MqlTradeRequest request = {};

MqlTradeResult result = {};


request.action = TRADE_ACTION_DEAL;

request.position = ticket;

request.symbol = _Symbol;

request.volume = PositionGetDouble(POSITION_VOLUME);

request.deviation = 1;


if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

{

request.type = ORDER_TYPE_SELL;

request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

}

else

{

request.type = ORDER_TYPE_BUY;

request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

}


OrderSend(request, result);

}

}

}

}

```


Дополнительные функции для реального скальпинга:


```mq5

//+–+

//| Функция мониторинга стакана цен (упрощенная) |

//+–+

void MonitorMarketDepth()

{

// В MT5 нет прямого доступа к Level II, но можно использовать

// символьные свойства для получения информации о спросе/предложении


MqlTick lastTick;

SymbolInfoTick(_Symbol, lastTick);


// Можно добавить логику анализа объема на текущих ценах

// Например, отслеживать крупные лимитные ордера

}


//+–+

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

//+–+

void AnalyzeVolumeClusters()

{

// Использование индикатора Volume Profile или Cluster Charts

// для определения уровней с максимальным объемом

}


//+–+

//| Функция для работы со стаканом заявок (требует специальных API) |

//+–+

void ProcessMarketDepth()

{

// Для реального доступа к Level II потребуется:

// 1. API от брокера с доступом к стакану

// 2. Специальные библиотеки или плагины

// 3. Прямое подключение к биржевым данным

}

```


Ключевые особенности скальпера:


1. Сверхбыстрая торговля:

· Использование тиковых данных

· Мгновенное исполнение (IOC)

· Минимальные уровни TP/SL (5-15 пунктов)

2. Система защиты:

· Ограничение по количеству сделок в день

· Защита по эквити

· Фильтр по спреду

· Фильтр новостей

3. Мониторинг качества соединения:

· Контроль скорости тиков

· Проверка стабильности подключения

4. Анализ микро-паттернов:

· Свечные паттерны на M1

· Анализ объемов

· Мониторинг момента


Требования для работы скальпера:


1. Технические:

· VPS с низкой задержкой (менее 1 мс к серверу)

· Выделенный канал связи

· Стабильное электропитание

2. Торговые условия:

· ECN счет с сырыми спредами

· Минимальная комиссия

· Разрешение на скальпинг

3. Рыночные условия:

· Высокая ликвидность (мажорные пары)

· Низкая волатильность в азиатскую сессию

· Отсутствие важных новостей


Важно: Скальпинг – это высокочастотная торговля с высокими рисками. Тестируйте стратегию на демо-счете не менее 3 месяцев перед использованием на реальные деньги. Начните с минимального лота и постепенно увеличивайте объемы при стабильной прибыльности.

Робот 4: «Гармоничный паттерн» (Harmonic Pattern Scanner)


Гармоничный паттерн (Harmonic Pattern Scanner) для MetaTrader 5


```mq5

//+–+

//| HarmonicPatternScanner.mq5 |

//| Copyright 2023, MetaQuotes Ltd. |

//| https://www.mql5.com |

//+–+

#property copyright "Copyright 2023, MetaQuotes Ltd."

#property link "https://www.mql5.com"

#property version "1.00"


//+–+

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

//+–+

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

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

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

input int MagicNumber = 112233; // Магический номер

input double FiboTolerance = 0.05; // Допуск для уровней Фибо (5%)

input int MinPatternBars = 20; // Минимум баров в паттерне

input int MaxPatternBars = 300; // Максимум баров в паттерне

input bool ShowPatternLines = true; // Показывать линии паттернов

input color PatternColor = clrBlue; // Цвет линий паттернов


//+–+

//| Перечисление типов паттернов |

//+–+

enum PATTERN_TYPE

{

PATTERN_NONE = 0,

PATTERN_GARTLEY = 1,

PATTERN_BUTTERFLY = 2,

PATTERN_CRAB = 3,

PATTERN_BAT = 4,

PATTERN_SHARK = 5,

PATTERN_CYPHER = 6

};


//+–+

//| Структура для хранения точек паттерна |

//+–+

struct PatternPoints

{

double X, A, B, C, D;

datetime timeX, timeA, timeB, timeC, timeD;

PATTERN_TYPE type;

int direction; // 1 – бычий, -1 – медвежий

};


//+–+

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

//+–+

PatternPoints lastPattern;

bool patternFound = false;

int lastPatternBar = 0;

int zigzagHandle;

double zigzagBuffer[];

datetime timeBuffer[];

double highBuffer[], lowBuffer[];

int lastCalculated = 0;


//+–+

//| Expert initialization function |

//+–+

int OnInit()

{

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

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

{

Print("Некорректный размер лота!");

return INIT_PARAMETERS_INCORRECT;

}


// Создание индикатора ZigZag для поиска экстремумов

zigzagHandle = iCustom(_Symbol, _Period, "Examples\\ZigZag.ex5", 12, 5, 3);


if(zigzagHandle == INVALID_HANDLE)

{

Print("Ошибка создания индикатора ZigZag!");

return INIT_FAILED;

}


// Настройка массивов

ArraySetAsSeries(zigzagBuffer, true);

ArraySetAsSeries(timeBuffer, true);

ArraySetAsSeries(highBuffer, true);

ArraySetAsSeries(lowBuffer, true);


return INIT_SUCCEEDED;

}


//+–+

//| Expert deinitialization function |

//+–+

void OnDeinit(const int reason)

{

if(zigzagHandle != INVALID_HANDLE) IndicatorRelease(zigzagHandle);

DeletePatternLines();

}


//+–+

//| Expert tick function |

//+–+

void OnTick()

{

// Проверяем наличие открытых позиций по этому символу и магику

if(PositionSelect(_Symbol)) return;


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

datetime currentTime = iTime(_Symbol, _Period, 0);


// Ищем паттерны каждые N баров или при смене дня

static datetime lastScanTime = 0;

if(currentTime – lastScanTime < 3600) return; // Сканируем раз в час


// Обновляем данные ZigZag

if(!UpdateZigZagData()) return;


// Ищем гармонические паттерны

PatternPoints foundPattern = ScanForPatterns();


if(foundPattern.type != PATTERN_NONE)

{

patternFound = true;

lastPattern = foundPattern;

lastPatternBar = iBarShift(_Symbol, _Period, currentTime);


// Отображаем паттерн на графике

if(ShowPatternLines) DrawPattern(foundPattern);


// Открываем сделку в точке D

OpenPatternTrade(foundPattern);


lastScanTime = currentTime;

}

}


//+–+

//| Обновление данных ZigZag |

//+–+

bool UpdateZigZagData()

{

// Копируем данные ZigZag

if(CopyBuffer(zigzagHandle, 0, 0, 500, zigzagBuffer) <= 0)

{

Print("Ошибка копирования данных ZigZag!");

return false;

}


// Копируем временные метки

if(CopyTime(_Symbol, _Period, 0, 500, timeBuffer) <= 0) return false;


// Копируем High и Low

if(CopyHigh(_Symbol, _Period, 0, 500, highBuffer) <= 0) return false;

if(CopyLow(_Symbol, _Period, 0, 500, lowBuffer) <= 0) return false;


return true;

}


//+–+

//| Поиск гармонических паттернов |

//+–+

PatternPoints ScanForPatterns()

{

PatternPoints result;

result.type = PATTERN_NONE;


// Собираем экстремумы из ZigZag

double extremes[];

datetime extremeTimes[];

int extremeBars[];


CollectExtremes(extremes, extremeTimes, extremeBars);


int extremeCount = ArraySize(extremes);

if(extremeCount < 5) return result;


// Ищем паттерны среди экстремумов

for(int i = 4; i < extremeCount; i++)

{

// Проверяем XABCD паттерны

for(int x = i-4; x <= i-4; x++)

for(int a = x+1; a <= i-3; a++)

for(int b = a+1; b <= i-2; b++)

for(int c = b+1; c <= i-1; c++)

for(int d = c+1; d <= i; d++)

{

// Проверяем временные рамки паттерна

int patternBars = extremeBars[d] – extremeBars[x];

if(patternBars < MinPatternBars || patternBars > MaxPatternBars) continue;


// Проверяем бычий паттерн (X – low, A – high, B – low, C – high, D – low)

if(extremes[x] < extremes[a] && extremes[a] > extremes[b] &&

extremes[b] < extremes[c] && extremes[c] > extremes[d])

{

PatternPoints bullPattern;

bullPattern.X = extremes[x];

bullPattern.A = extremes[a];

bullPattern.B = extremes[b];

bullPattern.C = extremes[c];

bullPattern.D = extremes[d];

bullPattern.timeX = extremeTimes[x];

bullPattern.timeA = extremeTimes[a];

bullPattern.timeB = extremeTimes[b];

bullPattern.timeC = extremeTimes[c];

bullPattern.timeD = extremeTimes[d];

bullPattern.direction = 1;


// Проверяем тип паттерна

bullPattern.type = CheckPatternType(bullPattern);

if(bullPattern.type != PATTERN_NONE)

{

// Проверяем, что точка D – последняя (или почти последняя)

int barsSinceD = iBarShift(_Symbol, _Period, extremeTimes[d]);

if(barsSinceD <= 3) // Паттерн свежий

{

return bullPattern;

}

}

}


// Проверяем медвежий паттерн (X – high, A – low, B – high, C – low, D – high)

if(extremes[x] > extremes[a] && extremes[a] < extremes[b] &&

extremes[b] > extremes[c] && extremes[c] < extremes[d])

{

PatternPoints bearPattern;

bearPattern.X = extremes[x];

bearPattern.A = extremes[a];

bearPattern.B = extremes[b];

bearPattern.C = extremes[c];

bearPattern.D = extremes[d];

bearPattern.timeX = extremeTimes[x];

bearPattern.timeA = extremeTimes[a];

bearPattern.timeB = extremeTimes[b];

bearPattern.timeC = extremeTimes[c];

bearPattern.timeD = extremeTimes[d];

bearPattern.direction = -1;


// Проверяем тип паттерна

bearPattern.type = CheckPatternType(bearPattern);

if(bearPattern.type != PATTERN_NONE)

{

// Проверяем, что точка D – последняя (или почти последшая)

int barsSinceD = iBarShift(_Symbol, _Period, extremeTimes[d]);

if(barsSinceD <= 3) // Паттерн свежий

{

return bearPattern;

}

}

}

}

}


return result;

}


//+–+

//| Сбор экстремумов из ZigZag |

//+–+

void CollectExtremes(double &extremes[], datetime ×[], int &bars[])

{

ArrayResize(extremes, 0);

ArrayResize(times, 0);

ArrayResize(bars, 0);


for(int i = 100; i >= 0; i–)

{

if(zigzagBuffer[i] != 0 && zigzagBuffer[i] != EMPTY_VALUE)

{

int size = ArraySize(extremes);

ArrayResize(extremes, size + 1);

ArrayResize(times, size + 1);

ArrayResize(bars, size + 1);


extremes[size] = zigzagBuffer[i];

times[size] = timeBuffer[i];

bars[size] = i;

}

}


// Ограничиваем количество экстремумов

int count = ArraySize(extremes);

if(count > 20)

{

ArrayResize(extremes, 20);

ArrayResize(times, 20);

ArrayResize(bars, 20);

}

}


//+–+

//| Проверка типа паттерна |

//+–+

PATTERN_TYPE CheckPatternType(const PatternPoints &pattern)

{

// Вычисляем соотношения Фибоначчи

double XA = MathAbs(pattern.A – pattern.X);

double AB = MathAbs(pattern.B – pattern.A);

double BC = MathAbs(pattern.C – pattern.B);

double CD = MathAbs(pattern.D – pattern.C);


// Отношения

double AB_XA = (XA != 0) ? AB / XA : 0;

double BC_AB = (AB != 0) ? BC / AB : 0;

double CD_BC = (BC != 0) ? CD / BC : 0;

double XC_XA = (XA != 0) ? MathAbs(pattern.C – pattern.X) / XA : 0;

double XD_XA = (XA != 0) ? MathAbs(pattern.D – pattern.X) / XA : 0;


// Уровни Фибоначчи

double fib_0382 = 0.382;

double fib_0500 = 0.5;

double fib_0618 = 0.618;

double fib_0707 = 0.707;

double fib_0786 = 0.786;

double fib_0886 = 0.886;

double fib_1130 = 1.13;

double fib_1272 = 1.272;

double fib_1414 = 1.414;

double fib_1618 = 1.618;

double fib_2000 = 2.0;

double fib_2240 = 2.24;

double fib_2618 = 2.618;


// Проверяем паттерн Гартли (Gartley)

// AB = 0.618 XA, BC = 0.382-0.886 AB, CD = 1.272-1.618 BC, XD = 0.786 XA

if(MathAbs(AB_XA – fib_0618) < FiboTolerance &&

На страницу:
2 из 3