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