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

Quasimodo (QM) Pattern EA

quasimodo_fqml_pattern_ea.mq5
Вы автор или правообладатель?

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

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

О программе

Данный советник для MetaTrader 5 реализует торговую стратегию на основе паттерна Quasimodo (QM). Он автоматически определяет swing pivot точки на графике с настраиваемым лукбэком и выявляет паттерны H-L-H-L (медвежий) или L-H-L-H (бычий), после чего выставляет сделку при ретрейсе цены к QM-линии (уровню плеча).

Советник поддерживает два режима входа: прямое срабатывание при пробитии QM-линии и режим ожидания отката (rejection close), при котором требуется возврат цены обратно через линию. Также доступна альтернативная Entry 2 — вход по закрытию последнего свечного противоположного цвета в точке Head.

Управление риском включает стоп-лосс с буфером за Head и опциональное расширение до ATR-флоора, тейк-профит по соотношению R:R или структурной цели, перевод в безубыток, трейлинг-стоп (по ATR или фиксированным пунктам) и частичное закрытие позиции. Лотирование поддерживает фиксированный размер и расчёт по проценту риска от баланса.

Советник рисует на графике структуру QM-паттерна, уровни входа/стопа/тейк-профита, маркеры swing-точек и линии предшествующего тренда, а также ведёт журнал событий с настраиваемым префиксом.

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

НастройкаОписание
InpMagicNumber Уникальный идентификатор (Magic Number) для отслеживания позиций, открытых данным советником.
InpOrderComment Комментарий, присваиваемый каждой открытой позиции.
InpTradeDirection Разрешённое направление торговли: обе стороны, только покупки или только продажи.
InpAllowMultipleTrades Разрешает одновременное открытие нескольких сделок. При значении False советник закрывает поиск новых паттернов, пока имеется хотя бы одна открытая позиция.
InpShowLogs При включении выводит сообщения советника в журнал (Journal).
InpLogPrefix Префикс, добавляемый к сообщениям в журнале.
InpLotSizingMode Режим расчёта размера лота: фиксированный лот или расчёт по проценту риска от баланса.
InpFixedLots Фиксированный объём лота при использовании режима фиксированного лотирования.
InpRiskPercent Процент баланса, рискуемый на одну сделку при использовании режима расчёта лота по риску.
InpSwingLookback Количество баров с каждой стороны, используемых для подтверждения swing pivot.
InpEntryBufferPoints Количество пунктов, на которые цена должна пройти за QM-линией для подтверждения входа.
InpWaitForRejectionClose При включении требует отката цены обратно через QM-линию после её пробития перед входом в сделку.
InpUseEntry2 При включении активирует альтернативный Entry 2: вход по закрытию последнего свечного противоположного цвета в точке Head.
InpMaxWaitBars Максимальное количество баров ожидания ретрейса до отмены вооружённой настройки.
InpMinRewardRisk Минимальное допустимое соотношение прибыль/риск (R:R). Настройки с меньшим значением пропускаются.
InpSkipSharedShoulder При включении пропускает новую настройку, которая использует тот же самый Left Shoulder, что и предыдущая.
InpRequirePriorTrend При включении требует наличия подтверждённого предшествующего тренда перед плечом паттерна.
InpTrendPivots Количество swing pivot позади Left Shoulder, используемых для подтверждения предшествующего тренда.
InpStopBufferPoints Количество пунктов буфера за Head, до которого рассчитывается структурный стоп-лосс.
InpUseAtrStopFloor При включении расширяет стоп-лосс до ATR-флоора, если структурный стоп слишком узкий.
InpAtrPeriod Период расчёта индикатора ATR, используемого для определения стоп-флоора и ATR-трейлинга.
InpAtrStopMultiplier Множитель ATR для расширения стопа до ATR-флоора при слишком узком структурном стопе.
InpTakeProfitMode Режим расчёта тейк-профита: по соотношению R:R или по структурной цели (broken swing extreme).
InpRewardRiskRatio Соотношение прибыль/риск (R:R) для расчёта тейк-профита в режиме R:R.
InpUseBreakeven При включении автоматически переводит стоп-лосс в безубыток при достижении определённой прибыли.
InpBreakevenAtRR Прибыль в R, при которой стоп перемещается в безубыток.
InpBreakevenLockPoints Количество пунктов, которые должны быть зафиксированы сверх точки входа для активации безубытка.
InpTrailingMode Метод трейлинг-стопа для запущенной позиции: выключен, ATR-расстояние или фиксированные пункты.
InpTrailStartRR Прибыль в R, при которой начинается ATR-трейлинг.
InpTrailAtrMultiplier Множитель ATR для расчёта расстояния трейлинг-стопа в ATR-режиме.
InpTrailLockPoints Минимальная фиксированная прибыль в пунктах, необходимая для начала трейлинга.
InpTrailDistancePoints Расстояние трейлинг-стопа от цены в пунктах в режиме фиксированных пунктов.
InpUsePartialClose При включении выполняет частичное закрытие позиции при достижении первой цели.
InpPartialAtRR Уровень прибыли в R, при котором выполняется частичное закрытие позиции.
InpPartialPercent Процент позиции, закрываемый при частичном выходе.
InpDrawVisuals Включает отрисовку структуры QM на графике: линии плеча, ноги, Head, BOS, QM-линию и уровни входа.
InpShowSwingMarkers Включает отрисовку подписанных маркеров swing-точек (H/HH/LH, L/LL/HL) на графике.
InpLoadHistorySwings При включении при загрузке сканирует историю графика и помечает исторические swing-точки (H/HH/LH/L/LL/HL), а также восстанавливает QM-паттерны из прошлого.
InpSwingHistoryBars Количество баров истории, которое сканируется при загрузке для маркировки исторических swing-точек.
InpBullColor Цвет визуальных элементов бычьего QM-паттерна.
InpBearColor Цвет визуальных элементов медвежьего QM-паттерна.
InpQmLineColor Цвет QM-линии (уровня входа) на графике.
InpSwingHighColor Цвет маркера swing high на графике.
InpSwingLowColor Цвет маркера swing low на графике.
InpTrendColor Цвет линий, соединяющих swing pivot для отображения предшествующего тренда.
Получить полный код

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

