TripleX





//+------------------------------------------------------------------+
//|                                                      TripleX.mq4 |
//|                                        Copyright © 2008, LEGRUPO |
//|                                           http://www.legrupo.com |
//|                                                     Version: 1.0 |
//| History:                                                         |
//| 1.0 => Release version to the public                             |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, LEGRUPO"
#property link      "http://www.legrupo.com"

#include <WinUser32.mqh>
#include <stderror.mqh>
#include <stdlib.mqh>


int MagicNumber = 0;
int ticket_buy1,ticket_buy2,ticket_buy3,ticket_sell1,ticket_sell2,ticket_sell3 = 0;
double Price[2];
int    giSlippage;
extern int    ExpertID             = 014488;
extern int    TakeProfit           = 300;
extern double StopLoss             = 150;
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   UseMoneyManagement   = true;
extern bool   AccountIsMicro       = true;
extern int    Risk                 = 10; // risk in percentage % (10% of risk in this case)

extern bool   useTimeFilter        = false;
extern int    startTradeTime       = 07;
extern int    endTradeTime         = 22;

extern bool   useTripleExit        = true;

extern int    Slippage             = 3;
color ExitLongColor = CLR_NONE;
color ExitShortColor = CLR_NONE;
extern string BuyComment           = "TripleX BUY";
extern string SellComment          = "TripleX SELL";

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

bool   CurrentBuyDot;
bool   CurrentSellDot;

bool   PreviousBuyDot;
bool   PreviousSellDot;

