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

netvolumecopier.mq4

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

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

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

О программе

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

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

Встроенный менеджер времени позволяет ограничить торговлю определёнными часовыми интервалами для каждого дня недели. Частота обновления данных и коэффициент пересчёта лотов настраиваются отдельно.

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

НастройкаОписание
time_manager_use Логический переключатель менеджера времени. При значении true торговля разрешена только в те дни и часы, которые заданы параметрами дня недели. При значении false торговля работает без временных ограничений.
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 Список разрешённых инструментов для копирования через запятую без префиксов (например, GBPUSD, EURUSD). Можно использовать отрицание (начало с «-») для исключения и восклицательный знак (начало с «!») для выборки. Если пусто — копируются все инструменты.
filter_comments_list Список разрешённых комментариев ордеров через запятую. Копируются только ордера, комментарий которых совпадает с одним из указанных значений. Если пусто — копируются все ордера.
filter_lots_minumum Минимальный допустимый лот ордера для копирования. Если значение больше нуля, ордера с лотом ниже этого порога пропускаются.
filter_lots_maximum Максимальный допустимый лот ордера для копирования. Если значение больше нуля, ордера с лотом выше этого порога пропускаются.
cross_table Список кросс-валютных пар через запятую в формате Исходный=Целевой. Используется для корректного определения инструментов CFD, когда имя символа на сервере отличается от имени на клиенте.
update_seconds Интервал обновления данных о ордерах в секундах. Определяет, как часто клиентский советник проверяет изменения на сервере и пересчитывает позиции.
lot_koef Множитель лота при копировании. Позволяет масштабировать размеры копируемых позиций. Значение 1 означает копирование с тем же размером лота, что и на сервере.
reverse Логический переключатель режима инверсии. При значении true направления ордеров на клиенте противоположны серверным: покупки становятся продажами и наоборот.
Получить полный код

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

/*
Please do the modified version of KopirMT4 EA by adding Net-Volume copy function only to suitable with my intention as example below:

1. The Source MT4 Account:
- There are 100 opening orders with some instruments (XAUUSD, GBPJPY, EURUSD...)
- There are 9 lots total buying XAUUSD (from 25 buy orders) and 12 lots total selling XAUUSD (from 30 sell orders) ---> The Net-volume will be -03 lots XAUUSD
2. The Receiver MT4 Account:
- When opening the EA, it will count Net-Volume for each instrument from Source Account, and start to open order accordingly. For above: It will open 03 lots SELL order XAUUSD , in case using of REVERSION MODE will be 3 lot BUY oder XAUUSD
- If Source Acct - Net Volume is being changed equal X:
      + -3< X < 0: Coressponding instrument Receiver order will close partially (close by order)

       + X < -3: Receiver account open more SELL order

       + X = 0: Coressponding instrument Receiver order will be closed full volume

       + X > 0: Coressponding instrument Receiver order will be closed full volume and open one more BUY order accordingly

Vice versa for REVERSION MODE.
And applying the same with all instruments.
*/

#property version   "1.00"
#property strict

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

CDrawPos          m_pos;

#define CopirName "NVC"

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

static ulong tm_last_open_file[];

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

int Delay=100; //Delay

int MagicCopier=0; //Magic

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

int     update_timeout_sec=0; //Update timeout (sec), default=0

S servers_list=""; //List of server accounts

SEP(4);//.
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

SEP(5);//.
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 (,)

SEP(7);//.
BLOCK(7,"Copying Trades Settings");//.
I    update_seconds=5; //Update (seconds)
D    lot_koef=1; //Use lot multiplicator
B    reverse=false; //Reverse mode

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

int port=0;

