Join the Dots v1.3

Author: Copyright � 2008, LEGRUPO
Profit factor:
0.00

This script is an automated trading system designed for the MetaTrader 4 platform. It functions as an "Expert Advisor" (EA), which means it monitors live market data and executes trades based on a specific set of logical rules without requiring manual intervention.

Core Strategy Logic

The primary goal of the script is to identify specific "dots" or signals generated by technical indicators to determine when to enter and exit the market. It relies on three distinct types of analysis to confirm its moves:

  • Trend Identification: The system looks at overarching market trends using a "Mega Trend" and a "Trend Histogram." This helps the script understand if the broader market direction is currently moving up, down, or remains flat.
  • Swing Analysis: It uses a specific "Swing_ZZ" indicator to identify potential turning points or momentum shifts in the price action.
  • Triple Filter Integration: When enabled, the script requires all three of these components (Trend, Histogram, and Swing) to align before it considers a trade valid. This acts as a safety net to ensure that the bot doesn't enter a trade against the prevailing market flow.

Trade Execution Rules

The logic for opening and closing positions is governed by several key behaviors:

1. Entry Conditions

  • Buy Signals: The script looks for specific patterns where momentum indicators align with an upward trend. If these conditions are met, it opens a "Buy" position.
  • Sell Signals: Conversely, if the indicators confirm a downward trend, the script opens a "Sell" position.
  • Signal Switching: To ensure smooth transitions, the bot is programmed to automatically close any existing opposing positions (e.g., closing all Sells when a Buy signal appears) before opening a new trade.

2. Trade Management & Safety

  • Stop Loss and Take Profit: You can define specific price targets for profit and "safety nets" (Stop Loss) to limit potential losses automatically.
  • Money Management: The script includes an intelligent calculation feature. Instead of always trading the same amount, it can calculate your position size based on your account balance, leverage, and a percentage of free margin that you choose to risk.
  • Trade Delay: To avoid "fake-outs" (where a signal appears and disappears quickly), there is an option to wait for a candle to complete. This ensures the signal is "locked in" before any money is committed.

3. Dynamic Exit Logic Beyond simple profit targets, the script features a unique "Next Dot" closing logic. This allows the bot to exit a trade as soon as a counter-signal appears on the chart, allowing it to react quickly to sudden changes in market momentum.

Identification and Tracking

The script uses a unique identification system (Magic Number). It automatically assigns a specific ID based on the currency pair being traded and the timeframe you are viewing. This allows the bot to "remember" which trades it opened so that it doesn't interfere with other manual trades or other automated bots running on the same account.

Orders Execution
It automatically opens orders when conditions are reachedChecks for the total of open ordersIt Closes Orders by itself
Miscellaneous
It issuies visual alerts to the screen
17 Views
2 Downloads
0 Favorites
Join the Dots v1.3
//+------------------------------------------------------------------+
//|                                        Join the dots-v1.2.1A.mq4 |
//|                                        Copyright © 2008, LEGRUPO |
//|                                           http://www.legrupo.com |
//|                                                     Version: 1.3 |
//| History:                                                         |
//| 1.0 => Release version to the public                             |
//| 1.1 => StopLoss bug fixed                                        |
//| 1.2 => fixes on this releases:                                   |
//|        1) More StopLoss bug fixed;                               |
//|        2) Now the EA close on the next oposite dot               |
//|           Make sure that CloseOrdersOnNextDot is true            |
//|1.2.1 => Stoploss Bug fixed by Saidas                             |
//|1.2.1A=> Added Money Management and UseTripleIndicators filter    |
//|         by Azmel                                                 |
//|1.3   => Added TradeDelay switch. If enabled, it will wait for    |
//|         next candle and only trade if dot does not repaint.      |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, LEGRUPO"
#property link      "http://www.legrupo.com"
//+------------------------------------------------------------------+
//| EX4 imports                                                      |
//+------------------------------------------------------------------+
#include <stdlib.mqh>
int MagicNumber = 0;
int ticket = 0;
double Price[2];
int    giSlippage;
extern int    ExpertID             = 994488;
extern int    TakeProfit           = 300;
extern double StopLoss             = 50;
extern double LotSize              = 0.1;
extern bool   useTakeProfit        = true;
extern bool   useStopLoss          = true;
extern bool   CloseOrdersOnNextDot = true;
extern bool   UseTripleIndicators  = true;
extern bool   TradeDelay           = true;
extern bool   MoneyManagement      = false;
extern int    PercentageToTrade    = 80;
extern int    AccountType          = 1;
extern int    Leverage             = 100;
extern int    Slippage             = 5;
color ExitLongColor = CLR_NONE;
color ExitShortColor = CLR_NONE;
extern string BuyComment           = "Join the Dots BUY";
extern string SellComment          = "Join the Dots SELL";

