Price Data Components
Orders Execution
Miscellaneous
0
Views
0
Downloads
0
Favorites
SwapFinder_script
//+------------------------------------------------------------------+
//| SwapFinder_script.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Bogdan Caramalac"
#property link "mailto:fxeconomist@yahoo.com"
extern int MarginUsage=90;
extern int MaxCurrenciesUsed=3;
extern bool JustTesting=False;
extern int Slippage=3;
extern bool ShowNegatives=False;
#include <bclib.mqh>
#include <WinUser32.mqh>
//however, this will slow down the process
bool FatalError=false;
int TickDenominator=1;
string Appendix="";
int SwapType=-1;
//**************************************************************************************
bool IsConfigValid(string BinConfig,int Permutation,int &Loaded,string &contracts[16],int &ops[16])
{
bool res=false;
int i;
int perm[16];
bool cex1,cex2;
int Asc1=49;
string ctest1,ctest2;
string LoadedCrrcies[16];
string permcrrcies[16];
for (i=0;i<16;i++)
{
perm[i]=0;
permcrrcies[i]="";
LoadedCrrcies[i]="";
ops[i]=0;
contracts[i]="";
}
Loaded=0;
for (i=0;i<StringLen(BinConfig);i++)
{
if (StringGetChar(BinConfig,i)==Asc1)
{
LoadedCrrcies[Loaded]=UsableCurrencies[i];
Loaded=Loaded+1;
}
}
if (Loaded<3)
return(res);
GenPermutation(Permutation,Loaded,perm);
for (i=0;i<Loaded;i++)
{
permcrrcies[i]=LoadedCrrcies[perm[i]-1];
}
res=True;
for (i=0;i<Loaded;i++)
{
if (i==Loaded-1)
{
//supposing continuous sell...from the first currency, to the first again
//if a contract does not exist, it will be reversed and bought
ctest1=StringConcatenate(permcrrcies[i],permcrrcies[0],Appendix);
ctest2=StringConcatenate(permcrrcies[0],permcrrcies[i],Appendix);
cex1=ContractIsTraded(ctest1);
cex2=ContractIsTraded(ctest2);
if (cex1==False&&cex2==False)
{
res=false;
return(res);
}
if (cex1==True)
{
ops[i]=OP_SELL;
contracts[i]=ctest1;
}
else
{
ops[i]=OP_BUY;
contracts[i]=ctest2;
}
}
else
{
//supposing continuous sell...from the first currency, to the first again
//if a contract does not exist, it will be reversed and bought
ctest1=StringConcatenate(permcrrcies[i],permcrrcies[i+1],Appendix);
ctest2=StringConcatenate(permcrrcies[i+1],permcrrcies[i],Appendix);
cex1=ContractIsTraded(ctest1);
cex2=ContractIsTraded(ctest2);
if (cex1==False&&cex2==False)
{
res=false;
return(res);
}
if (cex1==True)
{
ops[i]=OP_SELL;
contracts[i]=ctest1;
}
else
{
ops[i]=OP_BUY;
contracts[i]=ctest2;
}
}
}//for (i=0;i<Loaded;i++)
return(res);
}
void EstablishSwaps(int CrrNo,string contracts[],int ops[],double volumes[],double &usage[],double &TotalUsed,double &Swaps[],double &Interests[],double &NormalROA[],double &WeightedROA[],double &ROA, double &ROE, bool ShowSwaps)
{
int i;
bool brokerfound=False;
double m_tick,m_lotsize;
int mode;
string crr1;
TotalUsed=0;
for (i=0;i<CrrNo;i++)
{
crr1=StringSubstr(contracts[i],0,3);
usage[i]=volumes[i]*GetCurrency(crr1,AccountCurrency(),Appendix);
TotalUsed=TotalUsed+usage[i];
}
for (i=0;i<CrrNo;i++)
{
crr1=StringSubstr(contracts[i],0,3);
if (ops[i]==OP_BUY)
{
Swaps[i]=MarketInfo(contracts[i],MODE_SWAPLONG);
mode=MODE_SWAPLONG;
}
else
{
Swaps[i]=MarketInfo(contracts[i],MODE_SWAPSHORT);
mode=MODE_SWAPSHORT;
}
Interests[i]=Swap2Interest_Volume(volumes[i],mode,StringSubstr(contracts[i],0,6),Appendix);
NormalROA[i]=((Interests[i]/usage[i])*100)*365;
WeightedROA[i]=NormalROA[i]*usage[i]/TotalUsed;
ROA=ROA+WeightedROA[i];
}
ROE=ROA*TotalUsed/AccountEquity();
}
void EstablishRing(int CrrNo,string contracts[],int ops[],double &volumes[],double &usage[],double &TotalUsed,
double &Swaps[],double &Interests[],double &NormalROA[],double &WeightedROA[],double &ROA, double &ROE,
double &FXResult, double &FinalROE, bool ShowSwaps)
{
string ctest1;
int ms;
bool cex1;
int i;
int available;
if (JustTesting==false)
available=Truncate(AccountFreeMargin()*AccountLeverage()*(MarginUsage/100.00));
else
available=Truncate(AccountEquity()*AccountLeverage()*(MarginUsage/100.00));
available=Truncate(AccountBalance()*AccountLeverage()*(MarginUsage/100.00));
//WriteLn("Available = "+DoubleToStr(available,0));
int q=available/CrrNo;
string crr1,crr2;
double got,units;
double mk,Interest;
string rev;
string ResultCrrcy;
int operation;
for (i=0;i<CrrNo;i++)
{
crr1=StringSubstr(contracts[i],0,3);
crr2=StringSubstr(contracts[i],3,3);
if (i==0)
{
volumes[i]=0;
mk=GetCurrency(AccountCurrency(),crr1,Appendix);
units=q*mk;
volumes[i]=UnitsToLots(units,contracts[i])*MarketInfo(contracts[i],MODE_LOTSIZE);
rev="";
if (ops[i]==OP_SELL)
{
got=volumes[i]*MarketInfo(contracts[i],MODE_BID);
ResultCrrcy=crr2;
}
else
{
got=volumes[i];
ResultCrrcy=crr1;
}
}
else
{
if (ResultCrrcy==crr1)//we have the 1st currency at entry, we have a SHORT
{
units=got;
volumes[i]=UnitsToLots(units,contracts[i])*MarketInfo(contracts[i],MODE_LOTSIZE);
rev="";
ResultCrrcy=crr2;
mk=MarketInfo(contracts[i],MODE_BID);
got=mk*volumes[i];
}
else//we have a LONG
{
mk=MarketInfo(contracts[i],MODE_ASK);
units=got*(1/mk);
rev="reversed";
volumes[i]=UnitsToLots(units,contracts[i])*MarketInfo(contracts[i],MODE_LOTSIZE);
ResultCrrcy=crr1;
got=volumes[i];
}
}//else if (i==0)
//usage[i]=volumes[i]*GetCurrency(crr1,AccountCurrency());
//TotalUsed=TotalUsed+usage[i];
//WriteLn(StringConcatenate("Got ",DoubleToStr(got,4)," in ",ResultCrrcy," by applying rate ",DoubleToStr(mk,4)," of ",contracts[i]," ",rev));
//WriteLn(StringConcatenate("---------", OrderType2Str(ops[i])," ",DoubleToStr(volumes[i],0)," ",contracts[i] ) );
}//for (i=0;i<CrrNo;i++)
ROA=0;
ROE=0;
FXResult=0;
for (i=0;i<CrrNo;i++)
{
FXResult=FXResult-MarketInfo(contracts[i],MODE_SPREAD)*(MarketInfo(contracts[i],MODE_TICKVALUE)/TickDenominator)*volumes[i]/10000;
}
FXResult=(FXResult/AccountEquity())*100;
EstablishSwaps(CrrNo,contracts,ops,volumes,usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE,ShowSwaps);
FinalROE=ROE+FXResult;
return;
}
void GetBestRing(int maxcrrcies, int &bestconfig, int &permutation, string lookfor,string lookops)
{
int icomb,maxperm,iperm;
double Usage[16];
int maxim;
string image;
string Contracts[16];
int Ops[16];
string combimg,permimg;
double Volumes[16];
bool valid;
double ROA,ROE;
double Swaps[16];
double NormalROA[16];
double WeightedROA[16];
double Interests[16];
int crrcies,iimg;
double TotalSwap,TotalUsed;
double FXResult,FinalROE;
int lookcomb=-1;
int lookperm=-1;
int best=-1;
permutation=-1;
double maximdbl=Truncate(MathPow(2,CurrenciesNo))-1;
double bestswap=-99999999;
double lookswap=-99999999;
bool look=false;
string lookfor0,lookfor1,lookfor2;
int lookops0,lookops1,lookops2;
if (StringLen(lookfor)!=0)
{
lookfor0=Upper(ReturnNthWord(lookfor,1));
if (StringElement(Upper(lookops),0)=="B")
lookops0=OP_BUY;
else
lookops0=OP_SELL;
lookfor1=Upper(ReturnNthWord(lookfor,2));
if (StringElement(Upper(lookops),1)=="B")
lookops1=OP_BUY;
else
lookops1=OP_SELL;
lookfor2=Upper(ReturnNthWord(lookfor,3));
if (StringElement(Upper(lookops),2)=="B")
lookops2=OP_BUY;
else
lookops2=OP_SELL;
look=True;
//ClearSplash();
//SplashLn( lookfor0+" "+lookfor1+" "+lookfor2+" "+OrderType2Str(lookops0)+" "+OrderType2Str(lookops1)+" "+OrderType2Str(lookops2) );
//SplashScreen();
}
maxim=MathRound(maximdbl);
WriteLn(StringConcatenate("Maximal combination: ",DoubleToStr(maxim,0)));
WriteLn("");
int fhandle=FileOpen("ringlist.txt",FILE_WRITE);
for (icomb=maxim;icomb>=0;icomb--)
{
image=Padl(ConvertTo(2,icomb),CurrenciesNo,"0");
crrcies=Occurs("1",image);
valid=false;
if (crrcies>=3&&crrcies<=maxcrrcies)
{
maxperm=Factorial(crrcies)-1;
combimg="";
for (iimg=0;iimg<CurrenciesNo;iimg++)
{
if (StringElement(image,iimg)=="1")
combimg=StringConcatenate(combimg,UsableCurrencies[iimg]," ");
}
WriteLn(StringConcatenate("Studying ",combimg," having ",DoubleToStr(maxperm+1,0)," permutations"));
for (iperm=0;iperm<=maxperm;iperm++)
{
ROA=-1;
ROE=-1;
valid=IsConfigValid(image,iperm,crrcies,Contracts,Ops);
if (valid==True)
{
EstablishRing(crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE,FXResult,FinalROE,False);
if (FatalError==true)
{
FileClose(fhandle);
return;
}
if (valid==false)
continue;
if ((FinalROE>0)||(FinalROE<0&&ShowNegatives==True))
{
WriteLn(StringConcatenate(" Found ring with ROA=",DoubleToStr(ROA,4),"% ROE=",DoubleToStr(ROE,4),"% FinalROE=",DoubleToStr(FinalROE,4),"%"));
if (FinalROE>0)
FileWrite(fhandle,StringConcatenate(Contracts[0]," ",Contracts[1]," ",Contracts[2]," ",StringElement(OrderType2Str(Ops[0]),0),
StringElement(OrderType2Str(Ops[1]),0),StringElement(OrderType2Str(Ops[2]),0)," ROA=",DoubleToStr(ROA,4),"% ROE=",DoubleToStr(ROE,4),"% FinalROE=",DoubleToStr(FinalROE,4),"%" ));
}
if (ROA>bestswap&&ROA>=0)
{
best=icomb;
permutation=iperm;
bestswap=ROA;
}//if (TotalSwap>=bestswap&&TotalSwap>=0)
if (look==True)
{
if (Contracts[0]==lookfor0&&Contracts[1]==lookfor1&&Contracts[2]==lookfor2&&Ops[0]==lookops0&&Ops[1]==lookops1&&Ops[2]==lookops2)
{
lookcomb=icomb;
lookperm=iperm;
lookswap=ROA;
}
}
}//if (valid==True);
}//for (iperm=0;iperm<=maxperm;iperm++)
}//if (crrcies>=3)
}//for (icomb=0;icomb<=maxim;icomb++)
Say(2,"Done");
if (lookperm!=-1)
{
best=lookcomb;
permutation=lookperm;
bestswap=lookswap;
}
WriteLn("Best has been chosen combination "+DoubleToStr(best,0));
bestconfig=best;
FileClose(fhandle);
return;
}
int GetMaxMagic()
{
int maxmagic=0;
int ntrades=OrdersTotal();
int i;
int mhere=0;
if (ntrades!=0)
{
for (i=0;i<ntrades;i++)
{
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
mhere=OrderMagicNumber();
if (mhere>maxmagic)
maxmagic=mhere;
}
}
return(mhere);
}
void TradeRing(int CrrNo,int Ops[],string Contracts[],double Volumes[],int Magic)
{
ClearSplash();
int i,Gle;
double price;
string ErrType,ErrText,ErrExplanation;
for (i=0;i<CrrNo;i++)
{
if (Ops[i]==OP_BUY)
price=MarketInfo(Contracts[i],MODE_ASK);
else
price=MarketInfo(Contracts[i],MODE_BID);
SplashLn("Trying with "+Contracts[i]+" "+DoubleToStr( NormalizeDouble(Volumes[i]/1000*0.01,2) , 2) ) ;
OrderSend(Contracts[i],Ops[i],NormalizeDouble(Volumes[i]/1000*0.01,2),price,Slippage,0,0,"RING "+DoubleToStr(Magic,0),Magic,0,Blue);
Gle=GetLastError();
if (Gle!=0)
{
TranslateError(Gle,ErrType,ErrText,ErrExplanation);
SplashLn(ErrType+CRLF()+ErrText+CRLF()+ErrExplanation);
SplashScreen();
}
}
}
void AnalyseRing(int nRing)
{
int crrcies=0;
double Usage[16];
string Contracts[16];
int Ops[16];
double Volumes[16];
double ROA,ROE;
double Swaps[16];
double NormalROA[16];
double WeightedROA[16];
double Interests[16];
double TotalUsed;
int ntrades=OrdersTotal();
int i,mhere;
double op;
op=0;
if (ntrades!=0)
{
for (i=0;i<ntrades;i++)
{
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
mhere=OrderMagicNumber();
if (mhere==nRing)
{
Contracts[crrcies]=StringSubstr(OrderSymbol(),0,6);
Ops[crrcies]=OrderType();
Volumes[crrcies]=OrderLots()*MarketInfo(OrderSymbol(),MODE_LOTSIZE);
//WriteLn(Contracts[crrcies]+" "+DoubleToStr(Ops[crrcies],0)+" "+DoubleToStr(Volumes[crrcies],2));
crrcies=crrcies+1;
op=op+OrderProfit();
}
}
if (crrcies!=0)
{
EstablishSwaps(crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE,False);
DisplayRing("Currently traded ring ( having magic "+Alltrim(DoubleToStr(mhere,0))+" )",(op/AccountEquity())*100,crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE);
}
}
return;
}
string Alligned(int optype)
{
if (optype==OP_BUY)
return("Buy");
else
return("Sell ");
}
void DisplayRing(string title,double op,int crrcies,string Contracts[],int Ops[],double &Volumes[],double &Usage[],double &TotalUsed,double &Swaps[],double &Interests[],double &NormalROA[],double &WeightedROA[],double &ROA, double &ROE)
{
int iimg;
ClearSplash();
SplashLn(title);
SplashLn("");
SplashLn("Usage("+AccountCurrency()+") % Op. Volume Lots Contract Swap Interest NormalROA WeightedROA");
SplashLn("");
for (iimg=0;iimg<crrcies;iimg++)
SplashLn( StringConcatenate(
Padl(DoubleToStr(Usage[iimg],2),10," ")," ",
Padl(DoubleToStr(Usage[iimg]/TotalUsed*100,4),8," ")," ",
Alligned(Ops[iimg])," ",
Padl(DoubleToStr(Volumes[iimg],2),10," ")," ",
Padl(DoubleToStr(Volumes[iimg]/MarketInfo(Contracts[iimg],MODE_LOTSIZE),2),6," ")," ",
Lower(Contracts[iimg])," ",
Padl(DoubleToStr(Swaps[iimg],4),10," ")," ",
Padl(DoubleToStr(Interests[iimg],4),10," ")," ",
Padl(DoubleToStr(NormalROA[iimg],4),10," ")," ",
Padl(DoubleToStr(WeightedROA[iimg],4),10," ")
));
SplashLn("");
SplashLn(DoubleToStr(TotalUsed,2));
SplashLn("");
SplashLn(" ROA = "+DoubleToStr(ROA,4)+"%");
SplashLn(" ROE = "+DoubleToStr(ROE,4)+"%");
if (op!=0)
{
SplashLn("");
SplashLn("Forex result = "+DoubleToStr(op,4)+"%");
SplashLn("");
SplashLn("Final ROE = "+DoubleToStr(ROE+op,4)+"%");
}
SplashScreen();
}
void ScanRings(int maxcrrcies)
{
string Contracts[16];
int Ops[16];
double Volumes[16];
double Usage[16];
string image;
double ROA,ROE;
double Swaps[16];
double NormalROA[16];
double WeightedROA[16];
double Interests[16];
double FXResult,FinalROE;
bool valid;
int mb;
int gmm,icrt;
double TotalUsed;
int bestconfig,bestperm,crrcies,iimg,ms;
GetBestRing(maxcrrcies,bestconfig,bestperm,"","");
if (FatalError==true)
return;
if (bestconfig!=-1)
{
image=Padl(ConvertTo(2,bestconfig),CurrenciesNo,"0");
valid=IsConfigValid(image,bestperm,crrcies,Contracts,Ops);
EstablishRing(crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE,FXResult,FinalROE,True);
if (FinalROE>0)
{
ClearSplash();
DisplayRing("Best ring found ",FXResult,crrcies,Contracts,Ops,Volumes,Usage,TotalUsed,Swaps,Interests,NormalROA,WeightedROA,ROA,ROE);
SplashLn("Combination = "+DoubleToStr(bestconfig,0) );
SplashLn("Permutation ="+DoubleToStr(bestperm,0) );
}
else
{
ClearSplash();
SplashLn("Sorry, nothing found!");
SplashScreen();
ClearSplash();
}
}
else
{
ClearSplash();
SplashLn("Sorry, nothing found!");
SplashScreen();
ClearSplash();
}
if (JustTesting==True) //era (OrdersTotal()!=0||JustTesting==True)
mb=SplashScreen();
else
{
if (bestconfig!=-1)
{
SplashLn("");
SplashLn("Trade ring ?");
mb=SplashScreen(MB_YESNO);
if (mb==IDYES)
{
TradeRing(crrcies,Ops,Contracts,Volumes,GetMaxMagic()+1);
}
}
}
ClearSplash();
gmm=GetMaxMagic();
if (gmm!=0)
{
for (icrt=0;icrt<=gmm;icrt++)
AnalyseRing(icrt);
}
}
int init()
{
Appendix=GetSymbolsAppendix();
TickDenominator=GetTickDenominator(Appendix);
GetCurrenciesAndPairs(Appendix);
SetTextParameters("Courier New",10);
ClearText();
if (FatalError==true)
return;
for (int i=0;i<CurrenciesNo;i++)
Write(UsableCurrencies[i]+" ");
WriteLn("");
WriteLn("");
SetTextFirstScroll(4);
if ((JustTesting==false)&&(IsTradeAllowed()==false))
{
WriteLn("Script is set to trade, yet not allowed from setup window at startup!");
FatalError=true;
}
if (FatalError==true)
return(1);
return(0);
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int gm=GetMaxMagic();
if (gm!=0)
{
for (int i=1;i<=gm;i++)
{
AnalyseRing(i);
}
}
if (MaxCurrenciesUsed==0)
ScanRings(CurrenciesNo);
else
ScanRings(MaxCurrenciesUsed);
return(0);
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---