class _ORDERS
  {
public:

   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 плечо
   long              ticket; //4 tiket=magic clienta
   int               type; //4 тип
   long              magic; //4 magic
   long              original_ticket; //4 оригинальный тикет ордера
   long              account; //4 оригинальный тикет ордера
   string            name; //имя инструмента
   string            comment;
   string            currency; //тип валюты счета
   int               binary; //тип бинарного опциона
   bool              update; //обновление данных
   bool              bCross; //флаг что была активна кросс таблица, флаг ставиться при загрузке данных
   bool              bcopy; //копировать или нет

   void              operator=(const int nil=NULL) //нулевая инициализация переменных
     {
      lot=0; //8 лот
      full_lot=0; //8 полный лот
      open=0; //8 открытие ордера
      close=0; //8
      stop=0; //8
      take=0; //8
      tmOpen=0;//8
      tmClose=0;//8
      balance=0;//8
      equity=0;//8
      leverage=0; //8 плечо
      ticket=0; //4 tiket=magic clienta
      type=0; //4 тип
      magic=0; //4 magic
      original_ticket=0; //4 оригинальный тикет ордера
      account=0; //4 оригинальный тикет ордера
      name=""; //имя инструмента
      comment="";
      currency=""; //тип валюты счета
      binary=0; //тип бинарного опциона
      bcopy=0;
     }

   void              operator=(const _ORDERS &a1)//простое копирование
     {
      lot=a1.lot; //8 лот
      full_lot=a1.full_lot; //8 полный лот
      open=a1.open; //8 открытие ордера
      close=a1.close; //8
      stop=a1.stop; //8
      take=a1.take; //8
      tmOpen=a1.tmOpen;//8
      tmClose=a1.tmClose;//8
      balance=a1.balance;//8
      equity=a1.equity;//8
      leverage=a1.leverage; //8 плечо
      ticket=a1.ticket; //4 tiket=magic clienta
      type=a1.type; //4 тип
      magic=a1.magic; //4 magic
      original_ticket=a1.original_ticket; //4 оригинальный тикет ордера
      account=a1.account; //4 оригинальный тикет ордера
      name=a1.name; //имя инструмента
      comment=a1.comment;
      currency=a1.currency; //тип валюты счета
      binary=a1.binary; //тип бинарного опциона
      bcopy=a1.bcopy;
     }
  };

_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 OnDeinit(const int reason)
  {

   Comment("");

   g_timer.OnDeinit();

   /*if(ClientORServer==server)// || ClientORServer==duplication
     {

      string file=StringFormat("%s\\%lld.nvc",CopirName,AccountNumber());
      if(FileIsExist(file,FILE_COMMON))
        {
         FileDelete(file,FILE_COMMON);
         PrintFormat("Delete file: %s",file);
        }
     }*/
  }

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|FILE_UNICODE,"|");

   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);

      /*
      swrite=StringFormat("%d;%ls;%d;%f;%f;%f;%f;%f;%f;%ls;%u;%u;%d;%d;%f;%f;%d;%ls|\n",
                                         order_server[i].ticket, 0
                                         order_server[i].name, 1
                                         order_server[i].type, 2
                                         order_server[i].full_lot, 3
                                         order_server[i].lot, 4
                                         order_server[i].open, 5
                                         order_server[i].close, 6
                                         order_server[i].stop, 7
                                         order_server[i].take, 8
                                         order_server[i].comment, 9
                                         order_server[i].tmOpen, 10
                                         order_server[i].tmClose, 11
                                         tmsinc, 12
                                         order_server[i].magic, 13
                                         AccountBalance(), 14
                                         AccountEquity(), 15
                                         AccountLeverage(), 16
                                         AccountCurrency()); 17
      */

      if(ArraySize(param)==18 && StringToInteger(param[0])>0 && param[1]!="")
        {

         if(ArrayResize(history,cc+1)==-1)
            continue; //пропустим

         name=cross_fx(param[1],Symbols,history[cc].bCross); //задаем имя инстурменту без префикса
         history[cc].ticket=StringToInteger(param[0]); //+account
         history[cc].original_ticket=history[cc].ticket;

         history[cc].name=name;
         history[cc].type=(int)StringToInteger(param[2]);
         history[cc].full_lot=StringToDouble(param[3]);
         history[cc].lot=StringToDouble(param[4]);
         history[cc].open=StringToDouble(param[5]);
         history[cc].close=StringToDouble(param[6]);
         history[cc].stop=StringToDouble(param[7]);
         history[cc].take=StringToDouble(param[8]);
         history[cc].comment=param[9];

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

         history[cc].tmClose=0;
         history[cc].tmOpen=(datetime)(StringToDouble(param[10])+time_offset);

         history[cc].magic=StringToInteger(param[13]);

         history[cc].balance=StringToDouble(param[14]);
         history[cc].equity=StringToDouble(param[15]);
         history[cc].leverage=StringToDouble(param[16]);
         history[cc].currency=param[17];

         if(StrToDouble(param[11])>0)
            history[cc].tmClose=(datetime)(StringToDouble(param[11])+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

   */

   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(Bid(name)==0.0 || SymbolInfoInteger(name,SYMBOL_TRADE_MODE)==SYMBOL_TRADE_MODE_DISABLED)
        {
         SymbolSelect(name,false);//убираем неторговые символы
         continue; //если в окне данных инструмента такого нет (не включен или отсутсвует, то пропустить его)
        }

      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].original_ticket=history[i].ticket;
      order[c].ticket=(int)(history[i].ticket+account);

      order[c].bCross=history[i].bCross;

      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;
      order[c].bcopy=true;

      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(reverse)
        {

         if(order[c].type==OP_BUY)
            order[c].type=OP_SELL;
         else
            if(order[c].type==OP_SELL)
               order[c].type=OP_BUY;
        }

      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);
  }

