Robot Example 3 – Moving Average Crossover

0

Here is the MetaTrader MQL4 source code for our third example robot, which implements a double moving average crossover system.

//+------------------------------------------------------------------+
//|                                                     GuruEx03.mq4 |
//|     Copyright © 2009, Marketing Dreams Ltd. All Rights Reserved. |
//|                                         http://trading-gurus.com |
//|                                                                  |
//| GuruTrader™ example 3                                            |
//| Version 1.0                                                      |
//|                                                                  |
//| A basic moving average crossover system                          |
//|                                                                  |
//| Wealth Warning! This expert is for educational purposes only.    |
//| It should NEVER be used on a live account. Past performance is   |
//| in no way indicative of future results!                          |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Marketing Dreams Ltd."
#property link      "http://trading-gurus.com"
#define SLEEP_OK     250
#define SLEEP_ERR    250
//---- input parameters
extern int     Magic = 12347;
extern int     Slippage=30;
extern double  Lots=1.0;
extern int     FastPeriod=20;
extern int     SlowPeriod=33;
extern int     Hysteresis=4;
//---- static variables
static int     Dig;
static double  Points;
static bool    Initialized = FALSE;
static bool    Running = FALSE;
static bool    Long = FALSE;
static double  Fast;
static double  Slow;
static double  LastFast;
static double  LastSlow;
static int     OrderNumber;
static double  PositionSize;
static color   clBuy = DodgerBlue;
static color   clSell = Crimson;
//+------------------------------------------------------------------+
//| Utility functions                                                |
//+------------------------------------------------------------------+
#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh>
//+------------------------------------------------------------------+
//| Expert helper functions                                          |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Closes an order at market                                        |
//+------------------------------------------------------------------+
int CloseMarket(int Ticket)
{
   int    Type, ErrorCode;
   double Price, Quantity;
   OrderSelect(Ticket, SELECT_BY_TICKET);
   Type = OrderType();
   Quantity = OrderLots();
   while (TRUE) {             // Keep trying until the order really is closed
      if (Type == OP_BUY)
         Price=Bid;
      else if (Type == OP_SELL)
         Price=Ask;
      else
         return (-1);
      Print("CLOSE ", Ticket, ", ", Quantity, ", ", Price);
      if (OrderClose(Ticket, Quantity, Price, Slippage, CLR_NONE) == TRUE) {
         Sleep(SLEEP_OK);
         return (0);
      }
      else {
         ErrorCode = GetLastError();
         Print("Error closing order ", Ticket, ": ", ErrorDescription(ErrorCode),
               " (", ErrorCode, ")", " size: ", Quantity, ", prices: ",
               Price, ", ", Bid, ", ", Ask);
         Sleep(SLEEP_ERR);
         RefreshRates();
      }
   }
   return (-1);
}
//+------------------------------------------------------------------+
//| Places an order                                                  |
//+------------------------------------------------------------------+
int Order(string symbol, int Type, double Entry, double Quantity,
          double TargetPrice, double StopPrice, string comment="")
{
   string TypeStr;
   color  TypeCol;
   int    ErrorCode, Ticket;
   double Price, FillPrice;
   Price = NormalizeDouble(Entry, Dig);
   switch (Type) {
      case OP_BUY:
         TypeStr = "BUY";
         TypeCol = clBuy;
         break;
      case OP_SELL:
         TypeStr = "SELL";
         TypeCol = clSell;
         break;
      default:
         Print("Unknown order type ", Type);
         break;
   }
   Ticket = OrderSend(symbol, Type, Quantity, Price, Slippage,
              StopPrice, TargetPrice, comment, Magic, 0, TypeCol);
   if (Ticket >= 0) {
      Sleep(SLEEP_OK);
      if (OrderSelect(Ticket, SELECT_BY_TICKET) == TRUE) {
         FillPrice = OrderOpenPrice();
         if (Entry != FillPrice) {
            RefreshRates();
            Print("Slippage on order ", Ticket, " - Requested = ",
                  Entry, ", Fill = ", FillPrice, ", Current Bid = ",
                  Bid, ", Current Ask = ", Ask);
         }
      }
      else {
         ErrorCode = GetLastError();
         Print("Error selecting new order ", Ticket, ": ",
               ErrorDescription(ErrorCode), " (", ErrorCode, ")");
      }
      return (Ticket);
   }
   ErrorCode = GetLastError();
   RefreshRates();
   Print("Error opening ", TypeStr, " order: ", ErrorDescription(ErrorCode),
         " (", ErrorCode, ")", ", Entry = ", Price, ", Target = ",
         TargetPrice, ", Stop = ", StopPrice, ", Current Bid = ", Bid,
         ", Current Ask = ", Ask);
   Sleep(SLEEP_ERR);
   return (-1);
}
//+------------------------------------------------------------------+
//| Performs system initialisation                                   |
//+------------------------------------------------------------------+
void InitSystem()
{
   Running = FALSE;
   PositionSize = Lots;
   RefreshRates();
   LastFast = iMA(Symbol(), 0, FastPeriod, 0, MODE_EMA, PRICE_MEDIAN, 0);
   LastSlow = iMA(Symbol(), 0, SlowPeriod, 0, MODE_EMA, PRICE_MEDIAN, 0);
   if (LastFast > LastSlow)
      Long = TRUE;
   Initialized = TRUE;
}
//+------------------------------------------------------------------+
//| Checks for entry to a trade - Exits previous trade also          |
//+------------------------------------------------------------------+
int CheckEntry(double Size)
{
   if (!Long && (Fast > (Slow + Hysteresis * Points))) {
      // Fast MA crossed above slow MA so GO LONG!
      if (OrderNumber > 0)
         CloseMarket(OrderNumber);  // Close previous short order
      OrderNumber = Order(Symbol(), OP_BUY, Ask, Size, 0, 0);
      if (OrderNumber > 0) {
         Long = TRUE;
         return(1);
      }
   }
   else if (Long && (Fast < (Slow - Hysteresis * Points))) {
      // Fast MA crossed below slow MA so GO SHORT!
      if (OrderNumber > 0)
         CloseMarket(OrderNumber);  // Close previous long order
      OrderNumber = Order(Symbol(), OP_SELL, Bid, Size, 0, 0);
      if (OrderNumber > 0) {
         Long = FALSE;
         return(1);
      }
   }
   return(0);
}
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
   Dig = MarketInfo(Symbol(), MODE_DIGITS);
   Points = MarketInfo(Symbol(), MODE_POINT);
   Print("Digits = ", Dig, ", Points = ", DoubleToStr(Points, 5));
   if (!IsDemo() && !IsTesting()) {
      MessageBox("Wealth Warning! This expert is for educational purposes only." +
            " It should NEVER be used on a live account." +
            " Past performance is in no way indicative of future results!");
      Print("Initialization Failure");
      return(-1);
   }
   InitSystem();
   Print("Initialized OK");
   return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
    Print("DeInitialized OK");
    return(0);
}
//+------------------------------------------------------------------+
//| Expert start function                                            |
//| Executed on every tick                                           |
//+------------------------------------------------------------------+
int start()
{
   if (!Initialized) {
      return(-1);
   }
   LastFast = Fast;
   LastSlow = Slow;
   Fast = iMA(Symbol(), 0, FastPeriod, 0, MODE_EMA, PRICE_MEDIAN, 0);
   Slow = iMA(Symbol(), 0, SlowPeriod, 0, MODE_EMA, PRICE_MEDIAN, 0);
   if (CheckEntry(PositionSize) > 0) { // Entered a trade?
      Running = TRUE;                  // Yes - Indicate that we're in a trade
   }
   return(0);
}

Leave a Comment

Fields marked by an asterisk (*) are required.