double PricePerPip;
double DecimalCorrection;
double DecimalPlaces;
double TP;
bool   BuySignal;
bool   SellSignal;

bool   CurrentBuyDot;
bool   CurrentSellDot;

bool   PreviousBuyDot;
bool   PreviousSellDot;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
        
//--- by Saidas
   double SL = StopLoss*Point;//by Saidas
   
   //---- MoneyManagement feature by Azmel
   if (AccountType==0)
   {
      PricePerPip       = 10;
      DecimalCorrection = 0.5;
      DecimalPlaces     = 0;
   }
   
   if (AccountType==1)
   { 
      PricePerPip       = 10;
      DecimalCorrection = 0.05;
      DecimalPlaces     = 1;
   }
   
   if (AccountType==2)
   {
      PricePerPip       = 10;
      DecimalCorrection = 0.005;
      DecimalPlaces     = 2;
   }
   
   if (AccountType==3)
   {
      PricePerPip       = 1;
      DecimalCorrection = 0.005;
      DecimalPlaces     = 2;
   }
   
   if (MoneyManagement)
   {
      LotSize=NormalizeDouble(((AccountFreeMargin()*PercentageToTrade*Leverage)/
         (Ask*PricePerPip*1000000))-DecimalCorrection,DecimalPlaces);
   }
   //---- end of MoneyManagement feature.


   MagicNumber = MakeMagicNumber( ExpertID, false );
   double MegaTrend_up     = iCustom(NULL, 0, "Mega trend",144,3,0,0,0);
   double MegaTrend_down   = iCustom(NULL, 0, "Mega trend",144,3,0,1,0);
   double MegaTrend_buffer = iCustom(NULL, 0, "Mega trend",144,3,0,2,0);
   string megatrend_direction, trendhisto_direction, swingzz_direction;
   
   //Comment("MegaTrend_up: ",MegaTrend_up,"\nMegaTrend_down: ", MegaTrend_down, "\nMegaTrend_buffer: ",MegaTrend_buffer);   
   if (MegaTrend_buffer == MegaTrend_up) {
      //Comment("Megatrend up");
      megatrend_direction = "up";
   } else if (MegaTrend_buffer == MegaTrend_down) {
      //Comment("Megatrend down");
      megatrend_direction = "down";
   } else {
      //Comment("No trend from MegaTrend");
      megatrend_direction = "flat";
   }
   
   double TrendHisto_up     = iCustom(NULL, 0, "Trend Histo",1500,1,0);
   double TrendHisto_down   = iCustom(NULL, 0, "Trend Histo",1500,2,0);
   double TrendHisto_buffer = iCustom(NULL, 0, "Trend Histo",1500,0,0);
   
   //Comment("TrendHisto_up: ",TrendHisto_up,"\nTrendHisto_down: ", TrendHisto_down, "\nTrendHisto_buffer: ",TrendHisto_buffer);
   if (TrendHisto_buffer == TrendHisto_up) {
      //Comment("TrendHisto up");
      trendhisto_direction = "up";
   } else if (TrendHisto_buffer == TrendHisto_down) {
      //Comment("TrendHisto down");
      trendhisto_direction = "down";
   } else {
      //Comment("No trend from TrendHisto");
      trendhisto_direction = "flat";
   }
   
   double swingzz_up     = iCustom(NULL, 0, "Swing_ZZ",2,1,0);
   double swingzz_down   = iCustom(NULL, 0, "Swing_ZZ",2,2,0);
   double swingzz_buffer = iCustom(NULL, 0, "Swing_ZZ",2,0,0);
   //Comment("swingzz_up: ",swingzz_up,"\nswingzz_down: ", swingzz_down, "\nswingzz_buffer: ",swingzz_buffer);
   
   //---TradeDelay feature by Azmel.
   //---UseTripleIndicators feature by Azmel.
   if (TradeDelay)
   {
      if (UseTripleIndicators)
      {
         if (swingzz_down != 0 && megatrend_direction == "up" && trendhisto_direction == "up")
         {
            CurrentBuyDot=true;
         }
         else
         {
            CurrentBuyDot=false;
         }

         if (swingzz_up != 0 && megatrend_direction == "down" && trendhisto_direction == "down")
         {
            CurrentSellDot = true;
         }
         else
         {
            CurrentSellDot = false;
         }

         if (PreviousSellDot==true && CurrentSellDot==false)
         {
            SellSignal = true;
         }
         else
         {
            SellSignal = false;
         }

         if (PreviousBuyDot==true && CurrentBuyDot==false)
         {
            BuySignal = true;
         }
         else
         {
            BuySignal = false;
         }

         PreviousSellDot=CurrentSellDot;
         PreviousBuyDot =CurrentBuyDot;
      }
      else
      {
         if (swingzz_down != 0)
         {
            CurrentBuyDot=true;
         }
         else
         {
            CurrentBuyDot=false;
         }

         if (swingzz_up != 0)
         {
            CurrentSellDot = true;
         }
         else
         {
            CurrentSellDot = false;
         }

         if (PreviousSellDot==true && CurrentSellDot==false)
         {
            SellSignal = true;
         }
         else
         {
            SellSignal = false;
         }

         if (PreviousBuyDot==true && CurrentBuyDot==false)
         {
            BuySignal = true;
         }
         else
         {
            BuySignal = false;
         }

         PreviousSellDot=CurrentSellDot;
         PreviousBuyDot =CurrentBuyDot;
      }
   }
   else
   {
      if (UseTripleIndicators)
      {
         if (swingzz_down != 0 && megatrend_direction == "up" && trendhisto_direction == "up")
         {
            BuySignal = true;
         }
         else
         {
            BuySignal = false;
         }
       
         if (swingzz_up != 0 && megatrend_direction == "down" && trendhisto_direction == "down")
         {
            SellSignal = true;
         }
         else
         {
            SellSignal = false;
         }
      }
      else
      {
         if (swingzz_down != 0)
         {
            BuySignal = true;
         }
         else
         {
            BuySignal = false;
         }
      
         if (swingzz_up != 0)
         {
            SellSignal = true;
         }
         else
         {
            SellSignal = false;
         }
      }
   }
   //--- end of UseTripleIndicators feature.
   //--- end of TradeDelay feature.         
   
   if (BuySignal) {
      CloseShorts(MagicNumber);
      //Alert("BUY");
      if (CountLongs(MagicNumber)== 0 && CountShorts(MagicNumber)== 0) {
         if (useStopLoss) {
               SL = Bid-SL;//by Saidas
         } else {
               SL = 0;//by Saidas
         }
         if (useTakeProfit)
         {
            TP = Ask+TakeProfit*Point;
         }
         else
         {
            TP = 0;
         }
            ticket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,SL,TP,BuyComment,MagicNumber,0,CLR_NONE);//by Saidas
         if(ticket<0)
            {
             Alert("OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
      }
   }
   if (SellSignal) {
      CloseLongs(MagicNumber);
      //Alert("SELL");
      if (CountLongs(MagicNumber)== 0 && CountShorts(MagicNumber)== 0) {
         if (useStopLoss) {
               SL = Ask+SL;//by Saidas
         } else {
               SL = 0;//by Saidas
         }
         if (useTakeProfit)
         {
            TP = Bid-TakeProfit*Point;
         }
         else
         {
            TP = 0;
         }
            ticket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,SL,TP,SellComment,MagicNumber,0,CLR_NONE);//by Saidas
         if(ticket<0)
            {
             Alert("OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
      }
   }
   if (CloseOrdersOnNextDot) {
      if (swingzz_up != 0) {
         CloseLongs(MagicNumber);
      }
      if (swingzz_down != 0) {
         CloseShorts(MagicNumber);
      }
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Make Magic Number                                                |
//+------------------------------------------------------------------+
int MakeMagicNumber( int ExpertID, bool TimeSpecific )
{
   int SymbolCode  = 0;
   int PeriodCode  = 0;
   int MagicNumber = 0; 
   
   //---- Symbol Code
        if( Symbol() == "AUDCAD" || Symbol() == "AUDCADm" ) { SymbolCode = 1000; }
   else if( Symbol() == "AUDJPY" || Symbol() == "AUDJPYm" ) { SymbolCode = 2000; }
   else if( Symbol() == "AUDNZD" || Symbol() == "AUDNZDm" ) { SymbolCode = 3000; }
   else if( Symbol() == "AUDUSD" || Symbol() == "AUDUSDm" ) { SymbolCode = 4000; }
   else if( Symbol() == "CHFJPY" || Symbol() == "CHFJPYm" ) { SymbolCode = 5000; }
   else if( Symbol() == "EURAUD" || Symbol() == "EURAUDm" ) { SymbolCode = 6000; }
   else if( Symbol() == "EURCAD" || Symbol() == "EURCADm" ) { SymbolCode = 7000; }
   else if( Symbol() == "EURCHF" || Symbol() == "EURCHFm" ) { SymbolCode = 8000; }
   else if( Symbol() == "EURGBP" || Symbol() == "EURGBPm" ) { SymbolCode = 9000; }
   else if( Symbol() == "EURJPY" || Symbol() == "EURJPYm" ) { SymbolCode = 1000; }
   else if( Symbol() == "EURUSD" || Symbol() == "EURUSDm" ) { SymbolCode = 1100; }
   else if( Symbol() == "GBPCHF" || Symbol() == "GBPCHFm" ) { SymbolCode = 1200; }
   else if( Symbol() == "GBPJPY" || Symbol() == "GBPJPYm" ) { SymbolCode = 1300; }
   else if( Symbol() == "GBPUSD" || Symbol() == "GBPUSDm" ) { SymbolCode = 1400; }
   else if( Symbol() == "NZDJPY" || Symbol() == "NZDJPYm" ) { SymbolCode = 1500; }
   else if( Symbol() == "NZDUSD" || Symbol() == "NZDUSDm" ) { SymbolCode = 1600; }
   else if( Symbol() == "USDCAD" || Symbol() == "USDCADm" ) { SymbolCode = 1700; }
   else if( Symbol() == "USDCHF" || Symbol() == "USDCHFm" ) { SymbolCode = 1800; }
   else if( Symbol() == "USDJPY" || Symbol() == "USDJPYm" ) { SymbolCode = 1900; }
                     
   
   //---- Period Code
   if( TimeSpecific )
   {
              if( Period() == 1 )    { PeriodCode = 10; }
         else if( Period() == 5 )    { PeriodCode = 20; }
         else if( Period() == 15 )   { PeriodCode = 30; }
         else if( Period() == 30 )   { PeriodCode = 40; }
         else if( Period() == 60 )   { PeriodCode = 50; }
         else if( Period() == 240 )  { PeriodCode = 60; }
         else if( Period() == 1440 ) { PeriodCode = 70; }
         else if( Period() == 10080 ){ PeriodCode = 80; }
   }
   else
   {
      PeriodCode = 0;
   }
   //---- Calculate MagicNumber
   MagicNumber = ExpertID+SymbolCode+PeriodCode;
   return(MagicNumber);
}
//+------------------------------------------------------------------+
//| Calculate concurrent Long position                               |
//+------------------------------------------------------------------+
int CountLongs(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if( OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_BUY)
   count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Calculate concurrent short position                              |
//+------------------------------------------------------------------+
int CountShorts(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if(OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_SELL)
  count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Close Long Position                                              |
//+------------------------------------------------------------------+
void CloseLongs(int MagicNumber)
{
 int i = OrdersTotal();
 
 while( CountLongs(MagicNumber) != 0 && i >= 0 )
 {  
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
   
   if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber )
   {
     i--;
     continue;
   }
   else if(OrderType()==OP_BUY || OrderType()== OP_BUYLIMIT)
   {
     OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,ExitLongColor);
     i--;
   }
 }
}
//+------------------------------------------------------------------+
//| Close Short Position                                             |
//+------------------------------------------------------------------+
void CloseShorts(int MagicNumber)
{
 int i = OrdersTotal();
 
 while( CountShorts(MagicNumber) != 0 && i >= 0 )
 {  
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
   
   if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber)
   {
     i--;
     continue;
   }
   else if(OrderType()== OP_SELL || OrderType()==OP_SELLLIMIT )
  {
   OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,ExitShortColor);
  }
 }
}

Comments