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