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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.