качну, проверю.
Спасибо
Спасибо, отличный скрипт, приятно работать. Автору респект.
Или советник не под тот билд писался или тупо куча ошибок
Aliaksei Karalkou:
Или советник не под тот билд писался или тупо куча ошибок
8.5 лет ветке...
исправленный код советника .
//+---------------------------------------------------------------------------------+ //| Netgatom_Modern.mq4 | //| Обновлённая версия 2025 | //| Исправлены ошибки, | //| добавлены кнопки | //+---------------------------------------------------------------------------------+ #property copyright "Verdi, updated 2025" #property link "nemo811@mail.ru" #property version "2.00" #property strict // Входные параметры input int Magic = 0; // Уникальный номер ордеров сетки (кроме Stop-ордера) input double Lot = 0.01; // Объём первого рыночного ордера и первого limit-ордера input int delta = 37; // Шаг сетки (в пунктах) input int MaxOrders = 2; // Количество limit-ордеров сетки input int takeprofit = 52; // Уровень TP (0 - не использовать) input int zero_tp = 1; // Коэффициент поправки TP (0 или 1) input int stoploss = 0; // Уровень SL (0 - не использовать) input int Proskalz = 3; // Проскальзывание (в пунктах) // Глобальные переменные double SL, TP, Price, DeltaProfitR, DeltaProfitL, LotR, LotL, LotS; bool gridSet = false; // Флаг: сетка уже установлена // Структура для хранения рыночной информации (чтобы избежать множественных вызовов MarketInfo) struct MarketInfoStruct { double point; double tickSize; double tickValue; double nominalPoint; }; //+------------------------------------------------------------------+ //| Инициализация | //+------------------------------------------------------------------+ int OnInit() { // Включаем события мыши для кнопок ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, 1); // Создаём кнопки CreateButton("btnBuy", "BUY", 100, 50, clrGreen); CreateButton("btnSell", "SELL", 200, 50, clrRed); CreateButton("btnCancel", "CANCEL", 300, 50, clrGray); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Деинициализация | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Удаляем кнопки ObjectDelete("btnBuy"); ObjectDelete("btnSell"); ObjectDelete("btnCancel"); } //+------------------------------------------------------------------+ //| Обработка событий графика (нажатие кнопок) | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == "btnBuy") { // Визуальная обратная связь FlashButton("btnBuy", clrBlue); // Запускаем логику BUY if(!gridSet) ProcessTrading(true); else Alert("Сетка уже установлена. Нажмите CANCEL, чтобы сбросить."); } else if(sparam == "btnSell") { FlashButton("btnSell", clrBlue); if(!gridSet) ProcessTrading(false); else Alert("Сетка уже установлена. Нажмите CANCEL, чтобы сбросить."); } else if(sparam == "btnCancel") { FlashButton("btnCancel", clrOrange); CloseAllOrders(); gridSet = false; Alert("Все ордера удалены."); } } } //+------------------------------------------------------------------+ //| Основная логика установки сетки (вызывается из кнопок) | //+------------------------------------------------------------------+ void ProcessTrading(bool isBuy) { // Проверяем наличие отложенных ордеров if(CountPendingOrders() > 0) { Alert("Отмена! Удалите отложенные ордера вручную или нажмите CANCEL."); return; } // Проверяем наличие позиций (рыночных ордеров) double buyVolume = GetMarketVolume(OP_BUY); double sellVolume = GetMarketVolume(OP_SELL); if(buyVolume > 0 || sellVolume > 0) { // Если объёмы равны – это lock if(MathAbs(buyVolume - sellVolume) < 0.0001) { Alert("Отмена! Позиция Lock (объёмы Buy и Sell равны)."); return; } // Проверка направления (чтобы не открывать против большей позиции) if(isBuy && buyVolume < sellVolume) { Alert("Отмена Buy! Объём Sell больше."); return; } if(!isBuy && sellVolume < buyVolume) { Alert("Отмена Sell! Объём Buy больше."); return; } } // Получаем рыночную информацию (тик, пункт и т.д.) MarketInfoStruct mi; mi.point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); mi.tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); mi.tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); mi.nominalPoint = mi.tickValue * mi.point / mi.tickSize; // Расчёт общего убытка по открытым позициям double totalProfit = GetTotalProfit(); double dy = MathAbs(buyVolume - sellVolume); double n = (totalProfit * (-1)) / mi.nominalPoint; // Если нет открытых позиций – используем базовый Lot if(buyVolume == 0 && sellVolume == 0) { PlaceInitialOrders(isBuy, 0, Lot); } else { PlaceInitialOrders(isBuy, dy, Lot, n); } gridSet = true; // Помечаем, что сетка установлена } //+------------------------------------------------------------------+ //| Размещение начального рыночного ордера и сетки лимитных | //+------------------------------------------------------------------+ void PlaceInitialOrders(bool isBuy, double dy, double baseLot, double n = 0) { // --- Рыночный ордер --- double lotR = (dy > 0) ? dy : baseLot; double tp = 0, sl = 0; double priceMarket = (isBuy) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); double deltaProfitR = (n != 0) ? n / (dy + dy) : 0; if(takeprofit != 0) { if(isBuy) tp = NormalizeDouble(priceMarket + (takeprofit + deltaProfitR * zero_tp) * _Point, _Digits); else tp = NormalizeDouble(priceMarket - (takeprofit + deltaProfitR * zero_tp) * _Point, _Digits); } if(stoploss != 0) { if(isBuy) sl = NormalizeDouble(priceMarket - stoploss * _Point, _Digits); else sl = NormalizeDouble(priceMarket + stoploss * _Point, _Digits); } // Открываем рыночный ордер OpenOrder(isBuy ? OP_BUY : OP_SELL, lotR, priceMarket, sl, tp, "R"); // --- Лимитные ордера --- double sumi = 0; for(int i = 1; i <= MaxOrders; i++) { double lotL = (dy > 0) ? dy * i : baseLot * i; sumi += delta * (2 * dy + dy * (i - 2)) * (i - 1) / 2; double deltaProfitL = (n != 0) ? (sumi + n + 2 * dy * delta * i) / ((2 * dy + dy * (i - 1)) * i / 2 + 2 * dy) : (sumi + i * delta * baseLot) / ((2 * baseLot + baseLot * (i - 1)) * i / 2 + baseLot); double priceLimit; if(isBuy) priceLimit = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK) - delta * i * _Point, _Digits); else priceLimit = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID) + delta * i * _Point, _Digits); if(takeprofit != 0) { if(isBuy) tp = NormalizeDouble(priceLimit + (takeprofit + deltaProfitL * zero_tp) * _Point, _Digits); else tp = NormalizeDouble(priceLimit - (takeprofit + deltaProfitL * zero_tp) * _Point, _Digits); } if(stoploss != 0) { if(isBuy) sl = NormalizeDouble(priceLimit - stoploss * _Point, _Digits); else sl = NormalizeDouble(priceLimit + stoploss * _Point, _Digits); } OpenOrder(isBuy ? OP_BUYLIMIT : OP_SELLLIMIT, lotL, priceLimit, sl, tp, StringFormat("№%d", i)); } // --- Стоп-ордер для локкирования --- double lotS = (dy > 0) ? (2 * dy + dy * (MaxOrders - 1)) * MaxOrders / 2 + 2 * dy : (2 * baseLot + baseLot * (MaxOrders - 1)) * MaxOrders / 2 + baseLot; double priceStop; if(isBuy) priceStop = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK) + delta * (MaxOrders + 1) * _Point, _Digits); else priceStop = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID) - delta * (MaxOrders + 1) * _Point, _Digits); OpenOrder(isBuy ? OP_SELLSTOP : OP_BUYSTOP, lotS, priceStop, 0, 0, "Lock", 0); // Magic = 0 для лок-ордера } //+------------------------------------------------------------------+ //| Универсальная функция открытия ордера (с повторными попытками) | //+------------------------------------------------------------------+ void OpenOrder(int type, double volume, double price, double sl, double tp, string comment, int magic = -1) { if(magic == -1) magic = Magic; // по умолчанию используем глобальный Magic int ticket = -1; int attempts = 0; while(ticket < 0 && attempts < 10) { RefreshRates(); if(type == OP_BUY) ticket = OrderSend(_Symbol, type, volume, SymbolInfoDouble(_Symbol, SYMBOL_ASK), Proskalz, sl, tp, comment, magic, 0, clrGreen); else if(type == OP_SELL) ticket = OrderSend(_Symbol, type, volume, SymbolInfoDouble(_Symbol, SYMBOL_BID), Proskalz, sl, tp, comment, magic, 0, clrRed); else ticket = OrderSend(_Symbol, type, volume, price, Proskalz, sl, tp, comment, magic, 0, clrYellow); if(ticket < 0) { Print("Ошибка отправки ордера: ", GetLastError()); attempts++; Sleep(500); } } if(ticket < 0) Alert("Не удалось открыть ордер после 10 попыток."); else Print("Ордер открыт: ", comment); } //+------------------------------------------------------------------+ //| Подсчёт отложенных ордеров по символу | //+------------------------------------------------------------------+ int CountPendingOrders() { int count = 0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == _Symbol && OrderType() > OP_SELL) count++; } } return count; } //+------------------------------------------------------------------+ //| Суммарный объём рыночных ордеров заданного типа | //+------------------------------------------------------------------+ double GetMarketVolume(int opType) { double vol = 0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == _Symbol && OrderType() == opType) vol += OrderLots(); } } return vol; } //+------------------------------------------------------------------+ //| Суммарная прибыль по всем рыночным ордерам символа | //+------------------------------------------------------------------+ double GetTotalProfit() { double profit = 0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == _Symbol && (OrderType() == OP_BUY || OrderType() == OP_SELL)) profit += OrderProfit(); } } return profit; } //+------------------------------------------------------------------+ //| Удаление всех ордеров по символу | //+------------------------------------------------------------------+ void CloseAllOrders() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == _Symbol) { if(OrderType() <= OP_SELL) // рыночный ордер OrderClose(OrderTicket(), OrderLots(), OrderType() == OP_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK), Proskalz, clrWhite); else // отложенный OrderDelete(OrderTicket()); } } } } //+------------------------------------------------------------------+ //| Создание кнопки | //+------------------------------------------------------------------+ void CreateButton(string name, string text, int x, int y, color bgColor) { ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, 80); ObjectSetInteger(0, name, OBJPROP_YSIZE, 30); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bgColor); ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrBlack); ChartRedraw(); } //+------------------------------------------------------------------+ //| Мигание кнопки при нажатии | //+------------------------------------------------------------------+ void FlashButton(string name, color flashColor) { color original = (color)ObjectGetInteger(0, name, OBJPROP_BGCOLOR); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, flashColor); ChartRedraw(); Sleep(300); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, original); ChartRedraw(); } //+------------------------------------------------------------------+ //| OnTick – пустой, так как логика только по кнопкам | //+------------------------------------------------------------------+ void OnTick() { // Ничего не делаем } //+------------------------------------------------------------------+
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Net^atom:
Author: Артур