//+------------------------------------------------------------------+
//|                                               Baseline Model.mq5 |
//|                                               Gamuchirai Ndawana |
//|                    https://www.mql5.com/en/users/gamuchiraindawa |
//+------------------------------------------------------------------+
#property copyright "Gamuchirai Ndawana"
#property link      "https://www.mql5.com/en/users/gamuchiraindawa"
#property version   "1.00"

//+------------------------------------------------------------------+
//| System Constants                                                 |
//+------------------------------------------------------------------+
#define SYMBOL_ONE   "XAGUSD"                                                       //--- Our primary   symbol, the price of Silver in USD
#define SYMBOL_TWO   "XAGEUR"                                                       //--- Our secondary symbol, the price of Silver in EUR
#define SYMBOL_THREE "EURUSD"                                                       //--- Our EURUSD exchange rate.
#define FETCH        24                                                             //--- How many bars of data should we fetch?
#define TF_1         PERIOD_H1                                                      //--- Our intended time frame
#define VOLUME       SymbolInfoDouble(SYMBOL_ONE,SYMBOL_VOLUME_MIN) * 10            //--- Our trading volume

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
vector eurusd,xagusd,xageur;
double eurusd_growth,xagusd_growth,xageur_growth,bid,ask;
double sl_width = 3e2 * _Point;

//+------------------------------------------------------------------+
//| Libraries                                                        |
//+------------------------------------------------------------------+
#include  <Trade\Trade.mqh>
CTrade Trade;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Setup our technical indicators
   setup();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- New prices have been quoted
   new_quotes_received();
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom functions                                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Updates system variables accordingly                             |
//+------------------------------------------------------------------+
void new_quotes_received(void)
  {
   static datetime time_stamp;
   datetime time = iTime(SYMBOL_ONE,TF_1,0);

   if(time_stamp != time)
     {
      time_stamp = time;
      update();
     }
  }

//+------------------------------------------------------------------+
//| Setup our technical indicators and select the symbols we need    |
//+------------------------------------------------------------------+
void setup(void)
  {
//--- Select the symbols we need
   SymbolSelect(SYMBOL_ONE,true);
   SymbolSelect(SYMBOL_TWO,true);
   SymbolSelect(SYMBOL_THREE,true);
  }

//+------------------------------------------------------------------+
//| Update our system setup                                          |
//+------------------------------------------------------------------+
void update(void)
  {
//--- Fetch updated prices
   xagusd.CopyRates(SYMBOL_ONE,TF_1,COPY_RATES_CLOSE,1,FETCH);
   xageur.CopyRates(SYMBOL_TWO,TF_1,COPY_RATES_CLOSE,1,FETCH);
   eurusd.CopyRates(SYMBOL_THREE,TF_1,COPY_RATES_CLOSE,1,FETCH);

//--- Calculate the growth in market prices
   eurusd_growth = eurusd[0] / eurusd[FETCH - 1];
   xageur_growth = xageur[0] / xageur[FETCH - 1];
   xagusd_growth = xagusd[0] / xagusd[FETCH - 1];

//--- Update system variables
   SymbolSelect(SYMBOL_ONE,true);

   bid = SymbolInfoDouble(SYMBOL_ONE,SYMBOL_BID);
   ask = SymbolInfoDouble(SYMBOL_ONE,SYMBOL_ASK);

//--- Check if we need to setup a new position
   if(PositionsTotal() == 0)
      find_setup();

//--- Check if we need to manage our positions
   if(PositionsTotal() > 0)
      manage_setup();

//--- Give feedback on the market growth
   Comment("EURUSD Growth: ",eurusd_growth,"\nXAGEUR Growth: ",xageur_growth,"\nXAGUSD Grwoth: ",xagusd_growth);
  }

//+------------------------------------------------------------------+
//| Find setup                                                       |
//+------------------------------------------------------------------+
void find_setup(void)
  {
  
   //--- Check if the current market setup matches our expectations for selling
   if((eurusd_growth < 1) && (xageur_growth > 1) && (xagusd_growth < 1))
     {
      Trade.Sell(VOLUME,SYMBOL_ONE,bid,(ask + sl_width),(ask - sl_width),"");
     }

   //--- Check if the current market setup matches our expectations for buying
   if((eurusd_growth > 1) && (xageur_growth < 1) && (xagusd_growth > 1))
     {
      Trade.Buy(VOLUME,SYMBOL_ONE,ask,(bid - sl_width),(bid + sl_width),"");
     }
  }

//+------------------------------------------------------------------+
//| Manage setup                                                     |
//+------------------------------------------------------------------+
void manage_setup(void)
  {
   //--- Select our open position
   if(PositionSelect(SYMBOL_ONE))
     {
      double current_sl = PositionGetDouble(POSITION_SL);
      double current_tp = PositionGetDouble(POSITION_TP);

      //--- Buy setup
      if(current_sl < current_tp)
        {
         if((bid - sl_width) > current_sl)
            Trade.PositionModify(SYMBOL_ONE,(bid - sl_width),(bid + sl_width));
        }

      //--- Sell setup
      if(current_sl > current_tp)
        {
         if((ask + sl_width) < current_sl)
            Trade.PositionModify(SYMBOL_ONE,(ask + sl_width),(ask - sl_width));
        }
     }
  }

//+------------------------------------------------------------------+
//| Undefine system constants                                        |
//+------------------------------------------------------------------+
#undef TF_1
#undef SYMBOL_ONE
#undef SYMBOL_TWO
#undef SYMBOL_THREE
#undef VOLUME
#undef FETCH