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

kopirmt4_timelimit.mq4

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

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

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

О программе

Этот советник для MetaTrader 4 представляет собой копировщик торговых сделок между счетами. Он может работать в роли сервера (мастер-счета), клиента (ведомого счета) или в режиме дублирования. В режиме сервера советник сохраняет информацию об открытых и закрытых ордерах в общий файл, а в режиме клиента считывает эти данные и воспроизводит сделки на своем счете. Поддерживается одновременное копирование с нескольких серверных счетов.

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

Также реализованы уведомления по электронной почте и push-сообщения при срабатывании защитных механизмов, поддержка отложенных ордеров, режим скальпера и реверса, а также автоматическое формирование комментариев к ордерам.

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

НастройкаОписание
Delay Задает скорость обновления данных об ордерах в миллисекундах.
history_days Количество предыдущих дней, за которые загружается история сделок.
time_manager_use Включает управление торговым временем по дням недели.
Monday_time_on Интервал времени в понедельник, в течение которого разрешено копирование сделок.
Tuesday_time_on Интервал времени во вторник, в течение которого разрешено копирование сделок.
Wednesday_time_on Интервал времени в среду, в течение которого разрешено копирование сделок.
Thursday_time_on Интервал времени в четверг, в течение которого разрешено копирование сделок.
Friday_time_on Интервал времени в пятницу, в течение которого разрешено копирование сделок.
Saturday_time_on Интервал времени в субботу, в течение которого разрешено копирование сделок.
Sunday_time_on Интервал времени в воскресенье, в течение которого разрешено копирование сделок.
filter_magic_list Список разрешенных магических номеров для копирования, разделенных запятыми.
filter_symbols_list Список разрешенных инструментов для копирования, разделенных запятыми.
filter_comments_list Список разрешенных комментариев для копирования, разделенных запятыми.
filter_lots_minumum Минимальный лот, разрешенный для копирования.
filter_lots_maximum Максимальный лот, разрешенный для копирования.
cross_table Список соответствий инструментов сервера и клиента в формате СерверныйСимвол=КлиентскийСимвол, разделенных запятыми.
copytype Определяет направление копируемых сделок: все, только покупки или только продажи.
timeout Максимальное время в минутах с момента открытия сделки на сервере, в течение которого разрешено ее копирование.
reopen_position Разрешает повторное открытие позиции, если она была закрыта на клиенте.
close_price_use Включает закрытие сделки только при условии, что цена закрытия не хуже, чем на серверном счете.
auto_lot Включает автоматический расчет лота в зависимости от соотношения баланса или эквити серверного и клиентского счетов.
auto_lot_balance_or_equity Выбирает, что использовать для автоматического расчета лота: баланс или эквити счета.
use_currency_koef Учитывать коэффициент конвертации валют при копировании сделок между счетами с разной валютой.
use_levelerage_koef Учитывать соотношение плеч серверного и клиентского счетов при расчете лота.
lot_koef Множитель лота, применяемый к объему копируемой сделки.
order_lots Фиксированный рабочий лот, используемый при отключенном множителе лота.
open_minimal_lot Открывать минимальным лотом, если расчетный лот равен нулю.
MinLot Минимальный лот, которым открываются сделки, если расчетный лот меньше указанного значения.
MaxLot Максимальный лот, которым разрешено открывать сделки.
stopout_balance Уровень эквити, при достижении которого копирование останавливается.
stopout_margin_procent Минимальный уровень маржи в процентах, при котором копирование останавливается.
stopout_dd Максимальный процент просадки, при достижении которого копирование останавливается.
stopout_close Принудительно закрывать все ордера при срабатывании защитного механизма.
alert_mail_use Разрешает отправку уведомлений по электронной почте при срабатывании защитных механизмов.
alert_push_use Разрешает отправку push-уведомлений при срабатывании защитных механизмов.
copylimit Разрешает копирование лимитных ордеров.
copystop Разрешает копирование стоп-ордеров.
scalper Включает режим скальпера, при котором вход осуществляется всегда по лучшей цене.
reverse Включает инверсию сделок: покупки становятся продажами и наоборот, стоп-лосс и тейк-профит меняются местами.
otstup Отступ в пунктах для задержки входа или входа по лучшей цене.
slippage_is_count_spread Если включено, проскальзывание рассчитывается как количество спредов.
slippage Допустимое проскальзывание в пунктах для точности открытия сделки.
lot_digits Количество знаков после запятой для округления лота. Значение 0 означает автоматическое определение.
noCloseOrders Запрещает закрытие ордеров на клиенте, пока пользователь не закроет их вручную или по стоп-лоссу или тейк-профиту.
count_all_orders_use Учитывать все ордера по всем инструментам при подсчете количества ордеров на сервере.
count_orders_start Начинает копирование только при достижении указанного количества ордеров на сервере.
count_orders_stop Останавливает копирование при достижении указанного количества ордеров на сервере.
count_client_all_orders_use Учитывать все ордера по всем инструментам при подсчете количества ордеров на клиенте.
count_client_orders_stop Останавливает копирование при достижении указанного количества открытых ордеров на клиенте.
auto_comment Автоматически формирует комментарий к ордерам, содержащий номер счета и тикет исходного ордера.
user_comment Пользовательский комментарий, который присваивается копируемым ордерам.
copy_stoploss_use Разрешает копирование стоп-лосса с серверного счета на клиентский.
copy_takeprofit_use Разрешает копирование тейк-профита с серверного счета на клиентский.
user_change_sl_and_tp Разрешает пользователю изменять стоп-лосс и тейк-профит на клиентском счете.
stoploss_offset Смещение стоп-лосса в пунктах в большую или меньшую сторону.
takeprofit_offset Смещение тейк-профита в пунктах в большую или меньшую сторону.
user_takeprofit_use Разрешает использование пользовательского тейк-профита.
user_takeprofit Пользовательский тейк-профит в пунктах от цены открытия.
user_stoploss_use Разрешает использование пользовательского стоп-лосса.
user_stoploss Пользовательский стоп-лосс в пунктах от цены открытия.
no_move_stoploss_and_takeprofit Запрещает смещение стоп-лосса и тейк-профита при открытии позиции с отклонением цены.
equity_trail_start Процент прибыли, при достижении которого активируется трейлинг по эквити.
equity_trail_step Шаг в процентах для трейлинга по эквити.
trailing_stop Количество пунктов прибыли, при достижении которого активируется трейлинг-стоп.
trailing_step Шаг трейлинг-стопа в пунктах.
bu Количество пунктов прибыли, при достижении которого активируется перевод стоп-лосса в безубыток.
bu_profit Минимальный уровень прибыли в пунктах для срабатывания безубытка.
Получить полный код

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

