多币种交易程序架构设计-Multi currency transaction program architecture design

jayMetaTrader 4 EA交易4年前 (2021-07-03)193
可以用多个品种在一个图表上交易 - 在MQL5代码库免费下载MetaTrader 4的'多币种交易程序架构设计-Multi currency transaction program architecture design' ('zybsuper5135')EA, 2021.04.17...

//+------------------------------------------------------------------+

//| muskEAone.mq4 |

//| BillAbiao,QQ:327151901,WX:billabiao |

//| https://one.exness.link/a/sduus6ff |

//+------------------------------------------------------------------+

#property copyright "点击开户:BillAbiao,QQ:327151901,WX:billabiao"

#property link "https://one.exness.link/a/sduus6ff"

#property version "1.00"

#property strict

//------------

string userSymbols2[]={"EURUSD","GBPUSD","GBPCHF"};

//string userSymbols2[]={"EURUSD"};

//string userSymbols2[];

string systemSymbols[];

string debugMsg;

double minEquity,maxEquity;

bool stopFlagRun=false;

//----------

struct CONTROL_DATA{

int index;

string strSymbol;

ENUM_TIMEFRAMES timeFrame;//=PERIOD_H2;

int ExtHandle;

// CTrade ExtTrade;

int magicma;

int switchDo;

int orders_buy,orders_sell;

int orders_pending_buy,orders_pending_sell;

double minOpenPrice_buy,minOpenPrice_sell;

ulong maxOpenPrice_buy_ticket;

ulong minOpenPrice_buy_ticket;

double maxOpenPrice_buy,maxOpenPrice_sell;

double maxPendingOpenPrice_buy,maxPendingOpenPrice_sell;

ulong maxPendingOpenPrice_buy_ticket,maxPendingOpenPrice_sell_ticket;

double minPendingOpenPrice_buy,minPendingOpenPrice_sell;

ulong minPendingOpenPrice_buy_ticket,minPendingOpenPrice_sell_ticket;

double profit_buy,profit_sell;

double volume_buy,volume_sell;

ENUM_ORDER_TYPE signal;

double agvLen;

double minOpenPrice_profitBuy;

double maxOpenPrice_profitBuy;

double maxOpenPrice_volume;

double minOpenPrice_buyVolume;

double maxProfitBuy,minProfitBuy;

datetime lastOpenDateTime;

double maxPendingOpenPrice_volume;

double magicN;

double skip;

ulong stopLevel;//=SymbolInfoInteger(d[index].strSymbol,SYMBOL_SPREAD);

double point;

ulong spread;

double lastAsk;

double ask,bid;

int digits;

};

CONTROL_DATA d[];

#define MAGICMA 03082100

//+------------------------------------------------------------------+

//| Expert initialization function |

//+------------------------------------------------------------------+

int OnInit()

{

//---

initSymbols();

int n=ArraySize(systemSymbols);

ArrayResize(d,n);

for(int i=0;i<n;i++)

{

OnInit_INDEX(i);

}

//---

EventSetTimer(6);

minEquity=0;

maxEquity=0;

return(INIT_SUCCEEDED);

}

void OnInit_INDEX(int index)

{

int k=index;

d[k].index=index;

d[k].strSymbol=systemSymbols[index];

d[k].timeFrame=PERIOD_H1;

d[k].magicma=MAGICMA+index;

d[k].switchDo=1;

d[k].maxProfitBuy=0;

d[k].minProfitBuy=0;

d[k].magicN=5;

d[k].lastAsk=SymbolInfoDouble(d[k].strSymbol,SYMBOL_ASK);

}

void initSymbols()

{

int n=ArraySize(userSymbols2);

ArrayResize(systemSymbols,n);

int i;

for(i=0;i<n;i++)

{

// systemSymbols[i]=userSymbols2[i];

systemSymbols[i]=getSystemSymbol(userSymbols2[i]);

}

return ;

}

string getSystemSymbol(string strSymbol)

{

string ret="";

int n=SymbolsTotal(false);

int i;

string strTemp=strSymbol;

StringToLower(strTemp);

for(i=0;i<n;i++)

{

string name=SymbolName(i,false);

StringToLower( name);

if( strTemp==StringSubstr(name,0,6))

{

ret=SymbolName(i,false);

break;

}

}

return ret;

}

//+------------------------------------------------------------------+

//| Expert deinitialization function |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

EventKillTimer();

}

//+------------------------------------------------------------------+

//| Expert tick function |

//+------------------------------------------------------------------+

void OnTick()

