← К каталогу
Исходный код · ID 4296

shk_ha_grid_ea.mq5

Похожие материалы по тегам

#__slope direction line.mq5MQL5 / MetaTrader 5 · 1 общих теговrange breakout @meowforex1.pineTradingView · 1 общих тегов#1.mtf_collider_h4_close_13_v18bar.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit3.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit2.mq4MQL4 / MetaTrader 4 · 1 общих тегов!mth_fasttmaline_edit.mq4MQL4 / MetaTrader 4 · 1 общих тегов
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

SHK HA Grid EA — это самодостаточный торговый советник для MetaTrader 5, в который встроен движок сигналов на основе свечей Хайлин Аши и дивергенции MACD. Советник не требует внешних индикаторных файлов: вся логика расчёта индикаторов Хайлин Аши и MACD реализована непосредственно в коде.

Сигналы формируются на закрытых барах, что обеспечивает режим без перерисовок. Доступны два режима генерации сигналов: торговля при подтверждённом изменении цвета HA-свечей и режим импульсов с ожиданием пробоя. Дополнительно доступна фильтрация сигналов по тренду через скользящую среднюю более высокого таймфрейма.

Советник поддерживает управление позицией фиксированным лотом или риском в процентах от баланса, стоп-лосс и тейк-профит в пунктах или через ATR, трейлинг-стоп, а также модуль сетки/усреднения с несколькими режимами закрытия корзины. Реализованы всплывающие, push-уведомления и звуковые оповещения.

Настройки программы