#define DEMO_DAYS 30

#define EXPERIED "Ваш пробный период подошёл к концу. Приобретите полную версию на официальном сайте "

#property description "ENG";
#property description "The Copier trades";
#property description "";

#ifdef __MAIL__
#property description "For customer:";
#property description __MAIL__
#endif

#property version   "4.77"
#property strict
#property icon        "\\Images\\kopirmt4.ico";

#include <sovetnikovGUI/Orders.mqh>
#include <sovetnikovGUI/Time.mqh>
#include <sovetnikovGUI\Bcrypt.mqh>

CBcrypt g_crypt;

string autor="Copyright (c) 2014, Gavrilin Alexander V. ";

bool bAlert=false;

bool checkAccount()
{
   if(GetDemo())
      {
         return true;
      }
      else
      {

         if(!bAlert)
         {
            Alert(EXPERIED);//демо истекло
            bAlert=true;
         }

         return false;
      }

   return false;
}

/*
4.76
- переработан механизм открытия ордеров при заданном параметре Points
- исправлена логика отслеживания просадки на счете для остановки копирования

4.75
- исправление работы с сигналами

4.73
- исправление ошибки копирования инструментов, содержащих в названии восклицательный знак !

4.72
- исправление возможной ошибки при переоткрытии
- добавлено игнорирование Timeout, если включено переоткрытие Reopen position
- при первом открытии берет тр и сл исходные если включен режим User can modify orders
- исправление выставления своих тр и сл.
- исправление обновления данных при закрытии на стороне клиента
- добавлен классический трейлинг стоп (trailing stop) и безубыток (bu)

4.71
- обновлена работа с историей сделок, что позволило существенно снизить нагрузку на процессор

4.68
- исправлена работа с торговыми сессиями, которое приводило к остановке копирования

4.67
- исправлена отключение торговли на сервере с инвесторским паролем
- возвращена настройка частоты опроса по таймеру, по умолчанию 100 мс

4.66
- обновление механизма загрузки данных для снижения нагрузки при отсутствии сделок

4.65
- косметические исправления сообщений

4.64
- отладочный режим: отображение сделок сервера в журнале,которые обновились.
- отображение в журнале максимум информации о попытке открыть сделку.
- исправлена ошибка проверки торговой сессии из-за чего копировщик не копировал сделки

4.63
- исправление сброса тикета ордера при нехватки маржи на открытие, которое приводило к дублированию сделки.
- обновлены отладочные сообщения

4.62
- накопительное обновление, мелкие исправления в работе. Если у вас сделки ранее открывал брокер и вдруг престал копировать, то обновить обязательно.

4.61
- исправлена проблема с округлением лота

4.60
- исправлены комментарии

4.59
- запрет копирования открытых ордеров с комментарием from #

4.58
- отключено дополнительное получение котировок, которое может вызывать задержки при открытии и закрытии.

4.57
- испралена ошибка с повторным открытием сделки

4.56
- исправлено лишнее дублирование сделок в режиме Duplication

4.55
- убраны из настроек не актуальные параметры
- удалены метки на графике о текущем режиме так как они дулируют сообщение в правом верхнем углу
- добавлен параметр Cross Table , формат ServerSymbol1=ClientSymbol1 можно указать несколько через запятую. Это дополнение к внешнему файлу кросс таблиц kopirmt4_cross.ini
- переименован параметр Dublicator в Duplication
- исправлен механизм таймера, введен резервный механизм на случай сбоя.
- параметр timeout задан по умолчанию 5 минут
- обновлен механизм работы с ордерами, чтобы ускорить с ними работу.
- бесплатная версия будет работать только по AUDUSD так как данная версия предназначена в первую очередь для знакомства с функционалом.
- добавлен трал по % профиту как суммарно по всем копируемым сделкам так и раздельно по каждому из копируемых счетов.
- исправлено закрытие всех сделок по просадке в валюте и %
- несколько мелких улучшений и исправление замеченных ошибок.

4.51
- поправлена работа частичного закрытия, которое иногда приводило к закрытию всей сделки без причин

4.50
- добавлены опции увеличения\уменьшения ТР и СЛ
- добавлены опции разрешающие копировать ТР и СЛ раздельно

4.49
- мелкие исправления копирования отложенных ордеров

4.48
- исправлена ошибка отмены отложенного и лимитного ордера при фильтрации по комментарию

4.47
- добавлен режим дубликатора

4.46
- отключена проверка наличия маржи для открытия лимитных и отложенных ордеров до их выставления на клиенте

4.45
- исправлено копирование отложенных ордеров
- добавлена опция для отключения учета соотношения плечей "Use leverage accounts"

4.44
- исправлено округление лота

4.43
- исправлена работа множителя лота по валюте при включенном Auto lot
- остановка копирования по текущей просадке формула ((Эквити/Баланс)-1)*100, если просадка ниже или равна заданной то копирование отключается, возможна отправка уведомления и закрытие позиций принудительно.

4.42
- оптимизация

4.41
- добавлена проверка , можно ли торговать по инструменту прежде чем что либо делать.

4.40
- убраны возможности управления копировщиком из других советников (не актуальная функция)
- убрана возможность управления сторонним советником AutoTrade Manager (не актуальная функция)
- поправлено отображение режима работы с учетом текущего состояния советника
- доработан механизм остановки копирования при понижении уровня эквити или маржи, при востановлении уровня, копирование возобновляется.
- добавлен новый режим остановки копирования при понижении уровня маржи (%)
- добавлена отправка уведомлений при понижении уровня маржи\эквити на почту или с помощью Push уведомлений, не чаще 1 раз в 10 минут
- переработан режим конвертации валют счетов при копировании, по умолчанию конвертация отключена.
- доработан auto comment, добавлен в комментарий номер тикета сервера
- переименован параметр "use currency auto koef" на "use currency accounts"
- добавлены новые параметры "alert mail use", "alert push use", "stopout margin level %"
- добавлено отображение количества позиций открытых на серверах
- в бесплатной версии доступно копирование только на EURUSD, остальные валюты доступны только в платных версиях.
- изменено название параметра Otstup на Points

4.33
- корректировка конвертации RUB->USD
- отключена автоматическая конвертация по умолчанию

4.32
- слово реверс убирается из комментария
- поправлена конвертация с учетом валюты счета. На данный момент поддерживаются основные типы счетов USD,EUR,RUB
- поправлена возможность копировать XAUUSD

4.31
- исправлена работа с таблицей инструментов
- доработан анализ сделок закрытых частично

4.30
- оптимизация кода

4.21
- поправлено определение минимального лота у фьючерсов и акций

4.20
- доработана работа с префиксами
- переработан режим скальпера и режим отступов, изменена логика ограничения точки входа
- доступны настройки для задания частоты опроса сервера
- доступен режим активации опроса по таймеру или по поступлению тиков для снижения нагрузки

4.14
- поправлено отключение по достижению количества ордеров на сервере и клиенте
- добавлена функция count_client_orders_stop и count_client_all_orders_use для контроля количества на клиенте, при достижении указанного количества открытых ордеров копирование новых отключается.

4.13
- добавлена функция для отключения изменения SL и TP при изменении на сервере

4.12
- поправлен комментарий к ордерам
- улучшены фильтры по комментариям и меджикам:
filter magic list
поддерживает возможность указать все меджики начинающиеся с указанных цифр с помощью символа * (например: *1234)
в таком режиме все ордера имеющие меджик номер начинающийся с 1234 будут скопированы

filter comment list
поддерживает возможность строгого соответствия комментария с помощью символа ! (например: !EA_Ilan)
в таком режиме будут скопированы ордера, в которых комментарий полностью совпадает с указанным в настройке

4.11
- доработан перезапуск таймера
- добавлены Суббота и Воскресенье в тайм менеджер.
- поправлены пользовательские комментарии

4.10
- доработана поддержка бинарных опционов (поддержка только типа UP / DOWN)
- доработан режим входа по количеству спредов, теперь если спред нулевой, то копировщик автоматически переключается в режим точности входа в пунктах.
- изменено значение параметра filter slippage = 5.0 для совместимости с предыдущими версиями
- в Lite версии добавлена возможность указать комментарий
- в Free версию возвращена возможность указать множитель лота lot multiplicator

4.00
- доработано закрытие при активном режиме close price use
- изменена логика отслеживания ордеров для последующих новых функций (ВАЖНО: перед обновлением необходимо дождаться закрытия всех позиций, иначе копировщик их потеряет!)
- добавлена возможность включения и остановка копирования по количеству открытых инструментов (не доступно для Lite и Free версий)
- поправлена ошибка с минимальным лотом при копировании CFD и Forex инструментов
- изменена логика таблиц соответствия инструментов, приоритет имеет таблица, в таблице нужно указывать точное соответствие инструментов (полные названия как в терминале)
- добавлена опция  no_move_stoploss_and_takeprofit отключающее смещение для стопов и тейков, если вошли с отклонением. опция включена по умолчанию.
- параметр use_currency_koef установлен по умолчанию true
- добавлена новая опция slippage_is_count_spread, при активации true включается режим точности по количеству спредов и точность входа зависит от спреда. Данная опция включена по умолчанию.
- переименованы параметры:
   list accounts for copy, delimiter (,) - > server accounts
   default lot - > fix lot
   filter slippage open price - > filter slippage

3.43
- корректировка чтения данных клиентом (проблема наблюдалась на системах с SSD дисками и гибридными дисками HSSD)
- копирование по умолчанию тейкпрофит и стоплосс включено
3.42
- исправлена ошибка с выставлением отложенных и лимитных ордеров при определенных настройках
- изменена формула расчета лота при режиме авто лот используется описание 
- добавлена поддержка счетов в разной валюте, для корректной работы, необходимо, чтобы терминал получал котировки EURUSD и USDRUB. Поддерживаются счета в валютах EUR, USD, RUB
  расчет коэфициента можно отключить параметром use currency auto koef = false, по умолчанию данный режим отключен! Функция эксперементальная.
3.41
- возвращен параметр update timeout (sec) для возможности принудительного обновления
- правка ошибок
3.40
- улучшена синхронизация времени между сервером и клиентом
- добавлена возможность указать timeout дробным числом, если нужно указать время жизни сделки менее 1 минуты
- добавлено автоотключение модификации стоплосс\тейкпрофит на стороне клиента, если пользовательский стоп или тейк включен и задан нулем
- переработан алгоритм отслеживания ордеров сервера, опция update timeout (sec) больше не требуется и удалена. Убран параметр Delay, он больше не требуется.
- добавлена поддержка внешнего управления копированием инструмента из советников и индикаторов (подробности будут в инструкции)
- заложена поддержка разной валюты счетов, реализация автокоррекции лота будет в следующих обновлениях
- убрано удаление отложки, если она сработала раньше чем у клиента, что приводило к пропуску входа отложенными ордерами
- значение параметра timeout вернули в 0 по умолчанию, параметр выбора режима работы переименован в mode (по умолчанию данный параметр Server)
Внимание: данное обновление не совместимо с предыдущими версиями, перед обновлением необходимо закрыть открытые позиции на клиентах или дождаться их закрытия!!!

3.33
- поправлено копирование комментариев
- поправлено частичное закрытие в Lite версии

3.32
- доработка логики отслеживания ордеров
- добавлена возможность принудительного обновления данных сервера, параметр update timeout (sec), значение задается в секундах (настройка только для сервера)
- доработка автоопределения инструментов с префиксами и CFD
- тейк и стоп копируются у отложенных ордеров как и у рыночных, по умолчанию копировщик не копирует их.
  Включается копирование установкой параметров user takeprofit use=false, user stoploss use=false
- опция автокомментария, пишет номера счета с которого идет копирование

3.31
- исправлена ошибка переоткрытия ордера при timeout=0

3.30
- доработано копирования сделок открытых частями на ECN счетах
- параметр timeout по умолчанию равен 5, вместо 0. Параметр теперь влияет и на отложенные ордера!
- доработано открытие лимитных и стоповых ордеров, особенно при работе со скальперами и новостными советниками
- по умолчанию отключено копирование стопов и тейков для ускорения работы при копировании большого количества ордеров.
  Отложенным ордерам сразу тейк и стоп не выставляется, он ставится сразу после их открытия (если активированы соответсвующие опции).
  По умолчанию тейк и стоп виртуальные.
- переработано изменение стоп лосс и тейк профит для улучшения работы с роботами-скальперами

3.29
- введен параметр настройки глубины выгрузки истории для клиентов, это нужно для снижения нагрузки при внутридневной торговли
history count (days) = 1..N, параметр принимает в качестве значения кол-во предыдущих дней.
- добавлены настройки Time manager, позволяет задать время работы когда разрешено копировать сделки, время задается для каждого дня недели
формат времени позволяет указывать диапозоны торговли, например
0-10,13-17 или
22:10-08:00, 15:00-18:59
- добавлена поддержка работы совместно с AutoTradeManager

3.28
- исправлена работа с otstup
- исправлена загрузка данных при изменении настроек при открытых сделках
- добавлена новая опция: close price use = false/true , если опция включена (true), тогда сделка закрывается при обязательном условии, что цена не хуже, чем цена закрытия на источнике, при этом учитывается otstup

3.27
- исправлена совместная работа сервера и клиента на одном аккаунте (исправлены задвоения открытия позиций)
- исправлена модификация тейкпрофит, стоплосс и цены открытия
- исправлена опция по умолчанию, pause for set takeprofit (min) = 0
- изменена логика режима scalper mode, теперь положительная величина otstup это сколько пунктов минимум должна пройти цена на сервере от цены открытия, прежде чем сделку будет разрешено открыть.
  Если величина otstup отрицательная, то значит цена на сервере должна пройти в минус на данную величину от цены открытия, прежде чем будет разрешено ее открыть.
- введен интелектуальный режим расчета стоплосса и и тейкпрофита, учитывается расхождение между ценами позиций сервера и клиента
- доработан спящий режим для снижения нагрузки на процессор
- доработан режим загрузки счетов с разных серверов

3.26
- включение направления торговли (бай \ селл \ все)
- добавления возможнсоти ставить свой тейк или стоп раздельно
- переоткрытие сделок если закрыли сделку самостоятельно на клиенте

3.25
- версия для маркета, без встроенной защиты

3.22
11.11.2014
- добавил возможность указать свою кросс таблицу инстурментов, полезно для копирования инструментов с разными названиями
- сохранение ключа для последующего его использолвания на случай отсутсвия связи с сервером
- стоп блокировка копирования при достижении заданного убытка в валюте депозита
--------------------------------------------------------------------------------------
21.10.2014
- обновлена работа с частичным закрытием ордеров
- добавлена фильтрация с помощью исключения, например -EURUSD, то копировать все, кроме EURUSD

07.09.2014
глобальное обновление
-убраны все длл
-задействованы новые функции терминала
-снижена нагрузка на ПК за счет изменения способа работы копировщика
-добавлена возможность  указать в настройках с каких счетов копировать сделки, за счет этого сильно упростилась настройка. Портов как таковых больше нет и нет с ними проблемы!
-данная версия будет переходной при создании гибридного копировщика мт4<->м5

версия будет содержать в себе клиент и сервер, по умолчанию будет запущен клиент
*/