double getNetLotServer(string sSymbol)
  {

   double dLots[2];
   ArrayInitialize(dLots,0);

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

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

      if(order[i].tmClose>0 || order[i].type>=2)
         continue; //пропускаем закрытые если есть

      if(sSymbol==order[i].name)
        {
         dLots[order[i].type]+=order[i].lot; //считаем лоты
        }

     }

   int idigits=digits(sSymbol);

   double dnetlot=NormalizeDouble(dLots[0]-dLots[1],idigits);
   return dnetlot;
  }

int               getSymbolsClient(string &ar_symbols[])
  {

   ArrayResize(ar_symbols,0);
   int ic=0;
   for(int i=::OrdersTotal()-1; i>=0; i--)
     {
      if(!::OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         continue;

      bool bFind=false;
      for(int j=0; j<ic; j++)
        {
         if(ar_symbols[j]==::OrderSymbol())
           {
            bFind=true;
            break;
           }
        }

      if(!bFind)
        {
         if(ArrayResize(ar_symbols,ic+1)!=-1)
           {
            ar_symbols[ic]=::OrderSymbol();
            ic++;
           }
        }
     }

   return ic;
  }

int               getSymbolsServer(string &ar_symbols[])
  {

   ArrayResize(ar_symbols,0);
   int ic=0;
   for(int i=ArrayRange(order,0)-1; i>=0; i--)
     {

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

      if(order[i].tmClose>0 || order[i].type>=2)
         continue; //пропускаем закрытые если есть

      bool bFind=false;
      for(int j=0; j<ic; j++)
        {
         if(ar_symbols[j]==order[i].name)
           {
            bFind=true;
            break;
           }
        }

      if(!bFind)
        {
         if(ArrayResize(ar_symbols,ic+1)!=-1)
           {
            ar_symbols[ic]=order[i].name;
            ic++;
           }
        }
     }

   return ic;
  }

double getNetLotClient(string sSymbol,double &dLots[2],double &abuy[][2],double &asell[][2])
  {

   ArrayInitialize(dLots,0);

   ArrayResize(abuy,0);
   ArrayResize(asell,0);

   double dvlot=0;

   for(int i=0; i<::OrdersTotal(); i++)
     {
      if(!::OrderSelect(i,SELECT_BY_POS))
         continue; //тикет 0? такого быть не должно.

      if(::OrderCloseTime()>0 || ::OrderType()>=2)
         continue; //пропускаем закрытые если есть

      if(sSymbol==::OrderSymbol())
        {
         dvlot=NLot(::OrderLots(),sSymbol);

         dLots[::OrderType()]+=dvlot; //считаем лоты

         if(::OrderType()==OP_BUY)
           {
            int isize=ArrayRange(abuy,0);
            if(ArrayResize(abuy,isize+1)!=-1)
              {
               abuy[isize][0]=dvlot;
               abuy[isize][1]=::OrderTicket();
              }
           }

         if(::OrderType()==OP_SELL)
           {
            int isize=ArrayRange(asell,0);
            if(ArrayResize(asell,isize+1)!=-1)
              {
               asell[isize][0]=dvlot;
               asell[isize][1]=::OrderTicket();
              }
           }
        }

     }

   int idigits=digits(sSymbol);

   double dnetlot=NormalizeDouble(dLots[0]-dLots[1],idigits);
   return dnetlot;
  }

void SortByOrderOpenTime(_ORDERS &a[],ENUM_SORT idirection=ENUM_MODE_ASCEND)
  {
   int i=0,j=0;
   _ORDERS x;

   int size=ArraySize(a);

   for(i=0; i<size; i++)
     {
      for(j=size-1; j>i; j--)
        {
         if(idirection==MODE_ASCEND && a[j-1].tmOpen>a[j].tmOpen && a[j-1].tmClose==0 && a[j].tmClose==0)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }

         if(idirection==MODE_DESCEND && a[j-1].tmOpen<a[j].tmOpen && a[j-1].tmClose==0 && a[j].tmClose==0)
           {
            x=a[j-1];
            a[j-1]=a[j];
            a[j]=x;
           }
        }
     }
  }

