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

Virtual Straddle HFT

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

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

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

О программе

Virtual Straddle HFT — торговый советник для MetaTrader 5, работающий на hedging-счетах. Советник реализует стратегию виртуального стрэддла: размещает виртуальные отложенные ордера Buy Stop и Sell Stop на заданном расстоянии от текущей цены. При достижении одной из виртуальных уровней ценой происходит вспышечное открытие реальных позиций с настройками стоп-лосса и тейк-профита в пунктах.

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

В состав продукта входит информационная панель на графике, отображающая текущий статус виртуальных ордеров, количество позиций, плавающий профит, настройки лота и статистику сигналов. Виртуальные уровни могут отображаться в виде горизонтальных линий на графике. Торговые операции выполняются через API CTrade в асинхронном режиме.

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

НастройкаОписание
TriggerDistancePoints Расстояние виртуальных уровней Buy Stop и Sell Stop от текущей цены (в пунктах).
MaxPositions Максимальное количество одновременно открытых позиций за один всплеск.
OrderExpirySeconds Время жизни виртуальных ордеров в секундах. По истечении срока виртуальные ордера переставляются заново.
RearmOnlyWhenFlat Переключатель: при активном значении новые виртуальные стрэддлы размещаются только при отсутствии открытых позиций.
MagicNumber Магический номер для идентификации позиций, открытых советником.
SL_Points Стоп-лосс для открытых позиций (в пунктах).
TP_Points Тейк-профит для открытых позиций (в пунктах).
UseTrailing Переключатель включения трейлинг-стопа для управляемых позиций.
TrailStartPoints Прибыль (в пунктах), после которой начинается трейлинг-стоп.
TrailDistancePoints Расстояние стоп-лосса от цены при активном трейлинге (в пунктах).
TrailStepPoints Минимальное улучшение стоп-лосса при каждом перемещении трейлинга (в пунктах).
LotMode Режим расчёта размера лота: фиксированный, по шагу баланса или по проценту риска.
FixedLot Фиксированный размер лота для открытия позиций (используется при режиме лота «фиксированный»).
BalancePerStep Автоматический шаг баланса для расчёта лота в режиме «по шагу баланса» (в долларах).
LotPerStep Размер лота на каждый шаг баланса (используется при режиме «по шагу баланса»).
RiskPercent Общий процент риска от баланса (распределяется между всеми открываемыми позициями).
MaxSpreadPoints Фильтр спреда (в пунктах). Значение 0 означает фильтр отключён. При превышении спреда виртуальные ордера не размещаются.
MaxSlippagePoints Максимально допустимое проскальзывание (в пунктах). При превышении этого значения триггер отклоняется и ордер не размещается.
DeviationPoints Максимальное допустимое отклонение цены при размещении ордера (в пунктах).
ShowDashboard Переключатель отображения информационной панели на графике.
ShowVirtualLines Переключатель отображения горизонтальных линий виртуальных уровней на графике.
DashX Горизонтальная координата информационной панели на графике (в пикселях от левого верхнего угла).
DashY Вертикальная координата информационной панели на графике (в пикселях от левого верхнего угла).
Получить полный код

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

#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>
CTrade trade;

enum ENUM_LOT_MODE
{
   LOT_FIXED = 0,         // Fixed lot
   LOT_BALANCE_STEP = 1,  // Auto: lot per X balance
   LOT_RISK_PERCENT = 2   // Auto: risk % of balance
};

input group "=== Straddle ==="
input int    TriggerDistancePoints = 40;     // Virtual stop distance (points)
input int    MaxPositions          = 10;     // Max positions opened at once (adjustable)
input int    OrderExpirySeconds    = 10;     // Virtual orders expire & re-place (sec)
input bool   RearmOnlyWhenFlat     = true;   // Place new straddle only when no positions open
input long   MagicNumber           = 777001; // Magic number

input group "=== SL / TP / Trailing (points) ==="
input int    SL_Points            = 200;   // Stop loss (points)   [$2 on 0.01 lot, gold]
input int    TP_Points            = 500;   // Take profit (points) [$5 on 0.01 lot, gold]
input bool   UseTrailing          = true;  // Enable trailing stop
input int    TrailStartPoints     = 50;    // Trailing starts after this profit (points)
input int    TrailDistancePoints  = 50;    // SL kept this far behind price (points)
input int    TrailStepPoints      = 10;    // Min SL improvement per move (points)

input group "=== Lot Size ==="
input ENUM_LOT_MODE LotMode        = LOT_FIXED; // Lot mode
input double FixedLot              = 0.01;   // Fixed lot
input double BalancePerStep        = 1000.0; // Auto: balance step ($)
input double LotPerStep            = 0.01;   // Auto: lot for each step
input double RiskPercent           = 1.0;    // Auto: total risk % (split over all positions)