int TripleX_risk = 0;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   TripleX_risk = Risk*3;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   if (useTimeFilter) {
      if (Hour() <= startTradeTime || Hour() >= endTradeTime) {
         return(0);
      }
   }
   double SL = StopLoss*Point;//by Saidas
     
   if (useTripleExit) {
      Risk = TripleX_risk;
   }
   
   if(UseMoneyManagement==true) {
      LotSize = DefineLotSize(); //Adjust the lot size     total
   }
   
   MagicNumber = MakeMagicNumber( ExpertID, false );
   double HMA_up     = iCustom(NULL, 0, "HMA_Russian_Color_sep",89,0,0,0,0);
   double HMA_down   = iCustom(NULL, 0, "HMA_Russian_Color_sep",89,0,0,1,0);
   double HMA_buffer = iCustom(NULL, 0, "HMA_Russian_Color_sep",89,0,0,2,0);
   string HMA_direction, trendhisto_direction, swingzz_direction;
   string price_is = "";
   if (Ask > HMA_buffer) {
      price_is = "above_HMA";
   }
   if (Bid < HMA_buffer) {
      price_is = "bellow_HMA";
   }
   Comment("HMA_up: ",HMA_up,"\nHMA_down: ", HMA_down, "\nHMA_buffer: ",HMA_buffer,"\nWhere is price: ",price_is);
   if (HMA_buffer == HMA_up) {
      //Comment("HMA up");
      HMA_direction = "up";
   } else if (HMA_buffer == HMA_down) {
      //Comment("HMA down");
      HMA_direction = "down";
   } else {
      //Comment("No trend from HMA");
      HMA_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 && HMA_direction == "up" && trendhisto_direction == "up")
         {
            CurrentBuyDot=true;
         }
         else
         {
            CurrentBuyDot=false;
         }

         if (swingzz_up != 0 && HMA_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 && HMA_direction == "up" && trendhisto_direction == "up")
         {
            BuySignal = true;
         }
         else
         {
            BuySignal = false;
         }
       
         if (swingzz_up != 0 && HMA_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 && price_is == "above_HMA") {
      CloseShorts(MagicNumber,0.0);
      //Alert("BUY");
      if (CountLongs(MagicNumber)== 0 && CountShorts(MagicNumber)== 0) {
         if (useStopLoss) {
               SL = Ask-SL;//by Saidas
         } else {
               SL = 0;//by Saidas
         }
         if (useTripleExit) {
            SL = iLow(NULL,PERIOD_D1,5);
         }
         if (SL < Ask) {
            SL = Ask-StopLoss*Point;
         }
         if (useTakeProfit)
         {
            TP = Ask+TakeProfit*Point;
         }
         else
         {
            TP = 0;
         }
         
            ticket_buy1=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,SL,TP,BuyComment,MagicNumber,0,CLR_NONE);
         if(ticket_buy1<0)
            {
             Alert("ticket_buy1->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
         ticket_buy2=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,SL,TP,BuyComment,MagicNumber,0,CLR_NONE);
         if(ticket_buy2<0)
            {
             Alert("ticket_buy2->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
         ticket_buy3=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,SL,TP,BuyComment,MagicNumber,0,CLR_NONE);
         if(ticket_buy3<0)
            {
             Alert("ticket_buy3->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
      }
   }
   if (SellSignal && price_is == "bellow_HMA") {
      CloseLongs(MagicNumber,0.0);
      //Alert("SELL");
      if (CountLongs(MagicNumber)== 0 && CountShorts(MagicNumber)== 0) {
         if (useStopLoss) {
               SL = Bid+SL;//by Saidas
         } else {
               SL = 0;//by Saidas
         }
         if (useTripleExit) {
            SL = iHigh(NULL,PERIOD_D1,5);
         }
         if (SL < Bid) {
            SL = Bid+StopLoss*Point;
         }
         if (useTakeProfit)
         {
            TP = Bid-TakeProfit*Point;
         }
         else
         {
            TP = 0;
         }
         
            ticket_sell1=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,SL,TP,SellComment,MagicNumber,0,CLR_NONE);//by Saidas
         if(ticket_sell1<0)
            {
             Alert("ticket_sell1->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
            ticket_sell2=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,SL,TP,SellComment,MagicNumber,0,CLR_NONE);//by Saidas
         if(ticket_sell2<0)
            {
             Alert("ticket_sell2->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
            ticket_sell3=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,SL,TP,SellComment,MagicNumber,0,CLR_NONE);//by Saidas
         if(ticket_sell3<0)
            {
             Alert("ticket_sell1->OrderSend failed with error #",ErrorDescription(GetLastError()));
             return(0);
            }
      }
   }
   if (CloseOrdersOnNextDot) {
      if (swingzz_up != 0) {
         if (useTripleExit) {
            if (CloseByTicket(MagicNumber,ticket_buy1)) {
               ticket_buy1 = 0;
            }
         } else {
            CloseLongs(MagicNumber,0.0);
         }
      }
      if (swingzz_down != 0) {
         if (useTripleExit) {
            if (CloseByTicket(MagicNumber,ticket_sell1)) {
               ticket_sell1 = 0;
            }
         } else {
            CloseShorts(MagicNumber,0.0);
         }
      }
   }
   
   if (useTripleExit) {
      if (CountLongs(MagicNumber)!= 0 && HMA_direction == "down") {
         if (CloseByTicket(MagicNumber,ticket_buy2)) {
            ticket_buy2 = 0;
         }
      }
      
      if (CountShorts(MagicNumber)!= 0 && HMA_direction == "up") {
         if (CloseByTicket(MagicNumber,ticket_sell2)) {
            ticket_sell2 = 0;
         }
      }
   }
   
   datetime StartOfDay1 = StrToTime(TimeToStr(TimeCurrent(),TIME_DATE)+" 00:01");
   datetime StartOfDay2 = StrToTime(TimeToStr(TimeCurrent(),TIME_DATE)+" 00:30");
   
   //we want to execute previous orders only during the start of the
   //day or when we haven't already done so.
   if (((TimeCurrent()>StartOfDay1) && (TimeCurrent()<StartOfDay2))){
      double new_SL = 0.0;
      if (OrderSelect(ticket_buy3,SELECT_BY_TICKET)) {
         new_SL = iLow(NULL,PERIOD_D1,5);
         if (!OrderModify(OrderTicket(),OrderOpenPrice(),new_SL,OrderTakeProfit(),0,CLR_NONE)) {
            ticket_buy3 = 0;
         }
      }
      if (OrderSelect(ticket_sell3,SELECT_BY_TICKET,MODE_TRADES)) {
         new_SL = iHigh(NULL,PERIOD_D1,5);
         if (!OrderModify(OrderTicket(),OrderOpenPrice(),new_SL,OrderTakeProfit(),0,CLR_NONE)) {
            ticket_sell3 = 0;
         }
      }
   }
//----
   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, double split_lot)
{
 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)
   {
     if (split_lot == 0.0) {
         split_lot = OrderLots();
     }
     OrderClose(OrderTicket(),split_lot,Bid,Slippage,ExitLongColor);
     i--;
   }
 }
}
//+------------------------------------------------------------------+
//| Close Short Position                                             |
//+------------------------------------------------------------------+
void CloseShorts(int MagicNumber, double split_lot)
{
 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 )
  {
   if (split_lot == 0.0) {
       split_lot = OrderLots();
   }
   OrderClose(OrderTicket(),split_lot,Ask,Slippage,ExitShortColor);
  }
 }
}
double DefineLotSize() {
   double lotMM = MathCeil(AccountFreeMargin() *  Risk / 1000) / 100;
   if(AccountIsMicro==false) { //normal account
      if (lotMM < 0.1) lotMM = LotSize;
      if ((lotMM > 0.5) && (lotMM < 1)) lotMM=0.5;
      if (lotMM > 1.0) lotMM = MathCeil(lotMM);
      if  (lotMM > 100) lotMM = 100;
   } else { //micro account
      if (lotMM < 0.01) lotMM = LotSize;
      if (lotMM > 1.0) lotMM = MathCeil(lotMM);
      if  (lotMM > 100) lotMM = 100;
   }
   return (lotMM);
}
bool CloseByTicket(int MagicNumber, int ticket)
{
 if (OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) {
   return(OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,ExitLongColor));
 }
 return(false);
}



Sample





Analysis



Market Information Used:

Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar


Indicator Curves created:


Indicators Used:




Custom Indicators Used:
Trend Histo
Swing_ZZ
HMA_Russian_Color_sep

Order Management characteristics:
It automatically opens orders when conditions are reached

It can change open orders parameters, due to possible stepping strategy
Checks for the total of open orders
It Closes Orders by itself

Other Features:

It issuies visual alerts to the screen

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:0.19 Total Net Profit:-1061.05

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:0.44 Total Net Profit:-1285.52

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:1.02 Total Net Profit:5.61

Request Backtest for TripleX


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: