SwapFinder_script

Author: Bogdan Caramalac
Price Data Components
Series array that contains tick volumes of each bar
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reached
Miscellaneous
Uses files from the file systemIt writes information to file
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 supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---