static long tm_last_open_file[];

enum _set_copytype
{
   all, //Long & Short
   buy, //Long Only
   sell //Short Only
};

enum _set_type
{
   client=1,//Client (Slave)
   server=0,//Server (Master)
   duplication=2,//Duplication
};

enum _set_auto_lot
{
   balance=1,//Balance
   equity=0  //Equity
};

I     Delay=100; //Delay

BLOCK(1,"General Settings");//.
input _set_type    ClientORServer=server; //Mode

S servers_list=""; //Server accounts

BLOCK(2,"Server Settings");//.
int     update_timeout_sec=0; //Update timeout (sec), default=0

I     history_days=1; //History count (days)

BLOCK(3,"Client Settings");//.

BLOCK(4,"Time manager"); //.
B   time_manager_use=false; //Time manager use
S Monday_time_on="00:00-24:00"; //Monday
S Tuesday_time_on="00:00-24:00"; //Tuesday
S Wednesday_time_on="00:00-24:00"; //Wednesday
S Thursday_time_on="00:00-24:00"; //Thursday
S Friday_time_on="00:00-24:00"; //Friday
S Saturday_time_on="00:00-24:00"; //Saturday
S Sunday_time_on="00:00-24:00"; //Sunday

BLOCK(5,"Filters deals");//.

S  filter_magic_list=""; //Filter magic list, delimiter (,)

S  filter_symbols_list=""; //Filter symbols list, delimiter (,)

S  filter_comments_list=""; //Filter comment list, delimiter (,)

D  filter_lots_minumum=0; //Filter minimum lot

D  filter_lots_maximum=0; //Filter maximum lot

S   cross_table=""; //Cross Table List, delimiter (,)
input _set_copytype copytype=all;    //Copy mode

D   timeout=5; //Timeout (min)

B    reopen_position=false; //Reopen position
B    close_price_use=false; //Close price use

BLOCK(6,"MM Settings");//.

B    auto_lot=false; //Auto lot

input _set_auto_lot   auto_lot_balance_or_equity=balance; //Use balance or equity mode

B    use_currency_koef=false; //Use currency

B    use_levelerage_koef=false; //Use leverage

D  lot_koef=1; //Lot multiplicator

D  order_lots=0; //Fix lot

B  open_minimal_lot=true; //Open minimal lot if lot is 0

D  MinLot=0; //Minimal lot for open

D  MaxLot=0; //Maximal lot for open

D  stopout_balance=0; //Stop by equity

D  stopout_margin_procent=0; //Stop by margin level %
D  stopout_dd=0; //Stop by drawdown %
B    stopout_close=false; //Close all orders