datetime tmUpdate=0;
bool checkOrders(bool bTrade)
  {

   bPause=true;

   if((long)(TimeCurrent()-tmUpdate)>=update_seconds)
     {
      tmUpdate=TimeCurrent();
      bPause=false;
     }

   if(bPause)
      return false;

   if(!bTrade)
      return false;

   /*
         if(!checkWorkSymbolTime(main.m_name))
           {

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

   */

   /*
   1. анализируем открытые сделки и сверяем с данными сервера
   0 - закрыть, больше открыть, меньше подрезать

   2. анализируем открытые на сервере и сверяем с клиентом.
   0 - закрыть,    больше дооткрыть,   меньше подрезать

   если по символу торговать нельзя, то не трогаем его.

   */
   string sSymbolsClient[];
   int iclient=getSymbolsClient(sSymbolsClient);

   string sSymbolsServer[];
   int iserver=getSymbolsServer(sSymbolsServer);

   double dLotsClient[2];
   double abuy[][2],asell[][2];

   for(int i=0; i<iserver; i++)
     {
      if(!checkWorkSymbolTime(sSymbolsServer[i]))
         continue; //пропустить если в это время торговать на инструменте нельзя

      double dlotClient=getNetLotClient(sSymbolsServer[i],dLotsClient,abuy,asell);
      double dlotServer=getNetLotServer(sSymbolsServer[i])*lot_koef;

      int ib=ArrayRange(abuy,0);
      int is=ArrayRange(asell,0);

      int idgt=LotDigits(sSymbolsServer[i]);

      main.OnInit(sSymbolsServer[i],-1,0);
      main.Update();

      double dMinLot=MinLot(sSymbolsServer[i]);

      if(dlotServer==0.0 && dlotClient!=0.0)
        {
         main.OrderCloseAll(ALL);
         continue;
        }

      if(Abs(dlotClient)==0.0)
        {

         if(dlotServer!=0.0)
           {

            if(Abs(dlotServer)>=MinLot(sSymbolsServer[i]))
              {

               main.OrderSend(MagicCopier,dlotServer>0?OP_BUY:OP_SELL,NLot(Abs(dlotServer),sSymbolsServer[i]),-1,0,0,NULL,0);
              }
           }
        }
      else
        {

         if(dlotServer<0)
           {

            if(dLotsClient[OP_BUY]>0)
               main.OrderCloseAll(OP_BUY);

            if(dLotsClient[OP_SELL]<Abs(dlotServer))
              {

               if(NormalizeDouble(Abs(dlotServer)-dLotsClient[OP_SELL],idgt)>=dMinLot)
                 {
                  double dlotDelta=NLot(Abs(dlotServer)-dLotsClient[OP_SELL],sSymbolsServer[i]);

                  if(Abs(dlotServer)-dLotsClient[OP_SELL]>=MinLot(sSymbolsServer[i]))
                     main.OrderSend(MagicCopier,OP_SELL,dlotDelta,-1); //дооткрыть
                 }
              }
            else
               if(dLotsClient[OP_SELL]>Abs(dlotServer) && is>0)
                 {
                  double dlotDelta=NLot(dLotsClient[OP_SELL]-Abs(dlotServer),sSymbolsServer[i]);

                  if(NormalizeDouble(dLotsClient[OP_SELL]-Abs(dlotServer),idgt)>=dMinLot)
                    {
                     ArraySort(asell,WHOLE_ARRAY,0,MODE_ASCEND); //сортируем лоты по возврастанию

                     for(int j=0; j<is; j++)
                       {
                        if(dlotDelta<=0)
                           break; //лоты выровнялись

                        if(asell[j][0]>=dlotDelta)
                          {

                           if(main.OrderClose((long)asell[j][1],NLot(dlotDelta,sSymbolsServer[i]))) //закрываем
                              dlotDelta-=NLot(dlotDelta,sSymbolsServer[i]);

                          }
                        else
                           if(asell[j][0]<dlotDelta && dlotDelta>0)
                             {

                              if(main.OrderClose((long)asell[j][1],-1)) //закрываем
                                 dlotDelta-=asell[j][0];
                             }
                       }
                    }
                 }
           }//lot server>0
         else
            if(dlotServer>0)
              {

               if(dLotsClient[OP_SELL]>0)
                  main.OrderCloseAll(OP_SELL);

               if(dLotsClient[OP_BUY]<Abs(dlotServer))
                 {
                  if(NormalizeDouble(Abs(dlotServer)-dLotsClient[OP_BUY],idgt)>=dMinLot)
                    {

                     double dlotDelta=NLot(Abs(dlotServer)-dLotsClient[OP_BUY],sSymbolsServer[i]);

                     if(Abs(dlotServer)-dLotsClient[OP_BUY]>=MinLot(sSymbolsServer[i]))
                        main.OrderSend(MagicCopier,OP_BUY,dlotDelta,-1); //дооткрыть
                    }
                 }
               else
                  if(dLotsClient[OP_BUY]>Abs(dlotServer) && ib>0)
                    {
                     double dlotDelta=NLot(dLotsClient[OP_BUY]-Abs(dlotServer),sSymbolsServer[i]);

                     if(NormalizeDouble(dLotsClient[OP_BUY]-Abs(dlotServer),idgt)>=dMinLot)
                       {

                        ArraySort(abuy,WHOLE_ARRAY,0,MODE_ASCEND); //сортируем лоты по возврастанию

                        for(int j=0; j<ib; j++)
                          {
                           if(dlotDelta<=0)
                              break; //лоты выровнялись

                           if(abuy[j][0]>=dlotDelta)
                             {

                              if(main.OrderClose((long)abuy[j][1],NLot(dlotDelta,sSymbolsServer[i]))) //закрываем
                                 dlotDelta-=NLot(dlotDelta,sSymbolsServer[i]);

                             }
                           else
                              if(abuy[j][0]<dlotDelta && dlotDelta>0)
                                {

                                 if(main.OrderClose((long)abuy[j][1],-1)) //закрываем
                                    dlotDelta-=abuy[j][0];
                                }

                          }

                       }
                    }
              }//lot server<0
        }

     }

   iclient=getSymbolsClient(sSymbolsClient);

   for(int i=0; i<iclient; i++)
     {
      double dlotClient=getNetLotClient(sSymbolsClient[i],dLotsClient,abuy,asell);
      double dlotServer=getNetLotServer(sSymbolsClient[i])*lot_koef;
      int ib=ArrayRange(abuy,0);
      int is=ArrayRange(asell,0);

      main.OnInit(sSymbolsClient[i],-1,0);
      main.Update();

      if(dlotServer==0.0 && dlotClient!=0.0)
        {

         main.OrderCloseAll(ALL);
         continue;
        }

     }

   return (true);
  }