НастройкаОписание
I1 Заголовок раздела настроек движка сигналов (встроенный HA + MACD дивергенция).
InpMaxBarsToCalculate Количество баров истории для пересчёта состояния сигнала при каждом новом баре.
InpUseClosedBarsOnly Режим без перерисовок: сигналы формируются только на полностью закрытых барах.
InpConfirmationCandles Количество последовательных одноцветных свечей Хайлин Аши, необходимых для подтверждения сигнала (от 1 до 10).
InpMinBodyPercent Минимальный процент тела свечи Хайлин Аши для подтверждения сигнала.
InpSignalOnHAColorChange true — торговля при подтверждённом изменении цвета HA-свечей; false — режим импульсов с ожиданием пробоя.
InpRequireMACDDivergence Обязательное наличие дивергенции MACD для формирования сигнала.
InpMACDFastEMA Период быстрой EMA для расчёта индикатора MACD.
InpMACDSlowEMA Период медленной EMA для расчёта индикатора MACD.
InpMACDSignalEMA Период сигнальной EMA для расчёта индикатора MACD.
InpDivergencePivotLookback Глубина поиска пивотов для определения дивергенции MACD.
InpDivergenceSearchBars Количество баров назад для поиска предыдущих пивотов при расчёте дивергенции MACD.
InpDivergenceConfirmWindow Количество баров назад для проверки наличия подтверждённой дивергенции MACD.
InpRequireStrongCandleForCircle Требование сильной свечи для инициации импульсного сигнала (используется только в режиме импульсов).
InpCancelSignalOnOppositeHA Отмена ожидающегося сигнала при появлении свечи противоположного цвета HA (используется только в режиме импульсов).
InpConfirmByCloseBreak Подтверждение сигнала импульса пробоем цены (true) или по закрытию бара (false), используется только в режиме импульсов.
I1b Заголовок раздела настроек фильтра тренда.
InpUseTrendFilter Включение фильтра тренда для подавления сигналов, противоречащих текущему тренду.
InpTrendMATimeframe Таймфрейм для расчёта скользящей средней фильтра тренда (рекомендуется более высокий таймфрейм).
InpTrendMAPeriod Период скользящей средней для фильтра тренда.
InpTrendMAMethod Метод расчёта скользящей средней для фильтра тренда.
I2 Заголовок раздела настроек торговли.
InpMagic Магический номер для идентификации позиций, открытых советником.
InpTradeComment Комментарий к торговым операциям, открытым советником.
InpTradeDirection Направление торговли: обе стороны, только покупка или только продажа.
InpSlippagePoints Допустимое проскальзывание в пунктах при исполнении торговых операций.
InpMaxSpreadPoints Максимально допустимый спред в пунктах (0 — проверка спреда отключена).
InpCloseOnOppositeSignal Закрытие текущих позиций при появлении сигнала противоположного направления.
I3 Заголовок раздела настроек управления позицией.
InpFixedLots Фиксированный объём позиции (используется при нулевом значении риска в процентах).
InpRiskPercent Процент риска от баланса на одну сделку (0 — используется фиксированный лот).
I4 Заголовок раздела настроек стоп-лосса и тейк-профита.
InpUseATRForSLTP Использование ATR вместо фиксированных пунктов для расчёта стоп-лосса и тейк-профита.
InpATRPeriod Период индикатора ATR для расчёта стоп-лосса и тейк-профита.
InpATRMultiplierSL Множитель ATR для расчёта стоп-лосса (при использовании ATR вместо фиксированных пунктов).
InpATRMultiplierTP Множитель ATR для расчёта тейк-профита (при использовании ATR вместо фиксированных пунктов).
InpStopLossPips Стоп-лосс в пунктах (при использовании фиксированных значений).
InpTakeProfitPips Тейк-профит в пунктах (при использовании фиксированных значений).
I5 Заголовок раздела настроек трейлинг-стопа.
InpUseTrailingStop Включение трейлинг-стопа для открытых позиций.
InpTrailingStartPips Прибыль в пунктах, после которой активируется трейлинг-стоп.
InpTrailingStopPips Расстояние трейлинг-стопа от текущей цены в пунктах.
InpTrailingStepPips Шаг трейлинг-стопа в пунктах.
I6 Заголовок раздела настроек сетки и усреднения.
InpGridEnabled Включение модуля сетки/усреднения.
InpGridStepPips Расстояние между уровнями сетки в пунктах.
InpGridMaxLevels Максимальное количество уровней сетки, включая начальную позицию.
InpGridLotMultiplier Множитель объёма для каждого дополнительного уровня сетки.
InpGridUseIndividualSL Установка индивидуального широкого стоп-лосса на каждую сеточную позицию.
InpGridIndividualSLPips Ширина индивидуального стоп-лосса для каждой сеточной позиции в пунктах.
InpGridTPMode Режим закрытия корзины: по каждой позиции отдельно, по денежному итогу корзины или по пунктам от средней цены входа.
InpGridBasketTakeProfitMoney Суммарный тейк-профит корзины в денежном эквиваленте аккаунтной валюты (используется при режиме BASKET_MONEY).
InpGridBasketStopLossMoney Суммарный стоп-лосс корзины в денежном эквиваленте аккаунтной валюты (0 — отключено).
InpGridBasketTakeProfitPips Тейк-профит корзины в пунктах от средней цены входа (используется при режиме BASKET_PIPS).
I7 Заголовок раздела настроек оповещений.
InpEnablePopupAlert Включение всплывающих оповещений при подтверждении сигнала.
InpEnablePushAlert Включение push-уведомлений при подтверждении сигнала.
InpEnableSoundAlert Включение звуковых оповещений при подтверждении сигнала.
InpBuySoundFile Файл звукового оповещения для сигналов на покупку.
InpSellSoundFile Файл звукового оповещения для сигналов на продажу.
InpAlertCooldownSeconds Задержка в секундах между повторными оповещениями одного направления.
Получить полный код

Поиск по коду файла

#property version   "2.00"
#property description "Self-contained EA: embedded SHK Heikin Ashi + MACD divergence signal engine, SL/TP, trailing stop and grid/averaging module."
#property strict

#include <Trade\Trade.mqh>

enum ENUM_TRADE_DIRECTION
{
   DIR_BOTH      = 0,   // Buy and Sell
   DIR_BUY_ONLY  = 1,   // Buy only
   DIR_SELL_ONLY = 2    // Sell only
};

enum ENUM_GRID_TP_MODE
{
   GRID_TP_PER_TRADE      = 0,  // Each grid trade has its own TP
   GRID_TP_BASKET_MONEY   = 1,  // Close whole basket at target profit (account currency)
   GRID_TP_BASKET_PIPS    = 2   // Close whole basket when price reaches X pips from average entry
};