B    alert_mail_use=false; //Alert mail use
B    alert_push_use=false; //Alert push use

BLOCK(7,"Copying Trades Settings");//.

B    copylimit=false; //Copy limit orders
B    copystop=false; //Copy stop orders

B    scalper=false; //Scalper mode

B    reverse=false; //Reverse mode

D    otstup=0; //Points

B    slippage_is_count_spread=true; //Slippage is spread

D    slippage=10.0; //Filter slippage

I   lot_digits=0; //lot digits (0 - auto)

B    noCloseOrders=false;//No close orders on client

B    count_all_orders_use=true; //Count server all orders use

I     count_orders_start=0; //Count server order copy start

I     count_orders_stop=0; //Count server order copy stop

#ifndef MarketDemo
B    count_client_all_orders_use=true; //Count client all orders use

I     count_client_orders_stop=0; //Count client orders copy stop

#else
bool    count_client_all_orders_use=false; //Count client all orders use

int     count_client_orders_stop=1; //Count client orders copy stop

#endif

B  auto_comment=false; //Auto comment
S  user_comment=""; //User comment

B    copy_stoploss_use=true; //Copy stoploss use
B    copy_takeprofit_use=true;//Copy takeprofit use

B     user_change_sl_and_tp=false; //User can modify orders

D     stoploss_offset=0; //Stoploss Shift (+/-Points)
D     takeprofit_offset=0; //Takeprofit Shift (+/-Points)

int     setTP_pause=0; //Pause for set takeprofit (min)

B    user_takeprofit_use=false; //User takeprofit use
D  user_takeprofit=0; //User take at points

B    user_stoploss_use=false; //User stoploss use
D  user_stoploss=0; //User stop at points

B    no_move_stoploss_and_takeprofit=true; //No move stoploss and takeprofit

BLOCK(8,"Trailing Settings");//.
D  equity_trail_start=0; //Equity Tral Start (%)
D equity_trail_step=1; //Equity Tral Step (%)

B  trailing_all_servers=true; //Trailing All Servers Use

D  trailing_stop=0; //Trailing Stop Points
D  trailing_step=1; //Trailing Step Points
D  bu=0; //BU Start Points
D  bu_profit=0; //BU Minimum Profit Points

int port=0;

struct _ORDERS
{
   double            lot; //8 лот
   double            full_lot; //8 полный лот
   double            open; //8 открытие ордера
   double            close; //8
   double            stop; //8
   double            take; //8
   datetime          tmOpen;//8
   datetime          tmClose;//8
   double            balance;//8
   double            equity;//8
   double            leverage; //8 плечо
   ulong             ticket; //4 tiket=magic clienta
   int               type; //4 тип
   ulong             magic; //4 magic
   ulong             original_ticket; //4 оригинальный тикет ордера
   long              account; //4 оригинальный тикет ордера
   string            name; //имя инструмента
   string            comment;
   string            currency; //тип валюты счета
   int               binary; //тип бинарного опциона
   bool              update; //обновление данных

};

_ORDERS order[];

string crossCFD[][2]; //кросс таблица для cfd
string symbolsCopy[];
string magicCopy[];
string commentsCopy[];
string port_list[];

int   time_offset=0; //сдвиг в часах, временной для синхронизации времени сервера и клиента (определяется как Время Клиента=ВремяСервера+time_offset, смешение может быть и отрицательной велечиной и положительной в зависимости от разницы времени
string Symbols[];
int check_work=0;
bool bWork=true;

class CMyOrders: public COrders
{
public:
   virtual void OnTimer()
   {

   }

   virtual void OnChartEvent(const int id,// идентификатор события
                             const long& lparam,   // параметр события типа long
                             const double& dparam, // параметр события типа double
                             const string& sparam  // параметр события типа string
                            )
   {

   }

};

CMyOrders main();

int c1=0;

string g_scmt="";

datetime timer=0;

CTimer g_timer;
CTime gtime;
bool bPause=false;
string sservers_list="";

bool bStopExpert=false;

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

void AddSymbol(string newsymbol)
{

   int isize=ArraySize(Symbols);

   bool bFind=false;

   for(int i=0; i<isize; i++)
   {
      if(Symbols[i]==newsymbol)
      {
         bFind=true;
         break;
      }
   }

   if(!bFind)
   {
      if(ArrayResize(Symbols,isize+1)!=-1)
      {
         Symbols[isize]=newsymbol;
      }
   }

}

void OnDeinit(const int reason)
{

   Comment("");

   g_timer.OnDeinit();

   if(ClientORServer==server || ClientORServer==duplication)
   {
      string file=StringConcatenate("KopirMT4\\",IntegerToString(AccountNumber()),".cscopy");
      FileDelete(file,FILE_COMMON);
   }
}

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