#property version   "1.00"

#define EA_VERSION "1.00"

#include <Trade\Trade.mqh>

enum LotSizingMode
  {
   LOTS_FIXED,        // Fixed lot size
   LOTS_RISK_PERCENT  // Risk percent of balance (auto lot)
  };

enum TakeProfitMode
  {
   TP_REWARD_RISK,    // Reward-to-risk multiple
   TP_STRUCTURE       // Structural broken-swing extreme
  };

enum TrailingMode
  {
   TRAIL_OFF,         // No trailing
   TRAIL_ATR,         // ATR distance behind price
   TRAIL_POINTS       // Fixed points behind price
  };

enum TradeDirection
  {
   TRADE_BOTH,        // Both directions
   TRADE_BUYS_ONLY,   // Bullish QM only (buys)
   TRADE_SELLS_ONLY   // Bearish QM only (sells)
  };

input group "GENERAL"
input long           InpMagicNumber           = 1107;              // Magic number (unique ID for this EA)
input string         InpOrderComment          = "QM";              // Order comment
input TradeDirection InpTradeDirection        = TRADE_BOTH;        // Allowed trade direction
input bool           InpAllowMultipleTrades   = false;             // Allow several open trades at once
input bool           InpShowLogs              = true;              // Print log messages to the Journal
input string         InpLogPrefix             = "QM> ";            // Log prefix

input group "RISK & POSITION SIZING"
input LotSizingMode  InpLotSizingMode         = LOTS_RISK_PERCENT; // Lot sizing mode
input double         InpFixedLots             = 0.01;              // Fixed lot (Fixed mode)
input double         InpRiskPercent           = 0.5;               // Risk per trade, percent of balance (Risk mode)

input group "SWING / PATTERN DETECTION"
input int            InpSwingLookback         = 5;                 // Swing pivot lookback (bars each side)
input int            InpEntryBufferPoints     = 0;                 // Points the close must clear beyond the QM line
input bool           InpWaitForRejectionClose = false;             // Wait for a confirmation close back through the QM line
input bool           InpUseEntry2             = true;               // Also arm Entry 2: close of the last opposite-colour candle at the Head
input int            InpMaxWaitBars           = 30;                // Max bars to wait for the retrace, then cancel
input double         InpMinRewardRisk         = 1.0;               // Skip setups whose target reward-to-risk is below this
input bool           InpSkipSharedShoulder    = true;              // Skip a new setup that reuses the last Left Shoulder
input bool           InpRequirePriorTrend     = true;              // Require a prior trend into the pattern
input int            InpTrendPivots           = 2;                 // Swing pivots behind the Left Shoulder to confirm the trend

input group "STOP LOSS"
input int            InpStopBufferPoints      = 200;               // Buffer beyond the Head (points)
input bool           InpUseAtrStopFloor       = true;              // Widen the stop to an ATR floor if structural stop is tight
input int            InpAtrPeriod             = 14;                // ATR period (stop floor and ATR trail)
input double         InpAtrStopMultiplier     = 1.0;               // ATR multiple for the stop floor

input group "TAKE PROFIT"
input TakeProfitMode InpTakeProfitMode        = TP_REWARD_RISK;    // Take-profit mode
input double         InpRewardRiskRatio       = 2.0;               // Reward-to-risk ratio (RR mode)

input group "TRADE MANAGEMENT"
input bool           InpUseBreakeven          = true;              // Move stop to breakeven
input double         InpBreakevenAtRR         = 1.0;               // Profit in R before breakeven
input int            InpBreakevenLockPoints   = 50;                // Points locked beyond entry at breakeven
input TrailingMode   InpTrailingMode          = TRAIL_OFF;         // Trailing-stop method for the runner
input double         InpTrailStartRR          = 1.5;               // Profit in R before ATR trailing begins
input double         InpTrailAtrMultiplier    = 2.0;               // ATR multiple for the ATR trailing distance
input int            InpTrailLockPoints       = 1000;              // Points trail: min profit (points) locked once trailing begins
input int            InpTrailDistancePoints   = 300;               // Points trail: distance behind price (points)
input bool           InpUsePartialClose       = false;             // Bank a partial at the first target
input double         InpPartialAtRR           = 1.0;               // Partial target in R
input double         InpPartialPercent        = 50.0;              // Percent of the position to close at the partial

input group "CHART VISUALS"
input bool           InpDrawVisuals           = true;              // Draw QM structure (lines, levels, arrows)
input bool           InpShowSwingMarkers      = true;              // Draw labeled swing points (H/HH/LH, L/LL/HL)
input bool           InpLoadHistorySwings    = true;              // Label historical H/HH/LH/L/LL/HL on load
input int            InpSwingHistoryBars      = 1000;              // Bars of chart history to scan on load (period look-back)
input color          InpBullColor             = clrDodgerBlue;     // Bullish QM color
input color          InpBearColor             = clrRed;            // Bearish QM color
input color          InpQmLineColor           = clrDarkViolet;     // QM line (entry) color
input color          InpSwingHighColor        = clrDarkOrange;     // Swing-high marker color
input color          InpSwingLowColor         = clrDodgerBlue;     // Swing-low marker color
input color          InpTrendColor            = clrGray;           // Prior-trend connector color

struct SwingPivot
  {
   bool     isHigh; // True when the pivot is a swing high
   double   price;  // Pivot price
   datetime time;   // Pivot bar time
  };

struct ArmedSetup
  {
   bool     isActive;      // True while the setup waits for entry
   bool     isBull;        // True for a bullish QM (buy)
   double   qmLinePrice;   // Shoulder price, the entry level (QM line)
   double   headPrice;     // Head price, the invalidation and stop anchor
   double   targetPrice;   // Structural target (broken swing extreme)
   double   legPrice;      // Broken leg level (for the BOS drawing)
   datetime shoulderTime;  // Left-shoulder bar time
   datetime legTime;       // Leg bar time
   datetime headTime;      // Head bar time
   datetime bosTime;       // Break-of-structure bar time
   double   shoulderPrice; // Left-shoulder price
   datetime armedTime;     // Bar time the setup was armed (expiry base)
   bool     lineBroken;    // True once price closed beyond the QM line (rejection step 1)
   double   entry2Price;   // Entry 2: close of the last opposite-colour candle at the Head swing
   bool     entry2Valid;   // True when an Entry 2 candle was actually found
   bool     entry2Broken;  // True once price closed beyond Entry 2 (rejection step 1)
  };

struct TradeRecord
  {
   ulong  ticket;       // Position ticket
   bool   isBull;       // True for a buy
   double entryPrice;   // Fill price
   double initialStop;  // Initial stop price
   double riskDistance; // Distance between entry and the initial stop
   bool   partialTaken; // True once the partial has been banked
  };

CTrade   Trade;                       // Trade execution object
int      SymDigits;                   // Symbol digits
double   SymPoint;                    // Symbol point size
int      AtrHandle = INVALID_HANDLE;  // ATR indicator handle
datetime g_lastBarTime = 0;           // Time of the last processed bar

SwingPivot g_pivots[];                // Alternating H/L zig-zag of confirmed pivots
int        g_maxPivots = 24;          // Max zig-zag pivots to retain

double   g_lastLabeledHigh = 0.0;     // Last labeled swing-high price
datetime g_lastLabeledHighTime = 0;   // Last labeled swing-high time
double   g_lastLabeledLow = 0.0;      // Last labeled swing-low price
datetime g_lastLabeledLowTime = 0;    // Last labeled swing-low time

ArmedSetup g_setup;                   // Current armed QM setup
datetime g_lastArmedBosTime = 0;      // Guard against re-arming the same pattern
datetime g_lastArmedShoulderTime = 0; // Guard against reusing the same Left Shoulder

TradeRecord g_trades[];               // Per-ticket trade records

bool     g_replayMode = false;        // True while replaying past bars on init (suppresses log spam)

void Log(string message)
  {

   if(InpShowLogs && !g_replayMode) Print(InpLogPrefix + message);
  }

bool VisualsAllowed()
  {

   if(MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE)) return false;

   return true;
  }

bool IsNewBar()
  {

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

   if(currentBarTime != g_lastBarTime)
     {

      g_lastBarTime = currentBarTime;
      return true;
     }

   return false;
  }

double IndicatorValue(int handle, int buffer, int shift)
  {

   double values[];

   if(CopyBuffer(handle, buffer, shift, 1, values) < 1) return EMPTY_VALUE;

   return values[0];
  }

bool IsDirectionAllowed(bool isBull)
  {

   if(InpTradeDirection == TRADE_BOTH) return true;

   if(InpTradeDirection == TRADE_BUYS_ONLY) return isBull;

   return !isBull;
  }

double CalcLotsByRisk(double entry, double stop)
  {

   double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * InpRiskPercent / 100.0;

   double stopPoints = MathAbs(entry - stop) / SymPoint;

   if(stopPoints <= 0) return 0;

   double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double tickSize  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

   if(tickValue <= 0 || tickSize <= 0) return 0;

   double valuePerPoint = tickValue / tickSize * SymPoint;

   if(valuePerPoint <= 0) return 0;

   double lots = riskMoney / (stopPoints * valuePerPoint);

   double volMin  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double volMax  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double volStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(volStep > 0) lots = MathFloor(lots / volStep) * volStep;

   return NormalizeDouble(MathMax(volMin, MathMin(volMax, lots)), 2);
  }

int FindTradeRecord(ulong ticket)
  {

   for(int i = 0; i < ArraySize(g_trades); i++)

      if(g_trades[i].ticket == ticket) return i;

   return -1;
  }

int CountOurPositions()
  {

   int count = 0;

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

      ulong ticket = PositionGetTicket(i);

      if(ticket == 0 || !PositionSelectByTicket(ticket)) continue;

      if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber) continue;

      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;

      count++;
     }

   return count;
  }

void AddTradeRecord(ulong ticket, bool isBull, double entry, double stop)
  {

   if(ticket == 0 || FindTradeRecord(ticket) >= 0) return;

   int n = ArraySize(g_trades);
   ArrayResize(g_trades, n + 1);

   g_trades[n].ticket       = ticket;
   g_trades[n].isBull       = isBull;
   g_trades[n].entryPrice   = entry;
   g_trades[n].initialStop  = stop;
   g_trades[n].riskDistance = MathAbs(entry - stop);
   g_trades[n].partialTaken = false;
  }

void PruneTradeRecords()
  {

   for(int i = ArraySize(g_trades) - 1; i >= 0; i--)
     {

      if(!PositionSelectByTicket(g_trades[i].ticket))
        {

         for(int j = i; j < ArraySize(g_trades) - 1; j++) g_trades[j] = g_trades[j + 1];

         ArrayResize(g_trades, ArraySize(g_trades) - 1);
        }
     }
  }