input group "=== Filters ==="
input int    MaxSpreadPoints       = 30;     // Spread filter (points), 0 = off
input int    MaxSlippagePoints     = 15;     // Reject trigger if price already moved > this (points)
input int    DeviationPoints       = 20;     // Broker max deviation on order (points)

input group "=== Dashboard ==="
input bool   ShowDashboard         = true;
input bool   ShowVirtualLines      = true;
input int    DashX                 = 15;
input int    DashY                 = 25;

double   g_buyLvl = 0, g_sellLvl = 0;
ulong    g_stampMs = 0;
ulong    g_blockUntil = 0;
bool     g_armed = false;
string   g_last = "Starting";
int      g_signals = 0, g_rejected = 0;
double   g_pt = 0;
string   PFX = "VSH_";

int OnInit()
{
      // код доступен только после оплаты
   }

void OnDeinit(const int reason)
{
   EventKillTimer();
   ObjectsDeleteAll(0, PFX);
   Comment("");
}

double NormLot(double lot)
{
   double mn = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double mx = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double st = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   lot = MathFloor(lot / st + 1e-9) * st;
   return NormalizeDouble(MathMax(mn, MathMin(mx, lot)), 2);
}

double CalcLot()
{
   double lot = FixedLot;
   if(LotMode == LOT_BALANCE_STEP)
      lot = MathFloor(AccountInfoDouble(ACCOUNT_BALANCE) / BalancePerStep) * LotPerStep;
   else if(LotMode == LOT_RISK_PERCENT)
   {
      int n = MathMax(1, MaxPositions);
      double riskPerPos = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100.0 / n;

      double lossPerLot = PointsToMoney(SL_Points, 1.0);
      if(lossPerLot > 0) lot = riskPerPos / lossPerLot;
   }
   return NormLot(lot);
}

double PointsToMoney(double points, double lot)
{
   double tv = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double ts = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   if(ts <= 0) return 0;
   return points * g_pt / ts * tv * lot;
}

int CountPos()
{
   int c = 0;
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) c++;
   }
   return c;
}

double FloatingPL()
{
   double p = 0;
   for(int i = PositionsTotal() - 1; i >= 0; i--)
      if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
         p += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
   return p;
}

int SpreadPts() { return (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); }
bool SpreadOK() { return (MaxSpreadPoints <= 0 || SpreadPts() <= MaxSpreadPoints); }

void PlaceVirtual()
{
   if(!SpreadOK()) { g_armed = false; g_last = "Spread too high - waiting"; return; }
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   g_buyLvl  = NormalizeDouble(ask + TriggerDistancePoints * g_pt, _Digits);
   g_sellLvl = NormalizeDouble(bid - TriggerDistancePoints * g_pt, _Digits);
   g_stampMs = GetTickCount64();
   g_armed   = true;
   g_last    = "Virtual orders placed";
}

void CancelVirtual(string why)
{
   g_armed = false;
   g_last = why;
}

void Fire(bool isBuy)
{
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double price = isBuy ? ask : bid;

   double slipPts = isBuy ? (ask - g_buyLvl) / g_pt : (g_sellLvl - bid) / g_pt;
   if(MaxSlippagePoints > 0 && slipPts > MaxSlippagePoints)
   {
      g_rejected++;
      CancelVirtual("REJECTED: slippage " + DoubleToString(slipPts, 0) + " pts");
      g_blockUntil = GetTickCount64() + 1000;
      return;
   }
   if(!SpreadOK())
   {
      g_rejected++;
      CancelVirtual("REJECTED: spread " + IntegerToString(SpreadPts()));
      g_blockUntil = GetTickCount64() + 1000;
      return;
   }

   CancelVirtual(isBuy ? "BUY triggered - SELL deleted" : "SELL triggered - BUY deleted");

   double lot = CalcLot();
   int n = MaxPositions;
   if(!RearmOnlyWhenFlat) n -= CountPos();

   double margin = 0;
   ENUM_ORDER_TYPE ot = isBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
   if(OrderCalcMargin(ot, _Symbol, lot, price, margin) && margin > 0)
   {
      int fm = (int)MathFloor(AccountInfoDouble(ACCOUNT_MARGIN_FREE) * 0.95 / margin);
      n = MathMin(n, fm);
   }
   if(n <= 0) { g_last = "No margin / max reached"; g_blockUntil = GetTickCount64() + 1000; return; }

   double slD = SL_Points * g_pt;
   double tpD = TP_Points * g_pt;
   double minD = (MathMax(SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL),
                          SymbolInfoInteger(_

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

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

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

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

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

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

Стоимость полного кода
1 043,20₽ ≈ $12.76