SimpleGrail

Author: Copyright � 2009, LEHayes

This script is designed to automatically trade on the Forex market based on a simple trend-following strategy. Here's a breakdown of how it works:

  1. Setup: The script starts by defining various settings that you can adjust, such as the stop-loss distance (the maximum amount you're willing to lose on a trade), the trailing stop (a feature that automatically moves your stop-loss order to protect profits as the price moves in your favor), the size of the trades it places (Lots), a unique "magic number" to identify its own trades, the maximum number of orders it will open at once, and a percentage for free assets.

  2. Order Management: The script constantly monitors all open trades with its specific "magic number." If the trailing stop feature is enabled, it adjusts the stop-loss levels of these trades to lock in profits as the price moves in a favorable direction.

  3. Trend Detection: The core of the script is its simple trend detection. It looks at the recent high and open prices of the currency pair. It determines if a buy signal arises when the last open and high prices are bigger than their predecessors (3 previous bars). A sell signal arise when those prices are smaller than the last 3 bars.

  4. Trading Logic:

    • It checks if the account has enough free margin (available funds) to place trades.
    • It checks if the maximum number of orders have been opened.
    • If both conditions are met and a trend is detected (either an upward or downward trend), the script places a new trade in the corresponding direction (buy for an upward trend, sell for a downward trend). It will close trades only if they are in loss.
    • The script calculates the lot size (trade size) based on a percentage of your free margin, ensuring that the risk is controlled.
  5. Housekeeping The scripts has a function to close all the trades or just the trades in loss.

  6. Trailing Stop Function This part adjusts the stop-loss price of the current trades in profit in order to guarantee earnings.

Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt Closes Orders by itself It can change open orders parameters, due to possible stepping strategy
4 Views
0 Downloads
0 Favorites

Profitability Reports

NZD/USD Oct 2024 - Jan 2025
1119.00 %
Total Trades 21
Won Trades 20
Lost trades 1
Win Rate 95.24 %
Expected payoff 448.36
Gross Profit 10339.40
Gross Loss -923.80
Total Net Profit 9415.60
-100%
-50%
0%
50%
100%
GBP/USD Oct 2024 - Jan 2025
369.00 %
Total Trades 24
Won Trades 23
Lost trades 1
Win Rate 95.83 %
Expected payoff 418.09
Gross Profit 13771.00
Gross Loss -3736.80
Total Net Profit 10034.20
-100%
-50%
0%
50%
100%
AUD/USD Oct 2024 - Jan 2025
809.00 %
Total Trades 21
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff 248.71
Gross Profit 5959.70
Gross Loss -736.80
Total Net Profit 5222.90
-100%
-50%
0%
50%
100%
SimpleGrail
//+------------------------------------------------------------------+
//|                                                  SimpleGrail.mq4 |
//|                                        Copyright © 2009, LEHayes |
//|                                   BlessingsFromEarth@hotmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, LEHayes"
#property link      "BlessingsFromEarth@hotmail.com"


extern int    StopLoss       = 0;            // if using 4 digits, set to 20 on Trailing stop loss
extern int    TrailingStop   = 200;   // represents 20 lots with the extra digit
extern bool   choice         = true;
double Lots           = 0.1;           // This is legacy, no switch at this time for progressive lots
extern int    magicnumber    = 143;
bool   PolLots        = false;         // This closes half the lots at some point, without it, more earnings.
extern int    MaxOrders      =  1;     // you can place multiple orders, but suffer equity risk
extern double Prots= 15;                                  // Percentage of free assets


double Lot;                         // global lot for calculating free assets
int prevtime;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----


  Lots = GetLots();


   int i=0;  
   int total = OrdersTotal();   
   for(i = 0; i <= total; i++) 
     {
      if(TrailingStop>0)  
       {                 
       OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
       if(OrderMagicNumber() == magicnumber) 
         {
         TrailingStairs(OrderTicket(),TrailingStop);
         }
       }
      }

if(AccountFreeMargin() > (AccountBalance()/2))
{
bool BuyOp=false;
bool SellOp=false;


if (High[0]>High[1]&&High[1]>High[2]&&High[2]>High[3]&&Open[0]>Open[1]&&Open[1]>Open[2]&&Open[2]>Open[3]) BuyOp=true;
if (High[0]<High[1]&&High[1]<High[2]&&High[2]<High[3]&&Open[0]<Open[1]&&Open[1]<Open[2]&&Open[2]<Open[3]) SellOp=true;

   if(Time[0] == prevtime) 
       return(0);
   prevtime = Time[0];
   if(!IsTradeAllowed()) 
     {
       prevtime = Time[1];
       return(0);
     }


   if (total < MaxOrders || MaxOrders == 0)
     {   
       if(BuyOp)
        { 
         if (StopLoss!=0)
          {
           HouseKeeper(1);
           OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid-(StopLoss*Point),0,StringConcatenate("SimpleGrail_", Symbol(), "_Buy"),magicnumber,0,Green);
          }
         else
          {
           HouseKeeper(1);
           OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,StringConcatenate("SimpleGrail_",Symbol(), "_Buy"),magicnumber,0,Green);
          }
        }
       if(SellOp)
        { 
         if (StopLoss!=0)
          {
          HouseKeeper(2);
           OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Ask+(StopLoss*Point),0,StringConcatenate("SimpleGrail_", Symbol(), "_Sell"),magicnumber,0,Red);
          } 
         else 
          {
           HouseKeeper(2);
           OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,StringConcatenate("SimpleGrail_", Symbol(), "_Sell"),magicnumber,0,Red);
          }
        }
      }
}   
//----
   return(0);
  } 
  