void SyncTradeRecords()
  {

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

      ulong ticket = PositionGetTicket(i);

      if(ticket == 0 || !PositionSelectByTicket(ticket)) continue;

      if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber) continue;

      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;

      if(FindTradeRecord(ticket) >= 0) continue;

      int n = ArraySize(g_trades);
      ArrayResize(g_trades, n + 1);

      g_trades[n].ticket       = ticket;
      g_trades[n].isBull       = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY);
      g_trades[n].entryPrice   = PositionGetDouble(POSITION_PRICE_OPEN);
      g_trades[n].initialStop  = PositionGetDouble(POSITION_SL);
      g_trades[n].riskDistance = MathAbs(g_trades[n].entryPrice - g_trades[n].initialStop);

      g_trades[n].partialTaken = true;
     }
  }

void AddPivotToZigZag(bool isHigh, double price, datetime time)
  {

   int count = ArraySize(g_pivots);

   if(count == 0)
     {

      ArrayResize(g_pivots, 1);
      g_pivots[0].isHigh = isHigh;
      g_pivots[0].price  = price;
      g_pivots[0].time   = time;
      return;
     }

   if(g_pivots[count - 1].isHigh == isHigh)
     {

      bool moreExtreme = isHigh ? (price > g_pivots[count - 1].price) : (price < g_pivots[count - 1].price);

      if(moreExtreme)
        {

         g_pivots[count - 1].price = price;
         g_pivots[count - 1].time  = time;
        }
      return;
     }

   ArrayResize(g_pivots, count + 1);
   g_pivots[count].isHigh = isHigh;
   g_pivots[count].price  = price;
   g_pivots[count].time   = time;

   if(ArraySize(g_pivots) > g_maxPivots)
     {

      int drop = ArraySize(g_pivots) - g_maxPivots;

      for(int i = 0; i < ArraySize(g_pivots) - drop; i++) g_pivots[i] = g_pivots[i + drop];

      ArrayResize(g_pivots, g_maxPivots);
     }
  }

bool IsPriorTrendConfirmed(bool isBull, int shoulderIndex)
  {

   if(!InpRequirePriorTrend) return true;

   if(InpTrendPivots < 2) return true;

   int oldestIndex = shoulderIndex - InpTrendPivots;

   if(oldestIndex < 0) return false;

   for(int i = oldestIndex; i + 2 <= shoulderIndex; i++)
     {

      double earlier = g_pivots[i].price;

      double later = g_pivots[i + 2].price;

      if(!isBull) { if(!(later > earlier)) return false; }

      else        { if(!(later < earlier)) return false; }
     }

   return true;
  }

void DrawTrendline(string name, datetime time1, double price1, datetime time2, double price2, color clr, ENUM_LINE_STYLE style, int width, bool ray = false)
  {

   if(ObjectFind(0, name) < 0)
      ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);

   else
     {

      ObjectMove(0, name, 0, time1, price1);
      ObjectMove(0, name, 1, time2, price2);
     }

   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_STYLE, style);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, width);

   ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, ray);
   ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false);

   ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
   ObjectSetInteger(0, name, OBJPROP_BACK, false);
  }

void DrawHLevel(string name, datetime time1, datetime time2, double price, color clr, ENUM_LINE_STYLE style, int width)
  {

   DrawTrendline(name, time1, price, time2, price, clr, style, width, false);
  }

void DrawText(string name, datetime time, double price, string text, color clr, ENUM_ANCHOR_POINT anchor)
  {

   if(ObjectFind(0, name) < 0)
     {

      ObjectCreate(0, name, OBJ_TEXT, 0, time, price);
      ObjectSetString(0, name, OBJPROP_FONT, "Arial Bold");
      ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9);
      ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
     }

   ObjectSetString(0, name, OBJPROP_TEXT, text);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor);

   ObjectMove(0, name, 0, time, price);
  }

