Исходный код
Ниже представлен оптимизированный код индикатора KAMA для MetaTrader 4. Мы используем современную структуру OnCalculate для обеспечения высокой производительности и совместимости с новыми билдами терминала.
//+------------------------------------------------------------------+
//| KAMA_Adaptive |
//| Finfluct.com|
//+------------------------------------------------------------------+
#property copyright "Finfluct"
#property link "https://finfluct.com"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
// Входные параметры
input int InpKamaPeriod = 10; // Период ER (Efficiency Ratio)
input int InpFastPeriod = 2; // Период быстрой EMA
input int InpSlowPeriod = 30; // Период медленной EMA
input ENUM_APPLIED_PRICE InpPrice = PRICE_CLOSE; // Тип цены
// Буфер индикатора
double KamaBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, KamaBuffer);
SetIndexStyle(0, DRAW_LINE);
IndicatorShortName("KAMA(" + IntegerToString(InpKamaPeriod) + "," + IntegerToString(InpFastPeriod) + "," + IntegerToString(InpSlowPeriod) + ")");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const double &tick_volume[],
const double &volume[],
const int &spread[])
{
if(rates_total <= InpKamaPeriod) return(0);
int limit = rates_total - prev_calculated;
if(prev_calculated > 0) limit++;
// Константы сглаживания
double fastSC = 2.0 / (InpFastPeriod + 1.0);
double slowSC = 2.0 / (InpSlowPeriod + 1.0);
for(int i = limit - 1; i >= 0; i--)
{
int barIndex = rates_total - 1 - i;
// Инициализация начальных значений
if(barIndex < InpKamaPeriod)
{
KamaBuffer[i] = GetPrice(i, InpPrice);
continue;
}
double currentPrice = GetPrice(i, InpPrice);
// 1. Расчет направления (Signal)
double signal = MathAbs(currentPrice - GetPrice(i + InpKamaPeriod, InpPrice));
// 2. Расчет шума (Noise)
double noise = 0.0;
for(int j = 0; j < InpKamaPeriod; j++)
{
noise += MathAbs(GetPrice(i + j, InpPrice) - GetPrice(i + j + 1, InpPrice));
}
// 3. Расчет коэффициента эффективности (ER)
double er = 0.0;
if(noise != 0.0) er = signal / noise;
// 4. Расчет адаптивной альфы (Smoothing Constant)
double sc = MathPow(er * (fastSC - slowSC) + slowSC, 2.0);
// 5. Расчет KAMA
double prevKama = KamaBuffer[i + 1];
KamaBuffer[i] = prevKama + sc * (currentPrice - prevKama);
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Получение цены по типу |
//+------------------------------------------------------------------+
double GetPrice(int index, ENUM_APPLIED_PRICE priceType)
{
switch(priceType)
{
case PRICE_CLOSE: return(Close[index]);
case PRICE_OPEN: return(Open[index]);
case PRICE_HIGH: return(High[index]);
case PRICE_LOW: return(Low[index]);
case PRICE_MEDIAN: return((High[index] + Low[index]) / 2.0);
case PRICE_TYPICAL: return((High[index] + Low[index] + Close[index]) / 3.0);
case PRICE_WEIGHTED: return((High[index] + Low[index] + 2.0 * Close[index]) / 4.0);
default: return(Close[index]);
}
} Разбор параметров
InpKamaPeriod: Период расчета коэффициента эффективности (Efficiency Ratio, ER). Определяет количество баров, используемых для оценки силы тренда и уровня рыночного шума. Оптимальный диапазон: от 10 до 15.InpFastPeriod: Период быстрой экспоненциальной скользящей средней (EMA). Задает максимальную скорость адаптации KAMA при сильном направленном движении. Обычно равен 2.InpSlowPeriod: Период медленной EMA. Задает минимальную скорость индикатора во время флета, предотвращая ложные срабатывания. Стандартное значение — 30.InpPrice: Тип цены, используемый для расчетов (закрытие, открытие, медианная и т.д.). Позволяет адаптировать индикатор под различные торговые стратегии.
Как запустить
Для запуска индикатора выполните следующие шаги:
1. Откройте торговый терминал MetaTrader 4 и нажмите клавиши F4, чтобы запустить редактор MetaEditor.
2. Создайте новый пользовательский индикатор (Файл -> Создать -> Пользовательский индикатор), укажите имя, например, KAMA_Adaptive.
3. Полностью замените сгенерированный шаблон кодом, представленным выше, и нажмите кнопку Компилировать (или клавишу F7).
4. Вернитесь в терминал MetaTrader 4, найдите индикатор в окне 'Навигатор' и перетащите его на график любого финансового инструмента.
Стоит отметить, что хотя MQL4 отлично справляется с визуализацией и базовыми расчетами, для построения сложных прогностических систем на базе искусственного интеллекта часто требуется интеграция с внешними библиотеками. Например, вы можете изучить статью Интеграция MQL5 с Python через сокеты для TensorFlow моделей или рассмотреть архитектуру обмена данными, описанную в материале MetaTrader 5 и Python: Передача данных через ZeroMQ (ZMQ) сокеты.
Если вы планируете использовать KAMA в составе автоматизированного советника (EA), вам также могут понадобиться вспомогательные утилиты для управления позициями. Ознакомьтесь с решением для автоматизации риск-менеджмента в статье MQL5: Массовое изменение Stop Loss и Take Profit по Magic Number.