int loadOrdersFile(string file,int &c,int &cForOpen,long account_port)
{

   int f=FileOpen(file,FILE_READ|FILE_SHARE_READ|FILE_COMMON|FILE_CSV,"|");

   if(f==-1)
   {
      int err=GetLastError();
      if(err!=5004)  Print("File ",file," load is error ",err);
      return -err;
   }

   string line;
   string param[];
   string name;
   double sp=0;
   bool bError=true;

   _ORDERS history[];
   ArrayResize(history,0);
   int cc=0;
   MqlDateTime tm_sinchro= {0};
   TimeCurrent(tm_sinchro);
   tm_sinchro.min=0;
   tm_sinchro.sec=0;
   datetime tmsinc=StructToTime(tm_sinchro); //структура без минут и сек

   long account=AccountNumber();

   while(!FileIsEnding(f))
   {
      line=FileReadString(f);
      string_explode(";",line,param);

      if(ArraySize(param)==17 && StrToInteger(param[0])>0 && param[1]!="")
      {
         name=cross_fx(param[1],Symbols); //задаем имя инстурменту без префикса

         ArrayResize(history,cc+1);

         history[cc].magic=StringToInteger(param[12]);
         history[cc].ticket=StringToInteger(param[0]); //+account
         history[cc].name=name;
         history[cc].type=(int)StringToInteger(param[2]);
         history[cc].lot=StrToDouble(param[3]);
         history[cc].full_lot=0;
         history[cc].open=StrToDouble(param[4]);
         history[cc].close=StrToDouble(param[5]);
         history[cc].stop=StrToDouble(param[6]);
         history[cc].take=StrToDouble(param[7]);
         history[cc].comment=param[8];

         time_offset=(int)(tmsinc-StringToInteger(param[11])); //Время Клиента=ВремяСервера+time_offset, автонастройка времени

         history[cc].tmClose=0;
         history[cc].balance=StrToDouble(param[13]);
         history[cc].equity=StrToDouble(param[14]);
         history[cc].leverage=StrToDouble(param[15]);
         history[cc].currency=param[16];

         history[cc].tmOpen=(datetime)(StrToDouble(param[9])+time_offset);

         if(StrToDouble(param[10])>0) history[cc].tmClose=(datetime)(StrToDouble(param[10])+time_offset);

         cc++;
      }
   }

   FileClose(f);

   /*
   id; 0
   name; 1
   type;2
   lot;3
   open;4
   close;5
   stop;6
   take;7
   comment;8
   tmOpen;9
   tmClose;10
   Hour;11
   magic;12
   Balance,13
   Equity;14

   21115106;EURUSD;0;0.010000;1.296320;1.296270;0.000000;0.000000;;1410554589;1410554647;20;0;10252.470000;10252.470000!
   1373330139;EURJPY;1;0.200000;135.958000;136.195000;0.000000;0.000000;from #113678340;1413498186;1413500489;11;205335909;4797.300000;4810.730000!
   1373329932;EURJPY;1;0.250000;135.956000;135.961000;0.000000;0.000000;from #113678250;1413498075;1413498186;11;205335865;4797.300000;4810.730000!
   1373329600;EURJPY;1;0.300000;135.983000;135.957000;0.000000;0.000000;from #113678249;1413497869;1413498076;11;205335775;4797.300000;4810.730000!
            */

   /*
   ticket
   ticket2=ticket+account

   ticket2-account==ticket

   */
   ulong magic_id=0,find_id=0;
   int prev_pos=-1;
   double lot=0,part_lot=0;

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

      if(history[i].ticket==0 || history[i].tmClose!=0) continue;//

      ulong t=history[i].ticket;
      magic_id=t;
      lot=history[i].lot;
      part_lot=0;

      prev_pos=-1;

      for(int j=0; j<cc; j++)
      {

         if(history[j].ticket==0 || history[j].tmClose==0) continue;

         if((StringFind(history[j].comment,StringFormat("to #%d",magic_id))==0))
         {
            part_lot+=history[j].lot;
            magic_id=history[j].ticket;

            prev_pos=j;
         }
      }

      if(prev_pos!=-1)
      {
         history[i].ticket=history[prev_pos].ticket; //подменим открытому тикет который мониторим
         history[prev_pos].ticket=0;

      }

      history[i].full_lot=part_lot+lot;

   }

   for(int i=0; i<cc; i++)
   {

      if(history[i].ticket==0) continue; //пропустим удаленные

      if(!checkMagic(history[i].magic)) continue; //пропустим левые меджики и инструменты
      if(!checkSymbol(history[i].name)) continue; //пропустим левые меджики и инструменты
      if(!checkComments(history[i].comment)) continue; //пропустим левые меджики и инструменты

      if(filter_lots_minumum>0 && history[i].lot<filter_lots_minumum) continue;
      if(filter_lots_maximum>0 && history[i].lot>filter_lots_maximum) continue;

      name=history[i].name;

      if(MarketInfo(name,MODE_BID)==0.0 || !MarketInfo(name,MODE_TRADEALLOWED)) continue; //если в окне данных инструмента такого нет (не включен или отсутсвует, то пропустить его)

      if(history[i].type<2 || (copylimit && (history[i].type==OP_BUYLIMIT || history[i].type==OP_SELLLIMIT))
            || (copystop && (history[i].type==OP_BUYSTOP || history[i].type==OP_SELLSTOP)))
      {

         if(history[i].tmClose==0 && StringFind(history[i].comment,"to #")>=0) continue; //пропустим все ордера которые являются частью частичного закрытия, их не копируем

         if(history[i].tmClose==0)
         {
            cForOpen++; //считаем только те, которые надо открыть

         }

         if(ArrayResize(order,c+1)==-1) continue;

         int ibinary=0;
         double _point=point(name);

         order[c].ticket=(int)(history[i].ticket+account);
         order[c].original_ticket=history[i].ticket;
         order[c].account=account_port;
         order[c].name=name;
         order[c].type=history[i].type;
         order[c].lot=history[i].lot;
         order[c].full_lot=history[i].full_lot;
         order[c].open=history[i].open;
         order[c].close=history[i].close;
         order[c].stop=history[i].stop;
         order[c].take=history[i].take;

         string ccmt=ConvertComment(history[i].comment,history[i].tmOpen,ibinary);

         order[c].binary=ibinary;

         if(ibinary>0) order[c].comment=ccmt;
         else order[c].comment=history[i].comment;

         if(ibinary==0)
         {

            if(user_comment!="") order[c].comment=user_comment; //задаим свой коммент ордерам которые будем открывать
            if(ibinary==0 && reverse) order[c].comment=StringConcatenate(order[c].comment," reverse");

            if(user_comment==" ") order[c].comment=""; //задаим свой коммент ордерам которые будем открывать
            if(auto_comment) order[c].comment=StringFormat("%d-%d",order[c].account,order[c].original_ticket); //задаим свой коммент ордерам которые будем открывать
         }

         if(reverse)
         {

            if(order[c].type==OP_BUY) order[c].type=OP_SELL;
            else if(order[c].type==OP_SELL) order[c].type=OP_BUY;
            else if(order[c].type==OP_BUYSTOP) order[c].type=OP_SELLLIMIT;
            else if(order[c].type==OP_SELLSTOP) order[c].type=OP_BUYLIMIT;
            else if(order[c].type==OP_BUYLIMIT) order[c].type=OP_SELLSTOP;
            else if(order[c].type==OP_SELLLIMIT) order[c].type=OP_BUYSTOP;
         }

         if(order[c].type==OP_BUY || order[c].type==OP_BUYLIMIT || order[c].type==OP_BUYSTOP)
         {
            if(reverse)order[c].open-=otstup*point(name);
            else order[c].open+=otstup*point(name);

            if(reverse)order[c].close-=otstup*point(name);
            else order[c].close+=otstup*point(name);
         }

         if(order[c].type==OP_SELL || order[c].type==OP_SELLLIMIT || order[c].type==OP_SELLSTOP)
         {
            if(reverse) order[c].open+=otstup*_point;
            else order[c].open-=otstup*_point;

            if(reverse)order[c].close-=otstup*_point;
            else order[c].close+=otstup*_point;
         }

         if(reverse)
         {

            if(order[c].type==OP_BUY || order[c].type==OP_BUYLIMIT || order[c].type==OP_BUYSTOP)
            {

               order[c].stop=0;
               if(history[i].take>0)
               {
                  if(!no_move_stoploss_and_takeprofit) order[c].stop=order[c].open-MathAbs(history[i].take-history[i].open);
                  else order[c].stop=history[i].take;
               }
               order[c].take=0;
               if(history[i].stop>0)
               {
                  if(!no_move_stoploss_and_takeprofit) order[c].take=order[c].open+MathAbs(history[i].stop-history[i].open);
                  else order[c].take=history[i].stop;
               }

            }
            else if(order[c].type==OP_SELL || order[c].type==OP_SELLLIMIT || order[c].type==OP_SELLSTOP)
            {

               order[c].stop=0;
               if(history[i].take>0)
               {
                  if(!no_move_stoploss_and_takeprofit) order[c].stop=order[c].open+MathAbs(history[i].take-history[i].open);
                  else order[c].stop=history[i].take;
               }
               order[c].take=0;
               if(history[i].stop>0)
               {
                  if(!no_move_stoploss_and_takeprofit) order[c].take=order[c].open-MathAbs(history[i].stop-history[i].open);
                  else order[c].take=history[i].stop;
               }

            }

         }

         int ishift=0;
         if(order[c].type==OP_BUY || order[c].type==OP_BUYLIMIT || order[c].type==OP_BUYSTOP) ishift=1;
         if(order[c].type==OP_SELL || order[c].type==OP_SELLLIMIT || order[c].type==OP_SELLSTOP) ishift=-1;

         if(user_stoploss_use && user_stoploss==0.0) order[c].stop=0;
         if(user_takeprofit_use && user_takeprofit==0.0) order[c].take=0;

         if(!copy_stoploss_use) order[c].stop=0;
         if(!copy_takeprofit_use) order[c].take=0;

         if(stoploss_offset  &&  order[c].stop!=0.0) order[c].stop=nd(order[c].stop-ishift*stoploss_offset*_point,name);
         if(takeprofit_offset && order[c].take!=0.0) order[c].take=nd(order[c].take+ishift*takeprofit_offset*_point,name);

         order[c].tmOpen=history[i].tmOpen;
         order[c].tmClose=history[i].tmClose;
         order[c].balance=history[i].balance;
         order[c].equity=history[i].equity;
         order[c].leverage=history[i].leverage;
         order[c].currency=history[i].currency;
         c++;

      }

   }

   return (c);
}