//+------------------------------------------------------------------+
int HouseKeeper(int BuySell)
   {
   
      int i=0;
      int HKtotal = OrdersTotal();   
      bool IsClosed = false;
      
      choice = true;
      
      if (choice)
         {
            for(i = 0; i <= HKtotal; i++) 
               {
                  OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
                  IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                  if (IsClosed == false)
                     {
                         // try again
                         IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                     }
               }
         }
      else
         {
            for(i = 0; i <= HKtotal; i++) 
               {
                  OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
                  if(OrderMagicNumber() == magicnumber) 
                     {
                           
                        if (BuySell ==1)
                           {
                              if (OrderType() == OP_SELL)
                                 {
                                    if (OrderProfit() < 0)
                                       {
                                          IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                                          if (IsClosed == false)
                                             {
                                                // try again
                                                IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                                             }
                                       }
                                 }
                           }
                        else
                           {
                              if (OrderType() == OP_BUY)
                                 {
                                    if (OrderProfit() < 0)
                                       {
                                          IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                                          if (IsClosed == false)
                                             {
                                                // try again
                                                IsClosed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),3,Yellow);
                                             }
                                       }
                                 }                     
                           }
                  }
               }
         }      
   
      return(0);
   }


double GetLots()
   {
   
   Lot = NormalizeDouble( (AccountFreeMargin()/MaxOrders)*Prots/100/1000, 1);// Calculate the amount of lots 
   Print("Lot calculation is: ", Lot); 
   if (Lot < MarketInfo(Symbol(),MODE_MINLOT))
      {
         Lot = MarketInfo(Symbol(),MODE_MINLOT);       // For testing on const. min. lots
         Print("Lot is too small, setting to minlot of: ", Lot);
      }
   return(Lot);
   }  
  
