MQL4: Пишем копировщик сделок для MetaTrader4
Dmitry aka Silentspec
Общая идея
struct Params
{
int account;
char symbol;
int ticket;
int magic;
int type;
double volume;
double sl;
double tp;
double equity;
};
void write(string name,Params &a[],bool local=false)
{
int h;
do
{
h=local ? FileOpen(name,FILE_WRITE|FILE_BIN) :
FileOpen(name,FILE_WRITE|FILE_BIN|FILE_COMMON);
if(GetLastError()!=0)
Sleep(DELAY);
}
while(h==INVALID_HANDLE);
FileWriteArray(h,a);
FileClose(h);
}
void read(string name,Params &a[],bool local=false)
{
int h;
do
{
h=local ? FileOpen(name,FILE_READ|FILE_BIN) :
FileOpen(name,FILE_READ|FILE_BIN|FILE_COMMON);
if(GetLastError()!=0)
Sleep(DELAY);
}
while(h==INVALID_HANDLE);
FileReadArray(h,a);
FileClose(h);
}
void create()
{
account=AccountNumber();
backupName=IntegerToString(AccountNumber());
sharedName="shared";
backup();
}
void backup()
{
write(backupName,shared,true);
}
int backup(Params &a[])
{
read(backupName,a,true);
return ArraySize(a);
}
int pull(Params &a[])
{
read(sharedName,a);
return ArraySize(a);
}
void share()
{
Params orders[],temp[];
read(sharedName,orders); // читаем расшаренные позиции
int szO=ArraySize(orders);
int szP=ArraySize(positions);
int szTemp=ArrayResize(temp,0,szO+szP);
// копируем все "чужие" ордера во временный массив
for(int i=0;i<szO;i++)
if(orders.account!=this.account)
{
szTemp=ArrayResize(temp,szTemp+1);
ArrayCopy(temp,orders,szTemp-1,i,1);
}
// теперь дописываем текущие позиции на счету
ArrayResize(temp,szTemp+szP);
for(int i=szTemp;i<szTemp+szP;i++)
ArrayCopy(temp,positions,i,i-szTemp,1);
// сохраняем изменения в общий файл
write(sharedName,temp);
}
for(int i=total-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderType() <= 1)
{
sz=ArrayResize(positions,sz+1);
char sa[];
StringToCharArray(OrderSymbol(),sa);
ArrayCopy(positions.symbol,sa);
positions.ticket=OrderTicket();
c=OrderComment();
positions.magic=
StringToInteger(StringSubstr(c,StringFind(c,"#")+1));
positions.volume=OrderLots();
positions.sl=OrderStopLoss();
positions.tp=OrderTakeProfit();
positions.type=OrderType();
positions.equity=eq;
}
}
TradeCopier *func()
{
...
return GetPointer(this);
}
void OnTimer()
{
if(CopierType==SLAVE)
{
copier.mergeAndTrade();
}
else if(CopierType==MASTER)
{
copier.opened().share();
}
}
double v=LotType==DYNAMIC
? normalizeLot(CharArrayToString(p.symbol),
eq/p.equity*p.volume)
: p.volume;
static double normalizeLot(string symbol,double lot)
{
double lotMin = SymbolInfoDouble(symbol,
SYMBOL_VOLUME_MIN);
double lotMax = SymbolInfoDouble(symbol,
SYMBOL_VOLUME_MAX);
double lotStep= SymbolInfoDouble(symbol,
SYMBOL_VOLUME_STEP);
double c=1.0/lotStep;
double l=floor(lot*c)/c;
if(l lotMax) l = lotMax;
return l;
}
Заключение
- Надежность передачи – файлы не используются одновременно разными процессами, при этом у каждого клиента имеется снимок текущих позиций;
- Копирование фиксированного и относительного объема позиций, поддержка модификации стоп уровней и частичного закрытия;
- Возможность применения на любом количестве терминалов MT4/MT5, с неограниченным количеством Провайдеров/Клиентов.
- Скорость чтения – не идеальный вариант для скальпинга, копирования тиков и любых других операций, требующих минимальной задержки;
- Нагрузка на диск – чем меньше задержка, тем чаще будет перезаписываться файл.
Скачать исходник Копировщика
С уважением, Дмитрий аkа Silentspec
#видео#metatrader 4#mql#metatrader 5#mql5