{

//---

MainRUN( "Tick " );

return ;

/*

debugMsg="";

mainRun();

Comment(debugMsg);

*/

}

void OnTimer()

{

MainRUN( "Timer" );

return ;

}

bool runFlag=false;

void MainRUN( string strWho)

{

if( runFlag) return ;

runFlag=true;

debugMsg=strWho+": ";

mainRun();

runFlag=false;

Comment(debugMsg);

return ;

}

//+------------------------------------------------------------------+

void mainRun()

{

getMainData();

if( stopFlagRun) return ;

int i,n=ArraySize(d);

for( i=0;i<n;i++)

{

subControlSymbol(i);

}

return ;

}

void getMainData()

{

debugMsg+="mainData,";

debugMsg+=StringFormat("date=%s\n", TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS));

double equity=AccountEquity();

if( minEquity==0 || equity<minEquity) minEquity=equity;

if( maxEquity==0 || equity>maxEquity) maxEquity=equity;

debugMsg+=StringFormat("minEquity=%.2f,maxEquity=%.2f,Equity=%.2f\n",minEquity,maxEquity,equity);

if( equity<10)

{

stopFlagRun=true;

}

return ;

}

void subControlSymbol(int index)

{

debugMsg+=StringFormat("%d--> %s\n",index+1, d[index].strSymbol);

control_getdata(index);

switch (d[index].switchDo)

{

case 1:

d[index].switchDo=2;

control_open(index);

break;

case 2:

d[index].switchDo=3;

control_close(index);

break;

case 3:

d[index].switchDo=1;

control_modify(index);

break;

}

//------

debugMsg+="\n";

return ;

}

void control_open(int index)

{

debugMsg+="open\n";

double lots=0.01;

/*

if( d[index].orders_buy==0)

{

double ask=SymbolInfoDouble(d[index].strSymbol,SYMBOL_ASK);

bool res=OrderSend(d[index].strSymbol,OP_BUY,lots,ask,3,0,0,"",d[index].magicma,0,Blue);

return ;

}

if( d[index].orders_sell==0)

{

double bid=SymbolInfoDouble(d[index].strSymbol,SYMBOL_BID);

bool res=OrderSend(d[index].strSymbol,OP_SELL,lots,bid,3,0,0,"",d[index].magicma,0,Red);

return ;

}

*/

if( d[index].ask==d[index].lastAsk){

//debugMsg+="-------------\n";

return ;

}

d[index].lastAsk=d[index].ask;

if( d[index].orders_pending_buy==0 && d[index].orders_buy==0)

{

double ask=SymbolInfoDouble(d[index].strSymbol,SYMBOL_ASK);

double price=ask-d[index].point*(d[index].stopLevel+1);

price=NormalizeDouble(price,d[index].digits);

int res=OrderSend(d[index].strSymbol,OP_BUYLIMIT,lots,price,3,0,0,"",d[index].magicma,0,Blue);

if( res<0 ){

// stopFlagRun=true;

Print("open limit price=",price);

Print("ask=",ask);

}

return ;

}

if( d[index].orders_pending_buy==0) //add pending order

{

double val_1=2*d[index].point*(d[index].stopLevel);

// double val_2=d[index].point*d[index].spread;

double price;//=d[index].minOpenPrice_buy-val_1;//d[index].point*d[index].stopLevel;

double ask=SymbolInfoDouble(d[index].strSymbol,SYMBOL_ASK);

if( ask<d[index].minOpenPrice_buy)

{

price=ask-val_1;

}

else{

price=d[index].minOpenPrice_buy-val_1;

}

//if( ask-price<= val_1*1.5) return ;

lots=countVolumeBuy(index,price);

if( lots<=0) return ;

price=NormalizeDouble(price,d[index].digits);

int res=OrderSend(d[index].strSymbol,OP_BUYLIMIT,lots,price,3,0,0,"",d[index].magicma,0,Blue);

if( res<0 ){

// stopFlagRun=true;

Print("limit price=",price);

Print("ask=",ask);

}

}

return ;

}

double countVolumeBuy(int index, double openPrice)

{

double ret=0;

int i,n=OrdersTotal();

//if( n<=0) return ;

double val=1.5*d[index].point*d[index].stopLevel;

if( val<=0) return ret;

double setPrice=openPrice+val;

double profitAll=0;

for(i=0;i<n;i++)

{

if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

continue;

if( OrderSymbol()!=d[index].strSymbol) continue;

if( OrderMagicNumber()!=d[index].magicma) continue;

profitAll+=(OrderOpenPrice()-setPrice)*OrderLots()*100;

}

ret=MathAbs(profitAll)/(100*val);

double maxLots=SymbolInfoDouble(d[index].strSymbol,SYMBOL_VOLUME_MAX);

if( ret>maxLots) ret=maxLots;

if( ret>0 && ret<0.01) ret=0.01;

ret=NormalizeDouble(ret,2);

return ret;

}