//+------------------------------------------------------------------+
void TrailingStairs(int ticket,int trldistance)
   {
    bool result;
    int error;
    int Spred=Ask - Bid;
    int spread;
    
    if (OrderType()==OP_BUY)
      {
       if((Bid-OrderOpenPrice())>(Point*trldistance))
         {
          if(OrderStopLoss()<Bid-Point*trldistance || (OrderStopLoss()==0))
            {
             result=OrderModify(ticket,OrderOpenPrice(),Bid-Point*trldistance,OrderTakeProfit(),0,Green);
             while(result!=True)
               {
                  error=GetLastError();
                  Print("LastError closing first try =",error);
                  if(error==138)
                  {
                     Sleep(10000);
                     RefreshRates();
                     result=OrderModify(ticket,OrderOpenPrice(),Bid-Point*trldistance,OrderTakeProfit(),0,Green);
                  }
                  if(error==0)
                   {
                      result=true;
                   }
               }
           
            
             if (PolLots)
                if (NormalizeDouble(OrderLots()/2,2)>MarketInfo(Symbol(), MODE_MINLOT))
                  {
                     spread=MarketInfo(Symbol(),MODE_SPREAD); 
                     result = OrderClose(ticket,NormalizeDouble(OrderLots()/2,2),Ask,spread,Green);
                     while(result!=True)
                     {
                        error=GetLastError();
                        Print("1 LastError closing first try =",error);
                        if(error==138)
                          {
                              Sleep(10000);
                              RefreshRates();
                              spread=MarketInfo(Symbol(),MODE_SPREAD);
                              result = OrderClose(ticket,NormalizeDouble(OrderLots()/2,2),Ask,spread,Green);
                           }
                        if(error==0)
                           {
                              result=true;
                           }
                     }
                     
                  }
                else
                  {
                     spread=MarketInfo(Symbol(),MODE_SPREAD);
                     result = OrderClose(ticket,OrderLots(),Ask,spread,Green);
                     while(result!=True)
                     {
                        error=GetLastError();
                        Print("2 LastError closing first try =",error);
                        if(error==138)
                           {
                              Sleep(10000);
                              RefreshRates();
                              spread=MarketInfo(Symbol(),MODE_SPREAD);
                              result = OrderClose(ticket,OrderLots(),Ask,spread,Green);
                           }
                        if(error==0)
                           {
                              result=true;
                           }
                     }
                  }
            }
         }
       }
     else
       {
        if((OrderOpenPrice()-Ask)>(Point*trldistance))
          {
           if((OrderStopLoss()>(Ask+Point*trldistance)) || (OrderStopLoss()==0))
             {
               result=OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*trldistance,OrderTakeProfit(),0,Red);
               while(result!=True)
                  {
                     error=GetLastError();
                     Print("LastError closing first try =",error);
                     if(error==138)
                        {
                           Sleep(10000);
                           RefreshRates();
                           result=OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*trldistance,OrderTakeProfit(),0,Red);
                        }
                        if(error==0)
                           {
                              result=true;
                           }
                  }
             if (PolLots)
             if (NormalizeDouble(OrderLots()/2,2)>MarketInfo(Symbol(), MODE_MINLOT))
               {
                  spread=MarketInfo(Symbol(),MODE_SPREAD);
                  result = OrderClose(ticket,NormalizeDouble(OrderLots()/2,2),Bid,spread,Green);
                  while(result!=True)
                  {
                     error=GetLastError();
                     Print("3 LastError closing first try =",error);
                     if(error==138)
                        {
                           Sleep(10000);
                           RefreshRates();
                           spread=MarketInfo(Symbol(),MODE_SPREAD);
                           result = OrderClose(ticket,NormalizeDouble(OrderLots()/2,2),Bid,spread,Green);
                        }
                        if(error==0)
                           {
                              result=true;
                           }
                  }
                  
               }
             else
               {
                  spread=MarketInfo(Symbol(),MODE_SPREAD);
                  result = OrderClose(ticket,OrderLots(),Bid,spread,Green);
                  while(result!=true)
                  {
                     error=GetLastError();
                     Print("4 LastError closing first try =",error);
                     if(error==138)
                        {
                           Sleep(10000);
                           RefreshRates();
                           spread=MarketInfo(Symbol(),MODE_SPREAD);
                           result = OrderClose(ticket,NormalizeDouble(OrderLots()/2,2),Bid,spread,Green);
                        }
                        if(error==0)
                           {
                              result=true;
                           }
                  }

               }
             }
          }
        }
    }

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 ---