void DrawSwingMarker(bool isHigh, datetime time, double price, string label, color clr)
  {

   string tag      = (isHigh ? "QM_SWH_" : "QM_SWL_") + IntegerToString((int)time);
   string iconName = tag + "_i";
   string textName = tag + "_t";

   if(ObjectFind(0, iconName) < 0)
     {

      ObjectCreate(0, iconName, OBJ_TEXT, 0, time, price);
      ObjectSetString(0, iconName, OBJPROP_FONT, "Wingdings");
      ObjectSetString(0, iconName, OBJPROP_TEXT, CharToString(174));
      ObjectSetInteger(0, iconName, OBJPROP_FONTSIZE, 9);
      ObjectSetInteger(0, iconName, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, iconName, OBJPROP_ANCHOR, isHigh ? ANCHOR_RIGHT_LOWER : ANCHOR_RIGHT_UPPER);
      ObjectSetInteger(0, iconName, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, iconName, OBJPROP_HIDDEN, true);
     }

   if(ObjectFind(0, textName) < 0)
     {

      ObjectCreate(0, textName, OBJ_TEXT, 0, time, price);
      ObjectSetString(0, textName, OBJPROP_FONT, "Arial Bold");
      ObjectSetString(0, textName, OBJPROP_TEXT, label);
      ObjectSetInteger(0, textName, OBJPROP_FONTSIZE, 9);
      ObjectSetInteger(0, textName, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, textName, OBJPROP_ANCHOR, isHigh ? ANCHOR_LEFT_LOWER : ANCHOR_LEFT_UPPER);
      ObjectSetInteger(0, textName, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, textName, OBJPROP_HIDDEN, true);
     }

   ChartRedraw(0);
  }

void DrawQMStructure()
  {

   if(!(InpDrawVisuals && VisualsAllowed())) return;

   color  clr  = g_setup.isBull ? InpBullColor : InpBearColor;
   string id   = IntegerToString((int)g_setup.bosTime);
   string base = "QM_STRUCT_" + id;

   DrawTrendline(base + "_l1", g_setup.shoulderTime, g_setup.shoulderPrice, g_setup.legTime, g_setup.legPrice, clr, STYLE_SOLID, 2);

   DrawTrendline(base + "_l2", g_setup.legTime, g_setup.legPrice, g_setup.headTime, g_setup.headPrice, clr, STYLE_SOLID, 2);

   DrawTrendline(base + "_l3", g_setup.headTime, g_setup.headPrice, g_setup.bosTime, g_setup.targetPrice, clr, STYLE_SOLID, 2);

   DrawHLevel(base + "_bosln", g_setup.legTime, g_setup.bosTime, g_setup.legPrice, clr, STYLE_DOT, 1);

   DrawText(base + "_ls", g_setup.shoulderTime, g_setup.shoulderPrice, "Left Shoulder", clr, g_setup.isBull ? ANCHOR_UPPER : ANCHOR_LOWER);

   DrawText(base + "_head", g_setup.headTime, g_setup.headPrice, "Head", clr, g_setup.isBull ? ANCHOR_LOWER : ANCHOR_UPPER);

   DrawText(base + "_leg", g_setup.legTime, g_setup.legPrice, g_setup.isBull ? "Leg high" : "Leg low", clr, g_setup.isBull ? ANCHOR_LOWER : ANCHOR_UPPER);

   DrawText(base + "_bos", g_setup.bosTime, g_setup.legPrice, " BOS", clr, g_setup.isBull ? ANCHOR_LOWER : ANCHOR_UPPER);

   datetime lineEnd = g_setup.bosTime + (datetime)(PeriodSeconds(_Period) * (InpMaxWaitBars + 5));

   DrawHLevel(base + "_qml", g_setup.shoulderTime, lineEnd, g_setup.qmLinePrice, InpQmLineColor, STYLE_DASH, 1);

   DrawText(base + "_qmltxt", lineEnd, g_setup.qmLinePrice, " QM line (entry " + (g_setup.isBull ? "buy" : "sell") + ")", InpQmLineColor, ANCHOR_LEFT);

   if(g_setup.entry2Valid)
     {
      DrawHLevel(base + "_e2l", g_setup.headTime, lineEnd, g_setup.entry2Price, InpQmLineColor, STYLE_DASHDOT, 1);
      DrawText(base + "_e2txt", lineEnd, g_setup.entry2Price, " Entry 2 (" + (g_setup.isBull ? "buy" : "sell") + ")", InpQmLineColor, ANCHOR_LEFT);
     }

   ChartRedraw(0);
  }

void DrawPriorTren

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

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

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

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

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

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

Стоимость полного кода
2 858,10₽ ≈ $34.94