bool checkMagic(long magic)
  {
   if(filter_magic_list=="")
      return (true);
   bool bNoCopy=false;
   for(int i=0; i<ArraySize(magicCopy); i++)
     {
      if(StringSubstr(magicCopy[i],0,1)=="-")
         bNoCopy=true; //включаем режим исключения, а все остальное разрешено что не указано!
      if(StringSubstr(magicCopy[i],0,1)=="-" && StrToInteger(StringSubstr(magicCopy[i],1))==magic)
         return (false);
      if(StringSubstr(magicCopy[i],0,1)=="*" && StringFind(IntegerToString(magic),StringSubstr(magicCopy[i],1))==0)
         return (true);
      if(StrToInteger(magicCopy[i])==magic)
         return (true);
     }

   return (bNoCopy);
  }

bool checkSymbol(string smb)
  {
   if(filter_symbols_list=="")
      return (true);
   bool bNoCopy=false,bcross=false;
   for(int i=0; i<ArraySize(symbolsCopy); i++)
     {
      if(StringSubstr(symbolsCopy[i],0,1)=="-")
         bNoCopy=true; //включаем режим исключения, а все остальное разрешено что не указано!
      if(StringSubstr(symbolsCopy[i],0,1)=="-" && StringCompare(smb,cross_fx(StringSubstr(symbolsCopy[i],1),Symbols,bcross),false)==0)
         return (false);
      if(StringSubstr(symbolsCopy[i],0,1)=="!" && StringCompare(smb,cross_fx(StringSubstr(symbolsCopy[i],1),Symbols,bcross),false)==0)
         return (true);
      if(StringCompare(smb,cross_fx(symbolsCopy[i],Symbols,bcross),false)==0)
         return (true);
     }
   return (

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

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

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

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

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

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

Стоимость полного кода
3 637,60₽ ≈ $44.46