bool checkOrders(bool bTrade)
{

   int ticket=0,t=0;
   double lot,open,stop,take,delta,p,dslippage,_Ask=0,_Bid=0;
   datetime tm_open=0,tmClose=0;
   /*
   magic-account = ticket
   if select ticket
   */

   for(int i=0; i<ArrayRange(order,0); i++)
   {

      if(order[i].ticket==0) continue; //тикет 0? такого быть не должно.

      main.OnInit(order[i].name,(int)order[i].ticket,0);

      if(!checkWorkSymbolTime(main.m_name))
      {

         continue; //пропустить если в это время торговать на инструменте нельзя
      }

      bool bCountCopy=checkCountOrders(order[i].name); //подсчет ордеров
      bool bCountCopy2=checkCountClientOrders(order[i].name);

      p=main.p;
      if(p==0.0)
      {

         SymbolSelect(main.m_name,true);
         AddSymbol(main.m_name);
         main.p=point(main.m_name);
         p=main.p;

         if(p==0.0) continue;
      }

      _Ask=Ask(order[i].name);
      _Bid=Bid(order[i].name);

      double spread=NormalizeDouble((_Ask-_Bid)/p,1);

      dslippage=slippage;
      if(slippage_is_count_spread)
      {
         dslippage=ND1(slippage*spread);
         if(dslippage==0.0) dslippage=slippage;
      }

      if(AccountMargin()!=0.0)
      {
         double margin=NormalizeDouble((AccountEquity()/AccountMargin())*100,3);
         if(stopout_margin_procent!=0 && NormalizeDouble(margin,3)<=NormalizeDouble(stopout_margin_procent,3))
         {
            bTrade=false;
         }
      }

      if(stopout_balance>0 && NormalizeDouble(AccountEquity(),2)<=NormalizeDouble(stopout_balance,2))
      {
         bTrade=false;
      }

      if(AccountBalance()>0)
      {
         double dd=(AccountEquity()/AccountBalance()-1)*100; //-

         if(stopout_dd!=0 && NormalizeDouble(dd,3)<=-NormalizeDouble(MathAbs(stopout_dd),3) && dd<0)
         {
            bTrade=false;
         }
      }

      main.OnTick(); //контроль вирт
      main.Update();

      ticket=main.getOrderTicket(ALL); //проверим есть ли такой ордер среди открытых

      if(ticket>0)
      {

         main.bu_simple(bu,bu_profit);
         main.trailing_simple(trailing_stop,trailing_stop,trailing_step);
      }

      if(ticket<=0 && !reopen_position)
      {

         ticket=main.getLastHistoryTicket(ALL,0,true);

         if(::OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY))
         {

            continue; //запрет открытия ордера если он был закрыт и переоктрытие не включено
         }
      }
      int dgt=(int)digits(order[i].name);

      if(main.OrderSelect(ticket))
      {

         tmClose=main.OrderCloseTime();
         double dstop=main.OrderStopLoss();
         double dtake=main.OrderTakeProfit();

         if(order[i].tmClose>0 && tmClose==0.0 && order[i].binary!=1)
         {
            if(!noCloseOrders)
            {

               delta=0;

               bool bClose=false;
               if(close_price_use && main.OrderSelect(ticket))
               {
                  open=main.OrderOpenPrice();
                  delta=NormalizeDouble(open-order[i].open,dgt)+otstup*p;

                  if(order[i].type==OP_BUY && (NormalizeDouble((_Bid-order[i].close+delta)/p,1)>=0 || NormalizeDouble((order[i].close-order[i].open)/p,1)<=0)) bClose=true;
                  if(order[i].type==OP_SELL && (NormalizeDouble((order[i].close-_Ask+delta)/p,1)>=0 || NormalizeDouble((order[i].open-order[i].close)/p,1)<=0)) bClose=true;
                  if(order[i].type>=2) bClose=true;

               }

               if(!close_price_use || bClose)
               {
                  PrintFormat("Close order Ticket: %d Original ticket: %d Magic ID: %d Account: %d Delta: %.1f",ticket,order[i].original_ticket,order[i].ticket,order[i].account,delta);
                  main.OrderClose(ticket,-1,clrNONE);
               }
            }

         }
         else if(order[i].tmClose==0 && tmClose==0.0)
         {

            if(main.OrderSelect(ticket))
            {
               open=main.OrderOpenPrice();
               delta=NormalizeDouble(open-order[i].open,dgt)+otstup*p;
               int type=main.OrderType();

               tm_open=main.OrderOpenTime();

               if(order[i].type==OP_BUY || order[i].type==OP_BUYSTOP || order[i].type==OP_BUYLIMIT)
               {
                  stop=order[i].stop;
                  if(stop>0 && !no_move_stoploss_and_takeprofit) stop+=delta;

                  if(user_stoploss_use && user_stoploss>0) stop=open-user_stoploss*point(order[i].name);
                  else if(user_stoploss_use && user_stoploss==0) stop=-1;

                  take=0;
                  if(TimeCurrent()-tm_open>=setTP_pause*60)
                  {
                     take=order[i].take;

                     if(take>0 && !no_move_stoploss_and_takeprofit) take+=delta;

                     if(user_takeprofit_use && user_takeprofit>0) take=open+user_takeprofit*point(order[i].name);
                     else if(user_takeprofit_use && user_takeprofit==0) take=-1;
                  }

                  if(!copy_stoploss_use) stop=-1;
                  if(!copy_takeprofit_use) take=-1;

                  if(type==OP_BUY && (!user_change_sl_and_tp || (stop>0 && stop!=dstop && dstop==0) || (take>0 && take!=dtake && dtake==0)))
                  {

                     main.OrderModify(ticket,-1,stop,take,0,clrNONE);
                  }

                  if((type==OP_BUYSTOP || type==OP_BUYLIMIT) && order[i].type>=2)
                  {

                     if(!main.OrderModify(ticket,order[i].open,stop,take,0,clrNONE))
                     {
                        order[i].open=open;
                     }

                  }
               }

               if(order[i].type==OP_SELL || order[i].type==OP_SELLSTOP || order[i].type==OP_SELLLIMIT)
               {

                  stop=order[i].stop;

                  if(stop>0 && !no_move_stoploss_and_takeprofit) stop+=delta;

                  if(user_stoploss_use && user_stoploss>0) stop=open+user_stoploss*point(order[i].name);
                  else if(user_stoploss_use && user_stoploss==0) stop=-1;

                  take=0;
                  if(TimeCurrent()-tm_open>=setTP_pause*60)
                  {
                     take=order[i].take;

                     if(take>0 && !no_move_stoploss_and_takeprofit) take+=delta;

                     if(user_takeprofit_use && user_takeprofit>0) take=open-user_takeprofit*point(order[i].name);
                     else if(user_takeprofit_use && user_takeprofit==0) take=-1;
                  }

                  if(!copy_stoploss_use) stop=-1;
                  if(!copy_takeprofit_use) take=-1;

                  if(type==OP_SELL && (!user_change_sl_and_tp || (stop>0 && stop!=dstop && dstop==0) || (take>0 && take!=dtake && dtake==0)))
                  {

                     main.OrderModify(ticket,-1,stop,take,0,clrNONE);

                  }

                  if((type==OP_SELLSTOP || type==OP_SELLLIMIT) && order[i].type>=2)
                  {

                     if(!main.OrderModify(ticket,order[i].open,stop,take,0,clrNONE))
                     {
                        order[i].open=open;
                     }

                  }

               }

            }

            if(main.OrderSelect(ticket))
            {
               if(order[i].full_lot>0 && main.OrderCloseTime()==0.0 && order[i].binary==0)
               {

                  double start_lot=0;
                  double dlot=main.OrderLots();
                  main.get_part(ticket,start_lot);

          

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

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

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

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

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

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

Стоимость полного кода
6 239,30₽ ≈ $76.27