adaptivesupertrendengine.mq4
Похожие материалы по тегам
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «adaptivesupertrendengine.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Данный файл представляет собой include-библиотеку (заголовочный модуль) для MetaTrader 4, реализующую адаптивный движок анализа SuperTrend. Модуль объединяет расчёт SuperTrend на основе ATR, скользящую среднюю осциллятора средней цены (MPO), индикатор RSI и детекцию дивергенций по пивотам для формирования адаптивного трендового сигнала. Предназначен для интеграции в торговых советников как безголовый (headless) многоинстансный модуль.
Класс CAdaptiveSuperTrend хранит данные, специфичные для каждой пары инструмент/таймфрейм, и выполняет пересчёт при каждом тике. При появлении нового бара массивы сдвигаются и обновляются значения. Модуль корректно обрабатывает изменение символа или таймфрейма, перестраивая состояние с нуля.
Адаптивная функция уменьшает множитель SuperTrend при обнаружении дивергенции, повышая чувствительность индикатора к потенциальным разворотам тренда. Класс предоставляет набор методов доступа для получения текущих значений SuperTrend, направления тренда, сигналов дивергенции, эффективного множителя и значения ATR.
Настройки программы
| Настройка | Описание |
|---|---|
| AST_SuperTrendPeriod | Период SuperTrend — количество баров, используемых для расчёта среднего истинного диапазона (ATR). |
| AST_SuperTrendMultiplier | Множитель SuperTrend — коэффициент, определяющий расстояние линий SuperTrend от медианной цены с учётом ATR. |
| AST_MPO_Period | Период расчёта осциллятора средней цены (MPO) — количество баров, используемых для вычисления среднего тела свечи. |
| AST_MPO_smooth | Период экспоненциального сглаживания MPO — используется для сглаживания сырого значения осциллятора. |
| AST_RsiPeriod | Период индикатора RSI — количество баров для расчёта относительного индекса силы по ценам закрытия. |
| AST_DivSource | Источник осциллятора для детекции дивергенций: 0 — сглаженный MPO, 1 — RSI. |
| AST_DivPivotLen | Длина поиска пивотов для детекции дивергенций — количество баров в каждом направлении от кандидата пивота, используемое для проверки его валидности. |
| AST_DivSensitivity | Чувствительность адаптивного сжатия — доля уменьшения множителя SuperTrend при наличии дивергенции (значение от 0 до 1). |
| AST_EnableAdaptiveShrink | Переключатель адаптивного сжатия множителя SuperTrend при обнаружении дивергенции. |
Поиск по коду файла
#property strict
#property description " "
#property description "Headless, multi-instance SuperTrend analysis module that combines trend, momentum, and divergence information to produce an adaptive trend signal for an EA."
#property description " "
#ifndef ADAPTIVE_SUPERTREND_ENGINE_MQH
#define ADAPTIVE_SUPERTREND_ENGINE_MQH
input int AST_SuperTrendPeriod = 10;
input double AST_SuperTrendMultiplier = 3.0;
input int AST_MPO_Period = 6;
input int AST_MPO_smooth = 7;
input int AST_RsiPeriod = 14;
input int AST_DivSource = 0;
input int AST_DivPivotLen = 2;
input double AST_DivSensitivity = 0.3;
input bool AST_EnableAdaptiveShrink = true;
class CAdaptiveSuperTrend
{
private:
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
double m_st_up[];
double m_st_dn[];
double m_st_trend_calc[];
double m_buf_ATR_ST[];
double m_buf_MPO_Raw[];
double m_buf_MPO_Smooth[];
double m_buf_RSI[];
double m_LastPivLowPriceBuffer[];
double m_LastPivLowOscBuffer[];
double m_LastPivHighPriceBuffer[];
double m_LastPivHighOscBuffer[];
double m_LastTypeBuffer[];
double m_BarsSinceBuffer[];
datetime m_LastBarTime;
bool m_Initialized;
int m_LastBars;
double m_Point;
double m_SmoothAlpha;
int m_MPO_Period;
int m_DivPivotLen;
int Bars()
{
if(m_symbol == "")
return 0;
return iBars(m_symbol, m_timeframe);
}
bool ShiftArrays()
{
int newSize = Bars();
if(newSize < 3)
return false;
if(m_LastBars < 3)
{
Init(m_symbol, m_timeframe);
return false;
}
if(newSize != m_LastBars + 1)
{
Init(m_symbol, m_timeframe);
return false;
}
int oldSize = ArraySize(m_st_up);
if(oldSize != m_LastBars)
{
Init(m_symbol, m_timeframe);
return false;
}
ArrayResize(m_st_up, newSize);
ArrayResize(m_st_dn, newSize);
ArrayResize(m_st_trend_calc, newSize);
ArrayResize(m_buf_ATR_ST, newSize);
ArrayResize(m_buf_MPO_Raw, newSize);
ArrayResize(m_buf_MPO_Smooth, newSize);
ArrayResize(m_buf_RSI, newSize);
ArrayResize(m_LastPivLowPriceBuffer, newSize);
ArrayResize(m_LastPivLowOscBuffer, newSize);
ArrayResize(m_LastPivHighPriceBuffer, newSize);
ArrayResize(m_LastPivHighOscBuffer, newSize);
ArrayResize(m_LastTypeBuffer, newSize);
ArrayResize(m_BarsSinceBuffer, newSize);
ArraySetAsSeries(m_st_up, true);
ArraySetAsSeries(m_st_dn, true);
ArraySetAsSeries(m_st_trend_calc, true);
ArraySetAsSeries(m_buf_ATR_ST, true);
ArraySetAsSeries(m_buf_MPO_Raw, true);
ArraySetAsSeries(m_buf_MPO_Smooth, true);
ArraySetAsSeries(m_buf_RSI, true);
ArraySetAsSeries(m_LastPivLowPriceBuffer, true);
ArraySetAsSeries(m_LastPivLowOscBuffer, true);
ArraySetAsSeries(m_LastPivHighPriceBuffer, true);
ArraySetAsSeries(m_LastPivHighOscBuffer, true);
ArraySetAsSeries(m_LastTypeBuffer, true);
ArraySetAsSeries(m_BarsSinceBuffer, true);
for(int i = oldSize - 1; i >= 0; i--)
{
m_st_up[i + 1] = m_st_up[i];
m_st_dn[i + 1] = m_st_dn[i];
m_st_trend_calc[i + 1] = m_st_trend_calc[i];
m_buf_ATR_ST[i + 1] = m_buf_ATR_ST[i];
m_buf_MPO_Raw[i + 1] = m_buf_MPO_Raw[i];
m_buf_MPO_Smooth[i + 1] = m_buf_MPO_Smooth[i];
m_buf_RSI[i + 1] = m_buf_RSI[i];
m_LastPivLowPriceBuffer[i + 1] = m_LastPivLowPriceBuffer[i];
m_LastPivLowOscBuffer[i + 1] = m_LastPivLowOscBuffer[i];
m_LastPivHighPriceBuffer[i + 1] = m_LastPivHighPriceBuffer[i];
m_LastPivHighOscBuffer[i + 1] = m_LastPivHighOscBuffer[i];
m_LastTypeBuffer[i + 1] = m_LastTypeBuffer[i];
m_BarsSinceBuffer[i + 1] = m_BarsSinceBuffer[i];
}
m_LastBars = newSize;
return true;
}
void Update(int limit)
{
int bars = Bars();
if(bars < 3)
return;
if(limit < 0)
limit = 0;
if(limit > bars - 2)
limit = bars - 2;
for(int i = limit; i >= 0; i--)
{
m_buf_ATR_ST[i] =
iATR(m_symbol,
m_timeframe,
AST_SuperTrendPeriod,
i);
m_buf_RSI[i] =
iRSI(m_symbol,
m_timeframe,
AST_RsiPeriod,
PRICE_CLOSE,
i);
double rollingSum = 0.0;
double sumBodies = 0.0;
int mpoCount = m_MPO_Period;
if(i + mpoCount >= bars)
mpoCount = bars - i - 1;
if(mpoCount < 1)
mpoCount = 1;
for(int k = 0; k < mpoCount; k++)
{
double op = iOpen(m_symbol, m_timeframe, i + k);
double cl = iClose(m_symbol, m_timeframe, i + k);
sumBodies += MathAbs(cl - op);
}
double avgBody =
(sumBodies > 0.0)
? sumBodies / mpoCount
: m_Point;
if(avgBody <= 0.0)
avgBody = m_Point;
for(int k = 0; k < mpoCount; k++)
{
double op = iOpen(m_symbol, m_timeframe, i + k);
double cl = iClose(m_symbol, m_timeframe, i + k);
double body = MathAbs(cl - op);
double dir =
(cl > op) ? 1.0 :
(cl < op) ? -1.0 :
0.0;
double weight =
(avgBody > 0.0)
? body / avgBody
: 1.0;
rollingSum += dir * weight;
}
m_buf_MPO_Raw[i] =
(rollingSum / (mpoCount * 2.0)) * 100.0;
if(i + 1 < bars)
{
m_buf_MPO_Smooth[i] =
(m_buf_MPO_Raw[i] * m_SmoothAlpha) +
(m_buf_MPO_Smooth[i + 1] * (1.0 - m_SmoothAlpha));
}
else
{
m_buf_MPO_Smooth[i] = m_buf_MPO_Raw[i];
}
bool isPivLow = false;
bool isPivHigh = false;
int pIdx = i + m_DivPivotLen;
if(pIdx >= 0 && pIdx < bars)
{
isPivLow = true;
isPivHigh = true;
for(int j = 1; j <= m_DivPivotLen; j++)
{
if(pIdx + j < bars)
{
double low1 = iLow(m_symbol, m_timeframe, pIdx);
double low2 = iLow(m_symbol, m_timeframe, pIdx + j);
double high1 = iHigh(m_symbol, m_timeframe, pIdx);
double high2 = iHigh(m_symbol, m_timeframe, pIdx + j);
if(low1 >= low2)
isPivLow = false;
if(high1 <= high2)
isPivHigh = false;
}
if(pIdx - j >= 0 && pIdx - j < bars)
{
double low1 = iLow(m_symbol, m_timeframe, pIdx);
double low2 = iLow(m_symbol, m_timeframe, pIdx - j);
double high1 = iHigh(m_symbol, m_timeframe, pIdx);
double high2 = iHigh(m_symbol, m_timeframe, pIdx - j);
if(low1 >= low2)
isPivLow = false;
if(high1 <= high2)
isPivHigh = false;
}
}
}
if(i + 1 < bars)
{
m_LastPivLowPriceBuffer[i] = m_LastPivLowPriceBuffer[i + 1];
m_LastPivLowOscBuffer[i] = m_LastPivLowOscBuffer[i + 1];
m_LastPivHighPriceBuffer[i] = m_LastPivHighPriceBuffer[i + 1];
m_LastPivHighOscBuffer[i] = m_LastPivHighOscBuffer[i + 1];
m_LastTypeBuffer[i] = m_LastTypeBuffer[i + 1];
m_BarsSinceBuffer[i] = m_BarsSinceBuffer[i + 1] + 1.0;
}
if(isPivLow)
{
double oscValPiv =
(AST_DivSource == 0)
? m_buf_MPO_Smooth[pIdx]
: m_buf_RSI[pIdx];
double pivotLow =
iLow(m_symbol, m_timeframe, pIdx);
if(m_LastPivLowPriceBuffer[i + 1] != 0.0 &&
pivotLow < m_LastPivLowPriceBuffer[i + 1] &&
oscValPiv > m_LastPivLowOscBuffer[i + 1])
{
m_LastTypeBuffer[i] = 1.0;
m_BarsSinceBuffer[i] = 0.0;
}
m_LastPivLowPriceBuffer[i] = pivotLow;
m_LastPivLowOscBuffer[i] = oscValPiv;
Показано первые 50% кода (символов: 10946)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.