void control_close(int index)

{

debugMsg+="close\n";

if( d[index].orders_buy==0 && d[index].orders_pending_buy>0)

{

double val=d[index].maxPendingOpenPrice_buy+d[index].point*d[index].stopLevel;

if( d[index].bid>val)

{

deleteAllPendingOrders(index,OP_BUYLIMIT);

return ;

}

}

if( d[index].orders_buy>0 )

{

double val=d[index].point*d[index].stopLevel;

if( d[index].bid> d[index].maxOpenPrice_buy+val)

{

closeAllOrders(index, OP_BUY);

deleteAllPendingOrders(index,OP_BUYLIMIT);

return ;

}

double val2=d[index].minOpenPrice_buy+1.5*d[index].stopLevel*d[index].point;

//debugMsg+=StringFormat("val2=%.5f\n",val2);

if( d[index].bid> val2 && d[index].minOpenPrice_profitBuy+ d[index].maxOpenPrice_profitBuy>0)

{

debugMsg+=StringFormat("val2=%.5f\n",val2);

closeSomeOrders(index);

deleteAllPendingOrders(index,OP_BUYLIMIT);

return ;

}

}

return ;

}

void deleteAllPendingOrders(int index,int orderType)

{

//for(;;)

// {

int i,n;

n=OrdersTotal();

if( n<=0) return ;

for(i=0;i<n;i++)

{

if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

continue;

if( OrderSymbol()!=d[index].strSymbol) continue;

if( OrderMagicNumber()!=d[index].magicma) continue;

/*

if(OrderType()==OP_BUY)

{

double bid=SymbolInfoDouble(OrderSymbol(), SYMBOL_BID);

if(!OrderClose(OrderTicket(),OrderLots(),bid,3,Violet))

{

break;

}

}

else if(OrderType()==OP_SELL)

{

double ask=SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK);

if(!OrderClose(OrderTicket(),OrderLots(),ask,3,Violet))

{

break;

}

}*/

if(OrderType()==orderType){

bool ret=OrderDelete(OrderTicket(),Violet);

}

}

// }

}

void closeAllOrders(int index,int orderType)

{

//for(;;)

// {

int i,n;

n=OrdersTotal();

if( n<=0) return ;

for(i=0;i<n;i++)

{

if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

continue;

if( OrderSymbol()!=d[index].strSymbol) continue;

if( OrderMagicNumber()!=d[index].magicma) continue;

if( OrderType()!=orderType) continue;

if(OrderType()==OP_BUY)

{

double bid=SymbolInfoDouble(OrderSymbol(), SYMBOL_BID);

if(!OrderClose(OrderTicket(),OrderLots(),bid,3,Violet))

{

break;

}

}

else if(OrderType()==OP_SELL)

{

double ask=SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK);

if(!OrderClose(OrderTicket(),OrderLots(),ask,3,Violet))

{

break;

}

}

//if(OrderType()==orderType){

// bool ret=OrderDelete(OrderTicket(),Violet);

//}

}

// }

}

void closeSomeOrders(int index)

{

int i,n;

n=OrdersTotal();

if( n<=0) return ;

for(i=0;i<n;i++)

{

if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

continue;

if( OrderSymbol()!=d[index].strSymbol) continue;

if( OrderMagicNumber()!=d[index].magicma) continue;

//if( OrderType()!=orderType) continue;

if(OrderType()==OP_BUY)

{

if( OrderTicket()==d[index].maxOpenPrice_buy_ticket || OrderTicket()==d[index].minOpenPrice_buy_ticket)

{

double bid=SymbolInfoDouble(OrderSymbol(), SYMBOL_BID);

if(!OrderClose(OrderTicket(),OrderLots(),bid,3,Violet))

{

break;

}

}

}

}

}

void control_modify(int index)

{

debugMsg+="modify\n";

}

void control_getdata(int index)