input string I1 = "====== Signal Engine (embedded HA + MACD divergence) ======"; // ---
input int    InpMaxBarsToCalculate       = 3000;    // history window used to rebuild the signal state each bar
input bool   InpUseClosedBarsOnly        = true;    // non-repaint: only ever act on a fully closed bar
input int    InpConfirmationCandles      = 1;       // 1 to 10, consecutive same-color HA candles required
input double InpMinBodyPercent           = 0.0;
input bool   InpSignalOnHAColorChange    = true;    // true = trade on confirmed HA color flip; false = momentum/pending-breakout mode
input bool   InpRequireMACDDivergence    = true;
input int    InpMACDFastEMA              = 12;
input int    InpMACDSlowEMA              = 26;
input int    InpMACDSignalEMA            = 5;
input int    InpDivergencePivotLookback  = 2;
input int    InpDivergenceSearchBars     = 200;
input int    InpDivergenceConfirmWindow  = 30;
input bool   InpRequireStrongCandleForCircle = false; // only used in momentum mode (InpSignalOnHAColorChange = false)
input bool   InpCancelSignalOnOppositeHA = true;      // only used in momentum mode
input bool   InpConfirmByCloseBreak      = true;      // only used in momentum mode

input string I1b = "====== Trend Filter (recommended) ======"; // ---
input bool   InpUseTrendFilter           = true;    // suppress signals that fight the prevailing trend
input ENUM_TIMEFRAMES InpTrendMATimeframe= PERIOD_CURRENT; // use a higher timeframe (e.g. H1) for a smoother read
input int    InpTrendMAPeriod            = 200;
input ENUM_MA_METHOD InpTrendMAMethod    = MODE_EMA;

input string I2 = "====== Trading ======"; // ---
input ulong  InpMagic                    = 20260815;
input string InpTradeComment             = "SHK-HA-EA";
input ENUM_TRADE_DIRECTION InpTradeDirection = DIR_BOTH;
input int    InpSlippagePoints           = 30;
input double InpMaxSpreadPoints          = 0;      // 0 = disabled
input bool   InpCloseOnOppositeSignal    = true;

input string I3 = "====== Position Sizing ======"; // ---
input double InpFixedLots                = 0.01;   // used when InpRiskPercent = 0
input double InpRiskPercent              = 0.0;     // 0 = use fixed lots, otherwise % balance risk per trade based on SL distance

input string I4 = "====== Stop Loss / Take Profit ======"; // ---
input bool   InpUseATRForSLTP            = false;
input int    InpATRPeriod                = 14;
input double InpATRMultiplierSL          = 2.0;
input double InpATRMultiplierTP          = 3.0;
input double InpStopLossPips             = 50;
input double InpTakeProfitPips           = 100;

input string I5 = "====== Trailing Stop ======"; // ---
input bool   InpUseTrailingStop          = false;
input double InpTrailingStartPips        = 30;
input double InpTrailingStopPips         = 20;
input double InpTrailingStepPips         = 5;

input string I6 = "====== Grid / Averaging ======"; // ---
input bool   InpGridEnabled              = false;
input double InpGridStepPips             = 200;     // distance between grid levels
input int    InpGridMaxLevels            = 5;        // includes the initial trade
input double InpGridLotMultiplier        = 1.5;      // lot multiplier per additional level
input bool   InpGridUseIndividualSL      = true;     // safety SL on every grid trade (wide)
input double InpGridIndividualSLPips     = 300;
input ENUM_GRID_TP_MODE InpGridTPMode    = GRID_TP_BASKET_MONEY;
input double InpGridBasketTakeProfitMoney= 10.0;      // account currency, used if mode = BASKET_MONEY
input double InpGridBasketStopLossMoney  = 0.0;       // 0 = disabled, account currency
input double InpGridBasketTakeProfitPips = 50;        // pips from average entry, used if mode = BASKET_PIPS

input string I7 = "====== Alerts ======"; // ---
input bool   InpEnablePopupAlert         = true;
input bool   InpEnablePushAlert          = false;
input bool   InpEnableSoundAlert         = false;
input string InpBuySoundFile             = "alert.wav";
input string InpSellSoundFile            = "alert2.wav";
input int    InpAlertCooldownSeconds     = 120;

#define MOM_BODY_WINDOW   14
#define CIRCLE_WICK_FRAC  0.15

CTrade   trade;

int      g_atrHandle    = INVALID_HANDLE;
int      g_trendMAHandle = INVALID_HANDLE;

double   g_point        = 0.0;
double   g_pip          = 0.0;   // pip size (10 * point on 3/5-digit symbols)

datetime g_lastBarTime   = 0;
int      g_confCandles   = 1;

int      g_basketDir     = 0;     // 0 = none, 1 = buy, -1 = sell
double   g_basketEntryPx = 0.0;   // price of the very first grid entry
int      g_basketLevels  = 0;     // number of grid levels filled so far