{

debugMsg+="control getdata,";

d[index].spread=SymbolInfoInteger(d[index].strSymbol,SYMBOL_SPREAD);

d[index].point=SymbolInfoDouble(d[index].strSymbol, SYMBOL_POINT);

d[index].stopLevel=SymbolInfoInteger(d[index].strSymbol, SYMBOL_TRADE_STOPS_LEVEL);

debugMsg+=StringFormat("spread=%d, point=%.5f, stopLevel=%d\n",d[index].spread ,d[index].point, d[index].stopLevel) ;

//--

uint dataLen=60;

double allLen=0;

ENUM_TIMEFRAMES timeFrame=PERIOD_D1;

// timeFrame=d[index].timeFrame;

uint i;

for(i=0;i<dataLen;i++)

{

double high=iHigh(d[index].strSymbol,timeFrame,i+1);

double low=iLow(d[index].strSymbol,timeFrame,i+1);

allLen+=MathAbs( high-low);

}

d[index].agvLen= allLen/(dataLen);

d[index].skip=d[index].agvLen/6;

debugMsg+=StringFormat( "agvLen=%.5f, skip=%.5f\n", d[index].agvLen, d[index].skip);

//-------

int buys=0,sells=0;

d[index].orders_pending_buy=0;

d[index].orders_pending_sell=0;

d[index].minOpenPrice_buy=0;

d[index].maxOpenPrice_buy=0;

d[index].minPendingOpenPrice_buy=0;

d[index].maxPendingOpenPrice_buy=0;

d[index].profit_buy=0;

d[index].profit_sell=0;

//---

uint n=OrdersTotal();

for(i=0;i<n;i++)

{

if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;

if(OrderSymbol()==d[index].strSymbol && OrderMagicNumber()==d[index].magicma )

{

double price=OrderOpenPrice();

if(OrderType()==OP_BUY){

buys++;

double buyProfit=OrderProfit()+OrderCommission()+OrderSwap();

if( d[index].minOpenPrice_buy==0 || price<d[index].minOpenPrice_buy)

{

d[index].minOpenPrice_buy=price;

d[index].minOpenPrice_buy_ticket=OrderTicket();

d[index].minOpenPrice_profitBuy=buyProfit;

}

if( d[index].maxOpenPrice_buy==0 || price>d[index].maxOpenPrice_buy)

{

d[index].maxOpenPrice_buy=price;

d[index].maxOpenPrice_buy_ticket=OrderTicket();

d[index].maxOpenPrice_profitBuy=buyProfit;

}

d[index].profit_buy+=OrderProfit()+OrderCommission()+OrderSwap();

}

else if(OrderType()==OP_SELL){

sells++;

d[index].profit_sell+=OrderProfit()+OrderCommission()+OrderSwap();

}

else if(OrderType()==OP_BUYLIMIT){

d[index].orders_pending_buy++;

if( d[index].minPendingOpenPrice_buy==0 || price<d[index].minPendingOpenPrice_buy )

{

d[index].minPendingOpenPrice_buy=price;

}

if( d[index].maxPendingOpenPrice_buy==0 || price>d[index].maxPendingOpenPrice_buy )

{

d[index].maxPendingOpenPrice_buy=price;

}

}

else if(OrderType()==OP_SELLLIMIT){

d[index].orders_pending_sell++;

}

}

}

d[index].orders_buy=buys;

d[index].orders_sell=sells;

debugMsg+=StringFormat( "buys=%d, sells=%d\n", d[index].orders_buy, d[index].orders_sell);

debugMsg+=StringFormat( "pendingbuys=%d, pendingsells=%d\n", d[index].orders_pending_buy, d[index].orders_pending_sell);

debugMsg+=StringFormat( "minOpenPrice=%.5f, maxOpenPrice=%.5f\n", d[index].minOpenPrice_buy, d[index].maxOpenPrice_buy);

debugMsg+=StringFormat( "minPendingOpenPrice=%.5f, maxPendingOpenPrice=%.5f\n", d[index].minPendingOpenPrice_buy, d[index].maxPendingOpenPrice_buy );

//-----------

d[index].bid=SymbolInfoDouble( d[index].strSymbol, SYMBOL_BID);

d[index].ask=SymbolInfoDouble( d[index].strSymbol, SYMBOL_ASK);

debugMsg+=StringFormat( "profit_buy=%.2f, profit_sell=%.2f\n", d[index].profit_buy, d[index].profit_sell);

d[index].digits=(int)SymbolInfoInteger(d[index].strSymbol,SYMBOL_DIGITS);

return ;

}

----------------------

打包下載:ZIP下載

----------------------

扫描二维码推送至手机访问。

本文转载自互联网,如有侵权,联系删除。

本文链接:https://www.fxajax.com/MT4EA/124433.html

您暂未设置收款码

请在主题配置——文章设置里上传

扫描二维码手机访问