datetime g_lastAlertBarTime = 0;
int      g_lastAlertDir     = 0;
datetime g_lastAlertWall    = 0;

double   eHAOpen[];
double   eHAHigh[];
double   eHALow[];
double   eHAClose[];

double   eMacdFast[];
double   eMacdSlow[];
double   eMacdSignal[];
double   eMacdHist[];
bool     eBullDiv[];
bool     eBearDiv[];

int      eFirstBar = 1;

bool     eBuyPending  = false;
double   eBuyRefHigh  = 0.0;
int      eBuyBarsLeft = 0;

bool     eSellPending = false;
double   eSellRefLow  = 0.0;
int      eSellBarsLeft= 0;

string GV_Dir()    { return StringFormat("SHK_HA_EA_%s_%I64u_Dir",    _Symbol, InpMagic); }
string GV_Entry()  { return StringFormat("SHK_HA_EA_%s_%I64u_Entry",  _Symbol, InpMagic); }
string GV_Levels() { return StringFormat("SHK_HA_EA_%s_%I64u_Levels", _Symbol, InpMagic); }

void SaveBasketState()
{
   GlobalVariableSet(GV_Dir(),    (double)g_basketDir);
   GlobalVariableSet(GV_Entry(),  g_basketEntryPx);
   GlobalVariableSet(GV_Levels(), (double)g_basketLevels);
}

void LoadBasketState()
{
   g_basketDir     = GlobalVariableCheck(GV_Dir())    ? (int)GlobalVariableGet(GV_Dir())    : 0;
   g_basketEntryPx = GlobalVariableCheck(GV_Entry())  ? GlobalVariableGet(GV_Entry())        : 0.0;
   g_basketLevels  = GlobalVariableCheck(GV_Levels()) ? (int)GlobalVariableGet(GV_Levels())  : 0;
}

void ClearBasketState()
{
   g_basketDir     = 0;
   g_basketEntryPx = 0.0;
   g_basketLevels  = 0;
   if(GlobalVariableCheck(GV_Dir()))    GlobalVariableDel(GV_Dir());
   if(GlobalVariableCheck(GV_Entry()))  GlobalVariableDel(GV_Entry());
   if(GlobalVariableCheck(GV_Levels())) GlobalVariableDel(GV_Levels());
}

bool EIsBullishHA(const int i) { return(eHAClose[i] > eHAOpen[i]); }
bool EIsBearishHA(const int i) { return(eHAClose[i] < eHAOpen[i]); }

double EGetBodyPercent(const int i)
{
   double range = eHAHigh[i] - eHALow[i];
   if(range <= 0.0) return(0.0);
   return(MathAbs(eHAClose[i] - eHAOpen[i]) / range * 100.0);
}

double EAvgHABody(const int i, const int win, const int firstBar)
{
   int st = i - win;
   if(st < firstBar) return(0.0);
   double s = 0.0; int c = 0;
   for(int k = st; k < i; k++) { s += MathAbs(eHAClose[k] - eHAOpen[k]); c++; }
   return(c > 0 ? s / c : 0.0);
}

void EComputeHABar(const int i, const MqlRates &r[])
{
   double haClose = (r[i].open + r[i].high + r[i].low + r[i].close) / 4.0;
   double haOpen  = (eHAOpen[i - 1] + eHAClose[i - 1]) / 2.0;
   double haHigh  = MathMax(r[i].high, MathMax(haOpen, haClose));
   double haLow   = MathMin(r[i].low,  MathMin(haOpen, haClose));
   eHAOpen[i] = haOpen; eHAClose[i] = haClose; eHAHigh[i] = haHigh; eHALow[i] = haLow;
}

void EInitHASeed(const int firstBar, const MqlRates &r[])
{
   double haClose = (r[firstBar].open + r[firstBar].high + r[firstBar].low + r[firstBar].close) / 4.0;
   double haOpen  = (r[firstBar].open + r[firstBar].close) / 2.0;
   eHAClose[firstBar] = haClose;
   eHAOpen[firstBar]  = haOpen;
   eHAHigh[firstBar]  = MathMax(r[firstBar].high, MathMax(haOpen, haClose));
   eHALow[firstBar]   = MathMin(r[firstBar].low,  MathMin(haOpen, haClose));
}

bool EIsMacdPeak(const int i, const int lookback, const int firstBar, const int lastBar)
{
   if(i - lookback < firstBar || i + lookback > lastBar) return(false);
   for(int k = 1; k <= lookback; k++)
      if(eMacdHist[i] <= eMacdHist[i - k] || eMacdHist[i] <= eMacdHist[i + k]) return(false);
   return(true);
}

bool EIsMacdTrough(const int i, const int lookback, const int firstBar, const int lastBar)
{
   if(i - lookback < firstBar || i + lookback > lastBar) return(false);
   for(int k = 1; k <= lookback; k++)
      if(eMacdHist[i] >= eMacdHist[i - k] || eMacdHist[i] >= eMacdHist[i + k]) return(false);
   return(true);
}

void EComputeMACDDivergence(const int rates_total, const int firstBar, const int lastClosed, const MqlRates &r[])
{
   ArrayResize(eMacdFast, rates_total);
   ArrayResize(eMacdSlow, rates_total);
   ArrayResize(eMacdSignal, rates_total);
   ArrayResize(eMacdHist, rates_total);
   ArrayResize(eBullDiv, rates_total);
   ArrayResize(eBearDiv, rates_total);

   for(int i = 0; i < rates_total; i++)
   {
      eMacdFast[i] = 0.0; eMacdSlow[i] = 0.0; eMacdSignal[i] = 0.0; eMacdHist[i] = 0.0;
      eBullDiv[i] = false; eBearDiv[i] = false;
   }

   if(!InpRequireMACDDivergence) return;

   int fast = InpMACDFastEMA, slow = InpMACDSlowEMA, signal = InpMACDSignalEMA;
   int pivotLookback = InpDivergencePivotLookback, searchBars = InpDivergenceSearchBars;
   if(fast < 1) fast = 1;
   if(slow < 1) slow = 1;
   if(signal < 1) signal = 1;
   if(pivotLookback < 1) pivotLookback = 1;
   if(searchBars < 1) searchBars = 1;

   if(lastClosed < firstBar + pivotLookback * 2 + 2) return;

   double fastAlpha   = 2.0 / ((double)fast + 1.0);
   double slowAlpha   = 2.0 / ((double)slow + 1.0);
   double signalAlpha = 2.0 / ((double)signal + 1.0);

   for(int i = firstBar; i <= lastClosed; i++)
   {
      double price = r[i].close;
      if(i == firstBar)
      {
         eMacdFast[i] = price; eMacdSlow[i] = price; eMacdSignal[i] = 0.0; eMacdHist[i] = 0.0;
         continue;
      }
      eMacdFast[i]   = fastAlpha * price + (1.0 - fastAlpha) * eMacdFast[i - 1];
      eMacdSlow[i]   = slowAlpha * price + (1.0 - slowAlpha) * eMacdSlow[i - 1];
      double macdMain = eMacdFast[i] - eMacdSlow[i];
      eMacdSignal[i] = signalAlpha * macdMain + (1.0 - signalAlpha) * eMacdSignal[i - 1];
      eMacdHist[i]   = macdMain - eMacdSignal[i];
   }

   int lastPivot = lastClosed - pivotLookback;
   for(int i = firstBar + pivotLookback; i <= lastPivot; i++)
   {
      if(EIsMacdTrough(i, pivotLookback, firstBar, lastClosed))
      {
         int prevTrough = -1;
         int oldest = i - searchBars;
         if(oldest < firstBar + pivotLookback) oldest = firstBar + pivotLookback;
         for(int j = i - 1; j >= oldest; j--)
            if(EIsMacdTrough(j, pivotLookback, firstBar, lastClosed)) { prevTrough = j; break; }

         if(prevTrough >= 0 && r[i].low < r[prevTrough].low && eMacdHist[i] > eMacdHist[prevTrough])
            eBullDiv[i + pivotLookback] = true;
      }

      if(EIsMacdPeak(i, pivotLookback, firstBar, lastClosed))
      {
         int prevPeak = -1;
         int oldest = i - searchBars;
         if(oldest < firstBar + pivotLookback) oldest = firstBar + pivotLookback;
         for(int j = i - 1; j >= oldest; j--)
            if(EIsMacdPeak(j, pivotLookback, firstBar, lastClosed)) { prevPeak = j; break; }

         if(prevPeak >= 0 && r[i].high > r[prevPeak].high && eMacdHist[i] < eMacdHist[prevPeak])
            eBearDiv[i + pivotLookback] = true;
      }
   }
}

bool ERecentMACDDivergenceConfirmed(const int i, const bool bullish)
{
   if(!InpRequireMACDDivergence) return(true);
   int window = InpDivergenceConfirmWindow;
   if(window < 0) window = 0;
   int first = i - window;
   if(first < eFirstBar) first = eFirstBar;
   for(int k = i; k >= first; k--)
   {
      if(bullish && eBullDiv[k])  return(true);
      if(!bullish && eBearDiv[k]) return(true);
   }
   return(false);
}

bool EHasConfirmedHAColorChange(const int i, const bool bullish)
{
   int candles = g_confCandles;
   if(candles < 1) candles = 1;
   int runStart = i - candles + 1;
   int previous = runStart - 1;
   if(runStart < eFirstBar + 1 || previous < eFirstBar) return(false);

   for(int k = runStart; k <= i; k++)
   {
      if(bullish && !EIsBullishHA(k)) return(false);
      if(!bullish && !EIsBearishHA(k)) return(false);
      if(EGetBodyPercent(k) < InpMinBodyPercent) return(false);
   }
   if(bullish) return(EIsBearishHA(previous));
   return(EIsBullishHA(previous));
}

int EProcessColorChangeArrow(const int i)
{
   if(EHasConfirmedHAColorChange(i, true) && ERecentMACDDivergenceConfirmed(i, true))
      return(+1);
   if(EHasConfirmedHAColorChange(i, false) && ERecentMACDDivergenceConfirmed(i, false))
      return(-1);
   return(0);
}

int EProcessMomentumBranch(const int i)
{
   bool curBull  = EIsBullishHA(i);
   bool curBear  = EIsBearishHA(i);
   bool prevBull = EIsBullishHA(i - 1);
   bool prevBear = EIsBearishHA(i - 1);

   bool placedBuyArrow = false, placedSellArrow = false;
   int  fired = 0;

   if(eBuyPending)
   {
      if(InpCancelSignalOnOppositeHA && curBear)
      {
         eBuyPending = false;
      }
      else
      {
         bool brk = InpConfirmByCloseBreak ? (eHAClose[i] > eBuyRefHigh) : (eHAHigh[i] > eBuyRefHigh);
         if(brk)
         {
            placedBuyArrow = true;
            eBuyPending = false;
            fired = +1;
         }
         else
         {
            eBuyBarsLeft--;
            if(eBuyBarsLeft <= 0) eBuyPending = false;
         }
      }
   }

   if(eSellPending)
   {
      if(InpCancelSignalOnOppositeHA && curBull)
      {
         eSellPending = false;
      }
      else
      {
         bool brk = InpConfirmByCloseBreak ? (eHAClose[i] < eSellRefLow) : (eHALow[i] < eSellRefLow);
         if(brk && !placedBuyArrow)
         {
            placedSellArrow = true;
            eSellPending = false;
            fired = -1;
         }
         else
         {
            eSellBarsLeft--;
            if(eSellBarsLeft <= 0) eSellPending = false;
         }
      }
   }

   double bodyPct = EGetBodyPercent(i);
   double avgBody = EAvgHABody(i, MOM_BODY_WINDOW, eFirstBar);
   double range   = eHAHigh[i] - eHALow[i];
   double body    = MathAbs(eHAClose[i] - eHAOpen[i]);

   if(prevBear && curBull && !placedSellArrow)
   {
      bool ok = (bodyPct >= InpMinBodyPercent);
      if(ok && InpRequireStrongCandleForCircle)
      {
         double lowerWick = MathMin(eHAOpen[i], eHAClose[i]) - eHALow[i];
         bool strong = (range > 0.0 && lowerWick <= CIRCLE_WICK_FRAC * range) ||
                       (avgBody > 0.0 && body >= avgBody);
         ok = strong;
      }
      if(ok)
      {
         eBuyPending  = true;
         eBuyRefHigh  = eHAHigh[i];
         eBuyBarsLeft = g_confCandles;
      }
   }
   else if(prevBull && curBear && !placedBuyArrow)
   {
      bool ok = (bodyPct >= InpMinBodyPercent);
      if(ok && InpRequireStrongCandleForCircle)
    

Показано первые 50% кода (символов: 23519)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
2 351,90₽ ≈ $28.74