Goblin_BiPolar_FixedLots_alassio





// Goblin BiPolar Edition v.1.0
// by bluto @ www.forex-tsd.com
// 12/20/2006
//
// Here's a roughly cobbled version of Goblin that supports two EA routines in one - a buy side and a sell side running concurrently.
// Although effective, the code isn't the most modular at this point.  If the concept proves to be viable, I'll continue further
// development to optimize shared subroutines between the two sub-EA routines.  For now...play, test & be bodaceous!
//
// Modifications by alassio:
// - Determine lot size of individual orders
// - Scale lot sizes by account equity for compounding (replaces previous mm)
// - Collect winner/loser statistics
// - Allow usage of progressions after losers (experimental)
//

extern string    FixedLotsFeature = "** Determine lot size of individual orders **";
extern double    FixedLotsOrder1 = 2;
extern double    FixedLotsOrder2 = 2;
extern double    FixedLotsOrder3 = 1;
extern double    FixedLotsOrder4 = 3;
extern double    FixedLotsOrder5 = 4;
extern double    FixedLotsOrder6 = 5;
extern double    FixedLotsOrder7 = 0;
extern double    FixedLotsOrder8 = 0;
extern double    FixedLotsOrder9 = 0;
extern double    FixedLotsOrderLast = 0;

extern string    DynamicLotsFeature = "** Scale lots by account size for compounding **";
extern bool      UseDynamicLots = true;
extern double    LotBaseEquity = 50000;
extern double    LotBaseSize = 1;

extern string    StatisticsFeature = "** Collect winner/loser statistics **";
extern double    LoserLimit = -1000;
extern double    KellyFactor = 0.25;

extern string    ProgressionFeature = "** Use lot size progression after losers **";
extern bool      UseProgression = false;
extern bool      UseGlobalProg = true; // Same progression for bus/sell orders
extern int       ProgressionModel = 2; // 1 = Dahl progression, 2 = reverse Dahl progression
extern int       MaxProgStep = 12;
extern bool      UseCycleProgSteps = false;

extern string    EntryFeature = "** Select entry signal parameters **";
extern bool      UseRSX = false;
extern bool      UseConservativeRSX_Signals=false;        // If true, we use tighter RSX 70/30 rules
extern int       RSX_Period=17;
extern int       RSX_Timeframe=60;
extern bool      UseJMATrend = true;                                                 
extern int       JMAPeriod = 28;
extern int       JMALag = 2;
extern double    JMAPointDiff = 2;
extern bool      UseSMATrendFilter=false;
extern int       TrendFilterSMATimeFrame=60;
extern int       TrendFilterFastSMAPeriod=65;
extern int       TrendFilterMediumSMAPeriod=20;
extern int       TrendFilterSlowSMAPeriod=7;

extern string    LongTradeParms = "** Goblin Buy Side Parameters **";
extern double    LongTakeProfit = 10;           // Profit Goal for the latest order opened
extern double    LongInitialStop = 10;          // StopLoss
extern double    LongTrailingStop = 0;          // Pips to trail the StopLoss
extern int       LongMaxTrades=6;               // Maximum number of orders to open
extern int       LongPips=5;                    // Distance in Pips from one order to another
extern int       LongSecureProfit=0;            // If profit made is bigger than SecureProfit we close the orders
extern bool      LongAccountProtection=false;   // If one the account protection will be enabled, 0 is disabled
extern int       LongOrderstoProtect=0;         // This number subtracted from LongMaxTrades is the number of open orders to enable the account protection.
                                                // Example: (LongMaxTrades=10) minus (OrderstoProtect=3)=7 orders need to be open before account protection is enabled.
                                                
extern string    ShortTradeParms = "** Goblin Sell Side Parameters **";
extern double    ShortTakeProfit = 10;          // Profit Goal for the latest order opened
extern double    ShortInitialStop = 10;         // StopLoss
extern double    ShortTrailingStop = 0;         // Pips to trail the StopLoss
extern int       ShortMaxTrades=6;              // Maximum number of orders to open
extern int       ShortPips=5;                   // Distance in Pips from one order to another
extern int       ShortSecureProfit=0;           // If profit made is bigger than SecureProfit we close the orders
extern bool      ShortAccountProtection=false;  // If one the account protection will be enabled, 0 is disabled
extern int       ShortOrderstoProtect=0;        // This number subtracted from LongMaxTrades is the number of open orders to enable the account protection.
                                                // Example: (LongMaxTrades=10) minus (OrderstoProtect=3)=7 orders need to be open before account protection is enabled. 
                                                 
                                                 
// Global internal parameters used by LongGoblin() buy order module:   
                        
int              LongMagicNumber = 0;            // Magic number for the long orders placed                              
int              L_OpenOrders=0;
int              L_Count=0;
int              L_Slippage=5;
double           L_sl=0;
double           L_tp=0;
double           BuyPrice=0;
double           L_OrderLotSize=0;
int              L_Mode=0;
int              L_OrderType=0;
bool             L_ContinueOpening=true;
double           L_LastPrice=0;
int              L_PreviousOpenOrders=0;
double           L_Profit=0;
int              L_LastTicket=0;
int              L_LastType=0;
double           L_LastClosePrice=0;
double           L_LastLots=0;
double           L_PipValue=0;

double           L_OldProfit = 0;
int              L_ProgStep = 0;
double           L_ProgFactor = 1;
int              L_Winners = 0;
int              L_Losers = 0;
double           L_Balance = 0;
double           L_AccumulatedProfit = 0;

// Global internal parameters used by ShortGoblin() sell order module:
   
int              ShortMagicNumber = 0;           // Magic number for the short orders placed                            
int              S_OpenOrders=0;
int              S_Count=0;
int              S_Slippage=5;
double           S_sl=0;
double           S_tp=0;
double           SellPrice=0;
double           S_OrderLotSize=0;
int              S_Mode=0;
int              S_OrderType=0;
bool             S_ContinueOpening=true;
double           S_LastPrice=0;
int              S_PreviousOpenOrders=0;
double           S_Profit=0;
int              S_LastTicket=0;
int              S_LastType=0;
double           S_LastClosePrice=0;
double           S_LastLots=0;
double           S_PipValue=0;

double           S_OldProfit = 0;
int              S_ProgStep = 0;
double           S_ProgFactor = 1;
int              S_Winners = 0;
int              S_Losers = 0;
double           S_Balance = 0;
double           S_AccumulatedProfit = 0;

// Global internal shared parameters

double           G_MinLotSize=0;
double           G_MaxLotSize=0;
double           G_LotStep=0;
double           G_Decimals=0;
int              G_AcctLeverage=0;
int              G_CurrencyLotSize=0;
double           G_OrderLotSize=0;
int              G_Count=0;
int              G_Slippage=5;

int              G_ProgStep = 0;
double           progSteps[15];
int              maxWinPeriod = -1;
int              minWinPeriod = -1;
int              numWinPeriods = 0;
double           avgWinPeriod = 0;
int              numConsecutiveLosers = 0;
int              maxConsecutiveLosers = 0;
int              winPeriod = 0;
bool             lastWinner = true;
int              ordWinners[20];
double           ordProfits[20];
double           totalLoss = 0;
bool             initialized = false;

double           winPercent = 100;
double           wlr = 0;
double           avgProfit = 0;
double           avgLoss = 0;
double           expectedProfit = 0;
double           expectedProfitPercent = 100;
double           contracts = 0;
double           kelly = 0;

int init()
{
  initProgression(ProgressionModel);
  
// For those of us tired of messing around assigning annoying but essential magic numbers.
   
   if (Symbol()=="AUDCADm" || Symbol()=="AUDCAD") {LongMagicNumber=100001;ShortMagicNumber=200001;}
   if (Symbol()=="AUDJPYm" || Symbol()=="AUDJPY") {LongMagicNumber=100002;ShortMagicNumber=200002;}
   if (Symbol()=="AUDNZDm" || Symbol()=="AUDNZD") {LongMagicNumber=100003;ShortMagicNumber=200003;}
   if (Symbol()=="AUDUSDm" || Symbol()=="AUDUSD") {LongMagicNumber=100004;ShortMagicNumber=200004;}
   if (Symbol()=="CHFJPYm" || Symbol()=="CHFJPY") {LongMagicNumber=100005;ShortMagicNumber=200005;}
   if (Symbol()=="EURAUDm" || Symbol()=="EURAUD") {LongMagicNumber=100006;ShortMagicNumber=200006;}
   if (Symbol()=="EURCADm" || Symbol()=="EURCAD") {LongMagicNumber=100007;ShortMagicNumber=200007;}
   if (Symbol()=="EURCHFm" || Symbol()=="EURCHF") {LongMagicNumber=100008;ShortMagicNumber=200008;}
   if (Symbol()=="EURGBPm" || Symbol()=="EURGBP") {LongMagicNumber=100009;ShortMagicNumber=200009;}
   if (Symbol()=="EURJPYm" || Symbol()=="EURJPY") {LongMagicNumber=100010;ShortMagicNumber=200010;}
   if (Symbol()=="EURUSDm" || Symbol()=="EURUSD") {LongMagicNumber=100011;ShortMagicNumber=200011;}
   if (Symbol()=="GBPCHFm" || Symbol()=="GBPCHF") {LongMagicNumber=100012;ShortMagicNumber=200012;}   
   if (Symbol()=="GBPJPYm" || Symbol()=="GBPJPY") {LongMagicNumber=100013;ShortMagicNumber=200013;}
   if (Symbol()=="GBPUSDm" || Symbol()=="GBPUSD") {LongMagicNumber=100014;ShortMagicNumber=200014;}
   if (Symbol()=="NZDJPYm" || Symbol()=="NZDJPY") {LongMagicNumber=100015;ShortMagicNumber=200015;}
   if (Symbol()=="NZDUSDm" || Symbol()=="NZDUSD") {LongMagicNumber=100016;ShortMagicNumber=200016;}
   if (Symbol()=="USDCHFm" || Symbol()=="USDCHF") {LongMagicNumber=100017;ShortMagicNumber=200017;}
   if (Symbol()=="USDJPYm" || Symbol()=="USDJPY") {LongMagicNumber=100018;ShortMagicNumber=200018;}
   if (Symbol()=="USDCADm" || Symbol()=="USDCAD") {LongMagicNumber=100019;ShortMagicNumber=200019;}
   if (LongMagicNumber==0) {LongMagicNumber = 100999;}   
   if (ShortMagicNumber==0) {ShortMagicNumber = 200999;}   
   return(0);
   
  }


int start()
{

  if (!initialized)
  {
   for(int i = 0; i < 20; i++)
   {
     ordWinners[i] = 0;
     ordProfits[i] = 0;
   }
   initialized = true;
  }
  
//====================================================== Begin Top Level Command Module ============================================================  
 
// Global equity/risk based lot sizer

G_AcctLeverage = AccountLeverage();
G_MinLotSize = MarketInfo(Symbol(),MODE_MINLOT);
G_MaxLotSize = MarketInfo(Symbol(),MODE_MAXLOT);
G_LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
G_CurrencyLotSize = MarketInfo(Symbol(),MODE_LOTSIZE);

if(G_LotStep == 0.01) {G_Decimals = 2;}
if(G_LotStep == 0.1) {G_Decimals = 1;}

if (UseDynamicLots)
{
   if (G_OrderLotSize <= 0)
   {
      G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
   }
} else {
  G_OrderLotSize = LotBaseSize;
}

if (G_OrderLotSize < G_MinLotSize) {G_OrderLotSize = G_MinLotSize;}
if (G_OrderLotSize > G_MaxLotSize) {G_OrderLotSize = G_MaxLotSize;}
 
    
   LongGoblin();
   ShortGoblin();
   
   if (!IsTesting())
   {
      string msg =
         "Avg prof "+DoubleToStr(avgProfit,2)+", avg loss "+DoubleToStr(avgLoss,2)+", w/l "+DoubleToStr(wlr,2)+
          "%, prob "+DoubleToStr(winPercent,2)+"%"+
          "; Exp "+DoubleToStr(expectedProfit,2)+" ("+DoubleToStr(expectedProfitPercent,2)+"%)"+
          "; Kelly "+DoubleToStr(kelly,2)+", # "+DoubleToStr(contracts,2)+"";
   
      Comment("\nBUY CYCLE : Orders Open = ",L_OpenOrders," Profit = ",DoubleToStr(L_Profit,2)," +/-",
              "\nSELL CYCLE: Orders Open = ",S_OpenOrders," Profit = ",DoubleToStr(S_Profit,2)," +/-",
              "\n\n"+msg);
   }

   return(0);
  }  
   
//====================================================== End Of Top Level Command Module ============================================================<<

void initProgression(int model)
{
   if (model == 1)
   {
      // Increasing lot size with every winner, decrease again when losers become more likely
      progSteps[0] = 1;
      progSteps[1] = 1;
      progSteps[2] = 1.5;
      progSteps[3] = 1.5;
      progSteps[4] = 2;
      progSteps[5] = 2;
      progSteps[6] = 3;
      progSteps[7] = 3;
      progSteps[8] = 2;
      progSteps[9] = 2;
      progSteps[10] = 1.5;
      progSteps[11] = 1.5;
      progSteps[12] = 1;
      progSteps[13] = 1;
   } else {
      // Start with high factor to recover previous loss and the decrease lot size again
      progSteps[0] = 5;
      progSteps[1] = 3;
      progSteps[2] = 3;
      progSteps[3] = 2;
      progSteps[4] = 2;
      progSteps[5] = 1.5;
      progSteps[6] = 1.5;
      progSteps[7] = 1;
      progSteps[8] = 1;
      progSteps[9] = 1;
      progSteps[10] =1;
      progSteps[11] = 1;
      progSteps[12] = 1;
      progSteps[13] = 1;
   }
}

void setWinner(int orders,bool long,bool winner,double amount)
{
   if (UseDynamicLots)
   {
      amount = amount/G_OrderLotSize;
   }
   if(UseProgression)
   {
      if (long)
      {
         amount = amount/L_ProgFactor;
      } else {
         amount = amount/S_ProgFactor;
      }
   }
   if (winner && orders >= 0 && orders < 20)
   {
      ordWinners[orders]++;
      ordProfits[orders] = ordProfits[orders]+amount;
   } else
   if (!winner)
   {
      totalLoss = totalLoss+amount;
   }
   if (long)
   {
      if (winner)
      {
         L_Winners++;
      } else {
         L_Losers++;
      }
   } else 
   {
      if (winner)
      {
         S_Winners++;
      } else {
         S_Losers++;
      }
   }
   if (winner)
   {
      if (lastWinner)
      {
         winPeriod++;
      } else {
         winPeriod = 1;
         if (numConsecutiveLosers > maxConsecutiveLosers)
         {
            maxConsecutiveLosers = numConsecutiveLosers;
         }
         numConsecutiveLosers = 0;
      }
   } else {
      numConsecutiveLosers++;
      if (lastWinner)
      {
         // Run ended now
         if (winPeriod > maxWinPeriod)
         {
            maxWinPeriod = winPeriod;
         }
         if (winPeriod < minWinPeriod || minWinPeriod < 0)
         {
            minWinPeriod = winPeriod;
         }
         if (numWinPeriods > 0)
         {
            avgWinPeriod = (avgWinPeriod*numWinPeriods+winPeriod)/(numWinPeriods+1);
            numWinPeriods++;
         } else {
            avgWinPeriod = winPeriod;
            numWinPeriods = 1;
         }
      } else {
         winPeriod = 0;
      }
   }
   lastWinner = winner;
}

void LogStatistic()
{
   int winners = L_Winners+S_Winners;
   int losers = L_Losers+S_Losers;
   double losePercent = 0;
   if (losers > 0)
   {
      avgLoss = totalLoss/losers;
   }
   double avgProfit1 = ordProfits[1];
   if (ordWinners[1] > 0)
   {
      avgProfit1 = avgProfit1/ordWinners[1];
   }
   double avgProfit2 = ordProfits[2];
   if (ordWinners[2] > 0)
   {
      avgProfit2 = avgProfit2/ordWinners[2];
   }
   double avgProfit3 = ordProfits[3];
   if (ordWinners[3] > 0)
   {
      avgProfit3 = avgProfit3/ordWinners[3];
   }
   double avgProfit4 = ordProfits[4];
   if (ordWinners[4] > 0)
   {
      avgProfit4 = avgProfit4/ordWinners[4];
   }
   double avgProfit5 = ordProfits[5];
   if (ordWinners[5] > 0)
   {
      avgProfit5 = avgProfit5/ordWinners[5];
   }
   double avgProfit6 = ordProfits[6];
   if (ordWinners[6] > 0)
   {
      avgProfit6 = avgProfit6/ordWinners[6];
   }
   double avgProfit7 = ordProfits[7];
   if (ordWinners[7] > 0)
   {
      avgProfit7 = avgProfit7/ordWinners[7];
   }
   double avgProfit8 = ordProfits[8];
   if (ordWinners[8] > 0)
   {
      avgProfit8 = avgProfit8/ordWinners[8];
   }
   double avgProfit9 = ordProfits[9];
   if (ordWinners[9] > 0)
   {
      avgProfit9 = avgProfit9/ordWinners[9];
   }
   double avgProfit10 = ordProfits[10];
   if (ordWinners[10] > 0)
   {
      avgProfit10 = avgProfit10/ordWinners[10];
   }
   if (winners+losers > 0)
   {
      winPercent = 100.0*winners/(winners+losers);
      losePercent = 100.0*losers/(winners+losers);
      for(int i = 1; i <= 10; i++)
      {
         avgProfit += ordProfits[i];
      }
      expectedProfit = (totalLoss+avgProfit)/(winners+losers);
      if (winners > 0)
      {
         avgProfit = avgProfit/winners;
      }
      if (avgLoss < 0)
      {
         wlr = 100.0*avgProfit/(-avgLoss);
         expectedProfitPercent = 100*expectedProfit/(-avgLoss);
         if (wlr > 0)
         {
            kelly = KellyFactor*(winPercent/100.0-(100.0-winPercent)/wlr);
         }
         contracts = LotBaseEquity*kelly/(-avgLoss);
      }
   }
   Print("Buy winners "+L_Winners+",losers "+L_Losers+"; Sell winners "+S_Winners+", losers "+S_Losers+
         "; Total winners "+winners+" ("+DoubleToStr(winPercent,0)+"%), losers "+losers+" ("+DoubleToStr(losePercent,0)+"%)"+
         "; Longest run "+maxWinPeriod+", shortest run "+minWinPeriod+", avg run "+DoubleToStr(avgWinPeriod,1)+
         ", max cons. losers "+maxConsecutiveLosers);
   Print("Losers: "+losers+" ("+DoubleToStr(avgLoss,2)+"),"+
         "Winners 1: "+ordWinners[1]+" ("+DoubleToStr(avgProfit1,2)+"), "+
         "2: "+ordWinners[2]+" ("+DoubleToStr(avgProfit2,2)+"), "+
         "3: "+ordWinners[3]+" ("+DoubleToStr(avgProfit3,2)+"), "+
         "4: "+ordWinners[4]+" ("+DoubleToStr(avgProfit4,2)+"), "+
         "5: "+ordWinners[5]+" ("+DoubleToStr(avgProfit5,2)+"), "+
         "6: "+ordWinners[6]+" ("+DoubleToStr(avgProfit6,2)+"), "+
         "7: "+ordWinners[7]+" ("+DoubleToStr(avgProfit7,2)+"), "+
         "8: "+ordWinners[8]+" ("+DoubleToStr(avgProfit8,2)+"), "+
         "9: "+ordWinners[9]+" ("+DoubleToStr(avgProfit9,2)+"), "+
         "10: "+ordWinners[10]+" ("+DoubleToStr(avgProfit10,2)+")");
   Print("Avg profit "+DoubleToStr(avgProfit,2)+", avg loss "+DoubleToStr(avgLoss,2)+", w/l "+DoubleToStr(wlr,2)+
         "%, win prob "+DoubleToStr(winPercent,2)+"%"+
         "; Exp "+DoubleToStr(expectedProfit,2)+" ("+DoubleToStr(expectedProfitPercent,2)+"%)"+
         "; Kelly "+DoubleToStr(kelly,2)+", # "+DoubleToStr(contracts,2)+"");
}


//====================================================== Begin Buy Order Processing SubRoutine ======================================================<<

void LongGoblin()
  {
   L_Profit=0;
   L_OpenOrders=0;
   if (L_Balance <= 0)
   {
      L_Balance = AccountBalance();
   }
   if (S_PreviousOpenOrders < 1)
   {
     L_AccumulatedProfit = 0;
   }
   for(L_Count=0;L_Count<OrdersTotal();L_Count++)   
   {
    OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
    if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber) {L_OpenOrders++;L_Profit=L_Profit+OrderProfit();}
   }     
   
   L_PipValue = MarketInfo(Symbol(),MODE_TICKVALUE);
   if (L_PipValue==0) { L_PipValue=5; }
   
   if (L_PreviousOpenOrders>L_OpenOrders) 
   {	  
	 for(L_Count=OrdersTotal();L_Count>=0;L_Count--)
	  {     
      OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
	   if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType() == OP_BUY) 
	    {
        int m_Ticket = OrderTicket();
	     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),L_Slippage,Blue);
		  Print("Closing Buy Order ",m_Ticket);
		  return(0);
		 }
	  }
	  L_OldProfit = AccountBalance()-L_Balance-S_AccumulatedProfit;
	  if (S_AccumulatedProfit > 0)
	  {
	     Print("Subtracting accumulated sell profit "+S_AccumulatedProfit);
	  }
	  if (S_PreviousOpenOrders > 0)
	  {
	     L_AccumulatedProfit += L_OldProfit;
	  } else {
	     L_AccumulatedProfit = 0;
	  }
	  if (MaxProgStep > 12)
	  {
	    MaxProgStep = 12;
	  }
	  if (UseGlobalProg)
	  {
	    L_ProgStep = G_ProgStep;
	  }
	  if (L_OldProfit < LoserLimit*G_OrderLotSize)
	  {
	    // Loser
	    setWinner(L_PreviousOpenOrders,true,false,L_OldProfit);
	    L_ProgStep = 0;
	  } else {
	    // Winner
	    setWinner(L_PreviousOpenOrders,true,true,L_OldProfit);
	    L_ProgStep = L_ProgStep+1;
	    if (L_ProgStep > MaxProgStep)
	    {
	      L_ProgStep = MaxProgStep;
	      if (UseCycleProgSteps)
	      {
	        L_ProgStep = 0;
	      }
	    }
	  }
	  if (UseGlobalProg)
	  {
	    G_ProgStep = L_ProgStep;
	    S_ProgFactor = progSteps[G_ProgStep];
	  }
	  L_ProgFactor = progSteps[L_ProgStep];
	  if (L_ProgFactor <= 0)
	  {
	    L_ProgFactor = 1;
	  }
	  if (UseProgression)
	  {
	    if (L_OldProfit < LoserLimit*G_OrderLotSize)
	    {
	      Print("Last buy trade was a loser, factor is now "+L_ProgFactor+" (step "+L_ProgStep+")");
	    } else {
	      Print("Last buy trade was a winner, factor is now "+L_ProgFactor+" (step "+L_ProgStep+")");
	    }
	  }
	  LogStatistic();
   }

   L_PreviousOpenOrders=L_OpenOrders;
   if (L_OpenOrders>=LongMaxTrades) 
    {
	  L_ContinueOpening=False;
    } else {
	  L_ContinueOpening=True;
    }

   if (L_LastPrice==0) 
    {
	  for(L_Count=0;L_Count<OrdersTotal();L_Count++)
	   {	
       OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
	    if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType() == OP_BUY) 
		  {
			L_LastPrice=OrderOpenPrice();
		   L_OrderType=2;
		  }
	   }
    }

   if (UseDynamicLots && !L_ContinueOpening)
   {
      G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
   }
   
   if (L_OpenOrders<1) {L_OrderType=OpenOrdersBasedOnTrendRSX();}
 
// Here comes the fun part we all waited for where we update those trailing stops....yippeekyeah!!

   for(L_Count=OrdersTotal();L_Count>=0;L_Count--)
    {
     OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
     if (OrderSymbol() == Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType()== OP_BUY)  
      {	
       if (LongTrailingStop > 0 && (Bid-OrderOpenPrice()>=(LongTrailingStop+LongPips)*Point) &&  (OrderStopLoss()<(Bid-Point*LongTrailingStop)) )
        {				   
	      OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*LongTrailingStop,OrderClosePrice()+LongTakeProfit*Point+LongTrailingStop*Point,800,Yellow);
         return(0);
        } 
	   }
  	 }
   
   L_Profit=0;
   L_LastTicket=0;
   L_LastType=0;
	L_LastClosePrice=0;
	L_LastLots=0;	
	for(L_Count=0;L_Count<OrdersTotal();L_Count++)
	{
    OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
    if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType()==OP_BUY) 
	  {			
  	   L_LastTicket=OrderTicket();
		L_LastType=OP_BUY; 
		L_LastClosePrice=OrderClosePrice();
		L_LastLots=OrderLots();
		L_Profit=L_Profit+OrderProfit();	
	  }
   }
   L_OldProfit = L_Profit;
	
   if (L_OpenOrders>=(LongMaxTrades-LongOrderstoProtect) && LongAccountProtection==true) 
    {	    
     if (L_Profit>=LongSecureProfit) 
      {
       OrderClose(L_LastTicket,L_LastLots,L_LastClosePrice,L_Slippage,Yellow);		 
       L_ContinueOpening=False;
       return(0);
      }
    }
      
   if (L_OpenOrders > 0 && L_OpenOrders < LongMaxTrades && ((L_LastPrice-Ask)>=LongPips*Point))
   {
      if (L_OrderType==2 && L_ContinueOpening)
      {
         //Print("Ready to open buy order at "+Ask);
      } else {
         Print("BLOCKED buy order at "+Ask);
      }
   }
      
   if (L_OrderType==2 && L_ContinueOpening && ((L_LastPrice-Ask)>=LongPips*Point || L_OpenOrders<1) ) 
    {  		
     BuyPrice=Ask;
     L_LastPrice=0;
     if (LongTakeProfit==0) { L_tp=0; }
      else { L_tp=BuyPrice+LongTakeProfit*Point; }	
     if (LongInitialStop==0)  { L_sl=0; }
      else { L_sl=NormalizeDouble(BuyPrice-LongInitialStop*Point - (LongMaxTrades-L_OpenOrders)*LongPips*Point, Digits); }
       L_OrderLotSize=G_OrderLotSize;			
            if (L_OpenOrders <= 0)
            {
               L_OrderLotSize = FixedLotsOrder1;
            } else
            if (L_OpenOrders == 1)
            {
               L_OrderLotSize = FixedLotsOrder2;
            } else
            if (L_OpenOrders == 2)
            {
               L_OrderLotSize = FixedLotsOrder3;
            } else
            if (L_OpenOrders == 3)
            {
               L_OrderLotSize = FixedLotsOrder4;
            } else
            if (L_OpenOrders == 4)
            {
               L_OrderLotSize = FixedLotsOrder5;
            } else
            if (L_OpenOrders == 5)
            {
               L_OrderLotSize = FixedLotsOrder6;
            } else
            if (L_OpenOrders == 6)
            {
               L_OrderLotSize = FixedLotsOrder7;
            } else
            if (L_OpenOrders == 7)
            {
               L_OrderLotSize = FixedLotsOrder8;
            } else
            if (L_OpenOrders == 8)
            {
               L_OrderLotSize = FixedLotsOrder9;
            } else
            if (L_OpenOrders > 8)
            {
               L_OrderLotSize = FixedLotsOrderLast;
            }
            if (UseDynamicLots)
            {
              L_OrderLotSize = G_OrderLotSize*L_OrderLotSize;
            }
            if (UseProgression)
            {
              L_OrderLotSize = L_ProgFactor*L_OrderLotSize;
            }
      L_OrderLotSize = NormalizeDouble(L_OrderLotSize,G_Decimals);
      if (L_OrderLotSize < G_MinLotSize)
      {
         Print("ERROR: Lot size "+L_OrderLotSize+" too small, min "+G_MinLotSize+" required");
         L_OrderLotSize = G_MinLotSize;
      }
      if (L_OrderLotSize > G_MaxLotSize)
      {
         Print("ERROR: Lot size "+L_OrderLotSize+" too big, max "+G_MaxLotSize+" allowed");
         L_OrderLotSize = G_MaxLotSize;
      }
	   if (L_OpenOrders<1)
	   {
	     L_Balance = AccountBalance();
	   }
	   int nextOrder = L_OpenOrders+1;
	   Print("Open buy @"+nextOrder+" at "+DoubleToStr(L_OrderLotSize,G_Decimals)+" at "+DoubleToStr(BuyPrice,4)+" sl "+DoubleToStr(L_sl,4)+" tp "+DoubleToStr(L_tp,4));
	   int ticket = OrderSend(Symbol(),OP_BUY,L_OrderLotSize,BuyPrice,L_Slippage,L_sl,L_tp,"Goblin BiPolar Buy",LongMagicNumber,0,Blue);
	   if (ticket < 0)
	   {
	     Print("ERROR opening buy order at "+BuyPrice);
	   }
	   return(0);   
    }   
   return(0);
  }


//====================================================== Begin Sell Order Processing SubRoutine =====================================================<<

void ShortGoblin()
  {   
   S_Profit=0;  
   S_OpenOrders=0;
   if (S_Balance <= 0)
   {
      S_Balance = AccountBalance();
   }
   if (L_PreviousOpenOrders < 1)
   {
     S_AccumulatedProfit = 0;
   }
   for(S_Count=0;S_Count<OrdersTotal();S_Count++)   
    {
     OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
	  if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber) {S_OpenOrders++;S_Profit=S_Profit+OrderProfit();}
    }     
      
   S_PipValue = MarketInfo(Symbol(),MODE_TICKVALUE);
   if (S_PipValue==0) { S_PipValue=5; }
   
   if (S_PreviousOpenOrders>S_OpenOrders) 
   {	  
	 for(S_Count=OrdersTotal();S_Count>=0;S_Count--)
	  {	     
      OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
	   if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType() == OP_SELL) 
	    {
        int m_Ticket = OrderTicket();
	     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),S_Slippage,Red); 
	     Print("Closing Sell Order ",m_Ticket);
	     return(0);
		 }
	  }
	  S_OldProfit = AccountBalance()-S_Balance-L_AccumulatedProfit;
	  if (L_AccumulatedProfit > 0)
	  {
	     Print("Subtracting accumulated buy profit "+L_AccumulatedProfit);
	  }
	  if (L_PreviousOpenOrders > 0)
	  {
	     S_AccumulatedProfit += S_OldProfit;
	  } else {
	     S_AccumulatedProfit = 0;
	  }
	  if (MaxProgStep > 12)
	  {
	    MaxProgStep = 12;
	  }
	  if (UseGlobalProg)
	  {
	    S_ProgStep = G_ProgStep;
	  }
	  if (S_OldProfit < LoserLimit*G_OrderLotSize)
	  {
	    // Loser
	    setWinner(S_PreviousOpenOrders,false,false,S_OldProfit);
	    S_ProgStep = 0;
	  } else {
	    // Winner
	    setWinner(S_PreviousOpenOrders,false,true,S_OldProfit);
	    S_ProgStep = S_ProgStep+1;
	    if (S_ProgStep > MaxProgStep)
	    {
	      S_ProgStep = MaxProgStep;
	      if (UseCycleProgSteps)
	      {
	        S_ProgStep = 0;
	      }
	    }
	  }
	  if (UseGlobalProg)
	  {
	    G_ProgStep = S_ProgStep;
	    L_ProgFactor = progSteps[G_ProgStep];
	  }
	  S_ProgFactor = progSteps[S_ProgStep];
	  if (S_ProgFactor <= 0)
	  {
	    S_ProgFactor = 1;
	  }
	  if (UseProgression)
	  {
	    if (S_OldProfit < LoserLimit*G_OrderLotSize)
	    {
	      Print("Last sell trade was a loser, factor is now "+S_ProgFactor+" (step "+S_ProgStep+")");
	    } else {
	      Print("Last sell trade was a winner, factor is now "+S_ProgFactor+" (step "+S_ProgStep+")");
	    }
	  }
	  LogStatistic();
   }

   S_PreviousOpenOrders=S_OpenOrders;
   if (S_OpenOrders>=ShortMaxTrades) 
    {
	  S_ContinueOpening=False;
    } else {
	  S_ContinueOpening=True;
    }

   if (S_LastPrice==0) 
    {
	  for(S_Count=0;S_Count<OrdersTotal();S_Count++)
      {	
       OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);	
	    if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType() == OP_SELL) 
		  {
	      S_LastPrice=OrderOpenPrice();
		   S_OrderType=1;
		  }
	   }
    }

   if (UseDynamicLots && !S_ContinueOpening)
   {
      G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
   }
      
   if (S_OpenOrders<1){S_OrderType=OpenOrdersBasedOnTrendRSX();}
      

// Here comes the fun part we all waited for where we update those trailing stops....woohoo!!

   for(S_Count=OrdersTotal();S_Count>=0;S_Count--)
   {
    OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
    if (OrderSymbol() == Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType()==OP_SELL) 
	  {	
      if (ShortTrailingStop > 0 && (OrderOpenPrice()-Ask>=(ShortTrailingStop+ShortPips)*Point) && (OrderStopLoss()>(Ask+Point*ShortTrailingStop)) ) 
	    {					
	     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*ShortTrailingStop,OrderClosePrice()-ShortTakeProfit*Point-ShortTrailingStop*Point,800,Purple);
	     return(0);	  					
		 }
     }
   }
   
   S_Profit=0;
   S_LastTicket=0;
   S_LastType=0;
	S_LastClosePrice=0;
	S_LastLots=0;	
   for(S_Count=0;S_Count<OrdersTotal();S_Count++)
    {
	  OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
	  if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType()==OP_SELL) 
  	   {			
       S_LastTicket=OrderTicket();
	    S_LastType=OP_SELL;
 	    S_LastClosePrice=OrderClosePrice();
	    S_LastLots=OrderLots();
       S_Profit=S_Profit+OrderProfit();			 	   
      }
    }
   S_OldProfit = S_Profit;
    
   if (S_OpenOrders>=(ShortMaxTrades-ShortOrderstoProtect) && ShortAccountProtection==true) 
    {	    
     if (S_Profit>=ShortSecureProfit) 
      {
       OrderClose(S_LastTicket,S_LastLots,S_LastClosePrice,S_Slippage,Yellow);		 
       S_ContinueOpening=False;
       return(0);
      }
    }
       
   if (S_OpenOrders > 0 && S_OpenOrders < ShortMaxTrades && ((Bid-S_LastPrice)>=ShortPips*Point))
   {
      if (S_OrderType==1 && S_ContinueOpening)
      {
         //Print("Ready to open sell order at "+Bid);
      } else {
          Print("BLOCKED sell order at "+Bid);
     }
   }
      
    if (S_OrderType==1 && S_ContinueOpening && ((Bid-S_LastPrice)>=ShortPips*Point || S_OpenOrders<1)) 
     {		
      SellPrice=Bid;				
      S_LastPrice=0;
      if (ShortTakeProfit==0) { S_tp=0; }
       else { S_tp=SellPrice-ShortTakeProfit*Point; }	
      if (ShortInitialStop==0) { S_sl=0; }
       else { S_sl=NormalizeDouble(SellPrice+ShortInitialStop*Point + (ShortMaxTrades-S_OpenOrders)* ShortPips*Point, Digits);  }
        S_OrderLotSize=G_OrderLotSize;			
            if (S_OpenOrders <= 0)
            {
               S_OrderLotSize = FixedLotsOrder1;
            } else
            if (S_OpenOrders == 1)
            {
               S_OrderLotSize = FixedLotsOrder2;
            } else
            if (S_OpenOrders == 2)
            {
               S_OrderLotSize = FixedLotsOrder3;
            } else
            if (S_OpenOrders == 3)
            {
               S_OrderLotSize = FixedLotsOrder4;
            } else
            if (S_OpenOrders == 4)
            {
               S_OrderLotSize = FixedLotsOrder5;
            } else
            if (S_OpenOrders == 5)
            {
               S_OrderLotSize = FixedLotsOrder6;
            } else
            if (S_OpenOrders == 6)
            {
               S_OrderLotSize = FixedLotsOrder7;
            } else
            if (S_OpenOrders == 7)
            {
               S_OrderLotSize = FixedLotsOrder8;
            } else
            if (S_OpenOrders == 8)
            {
               S_OrderLotSize = FixedLotsOrder9;
            } else
            if (S_OpenOrders > 8)
            {
               S_OrderLotSize = FixedLotsOrderLast;
            }
            if (UseDynamicLots)
            {
              S_OrderLotSize = G_OrderLotSize*S_OrderLotSize;
            }
            if (UseProgression)
            {
              S_OrderLotSize = S_ProgFactor*S_OrderLotSize;
            }
       S_OrderLotSize = NormalizeDouble(S_OrderLotSize,G_Decimals);
       if (S_OrderLotSize < G_MinLotSize)
       {
         Print("ERROR: Lot size "+S_OrderLotSize+" too small, min "+G_MinLotSize+" required");
         S_OrderLotSize = G_MinLotSize;
       }
       if (S_OrderLotSize > G_MaxLotSize)
       {
         Print("ERROR: Lot size "+S_OrderLotSize+" too big, max "+G_MaxLotSize+" allowed");
         S_OrderLotSize = G_MaxLotSize;
       }
	    if (S_OpenOrders<1)
	    {
	      S_Balance = AccountBalance();
	    }
	    int nextOrder = S_OpenOrders+1;
	    Print("Open sell @"+nextOrder+" of "+DoubleToStr(S_OrderLotSize,G_Decimals)+" at "+DoubleToStr(SellPrice,4)+" sl "+DoubleToStr(S_sl,4)+" tp "+DoubleToStr(S_tp,4));
	    int ticket = OrderSend(Symbol(),OP_SELL,S_OrderLotSize,SellPrice,S_Slippage,S_sl,S_tp,"Goblin Bipolar Sell",ShortMagicNumber,0,Red);		    		    
	    if (ticket < 0)
	    {
	      Print("ERROR opening sell order at "+SellPrice);
	    }
	    return(0);    
     }      
    return(0);
  }  
  
int deinit()
  {
   return(0);
  }  
  

//==================================================== And here's the lovely Buy/Sell Signal Generator  ============================================<<

int OpenOrdersBasedOnTrendRSX()
{
     int SignalOrderType=3;
     double slowsma=0,mediumsma=0,fastsma=0;

// Let's check our very reliable super secret mega-signal...
 
   if (UseJMATrend)
   {
     double jma1=iCustom(Symbol(),Period(),"Turbo_JMA",JMAPeriod,-100,0,JMALag);
     double jma2=iCustom(Symbol(),Period(),"Turbo_JMA",JMAPeriod,-100,0,JMALag+1);
     if (MathAbs(jma1 - jma2) / Point > JMAPointDiff)
      {
       if (jma1 < jma2) {SignalOrderType=1;}
       if (jma1 > jma2) {SignalOrderType=2;}
      }
   }
   
// Welp, our mega-signal says no cigar...let's see what trusty 'ol RSX has to say...  
 
     if (SignalOrderType==3 && UseRSX)
     {
       double UpTrendVal = iCustom(Symbol(),Period(), "Turbo_JVEL",17,-100,0,1);
       double DnTrendVal = iCustom(Symbol(),Period(), "Turbo_JVEL",17,-100,1,1);
       double TrendVal = (UpTrendVal + DnTrendVal);
       double rsxcurr = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,1);
       double rsxprev1 = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,2);
       double rsxprev2 = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,3);
       if (UseConservativeRSX_Signals==true)
        {            
         if (rsxcurr < rsxprev1 &&  rsxcurr < 70 && rsxprev1 > 70 && TrendVal < (-0.01)) {SignalOrderType=1;}    // we only go short on RSX downturns
         if (rsxcurr > rsxprev1 &&  rsxcurr > 30 && rsxprev1 < 30 && TrendVal > (0.01)) {SignalOrderType=2;}       // we only go long on RSX upturns
        }
       if (UseConservativeRSX_Signals==false)
        {            
         if (rsxcurr < rsxprev1 && TrendVal < (-0.01)) {SignalOrderType=1;}    // we only go short on RSX downturns
         if (rsxcurr > rsxprev1 && TrendVal > (0.01)) {SignalOrderType=2;}       // we only go long on RSX upturns
        }
     } 
      
     if (SignalOrderType == 1 &&  UseSMATrendFilter == true)
     {
        fastsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterFastSMAPeriod,-100,0,1);
        mediumsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterMediumSMAPeriod,-100,0,1);
        slowsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterSlowSMAPeriod,-100,0,1);
        if (slowsma > mediumsma && mediumsma > fastsma)
        {
           SignalOrderType = 1;
        } else {
           SignalOrderType = 3;
        } 
     }
     if (SignalOrderType == 2 &&  UseSMATrendFilter == true)
     {
        fastsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterFastSMAPeriod,-100,0,1);
        mediumsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterMediumSMAPeriod,-100,0,1);
        slowsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterSlowSMAPeriod,-100,0,1);
        if (slowsma < mediumsma && mediumsma < fastsma)
        {
           SignalOrderType = 2;
        } else {
           SignalOrderType = 3;
        } 
     }  
        
     return(SignalOrderType);
}






Sample





Analysis



Market Information Used:



Indicator Curves created:


Indicators Used:




Custom Indicators Used:
Turbo_JVEL
Turbo_JRSX
Turbo_JMA

Order Management characteristics:
Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached

Other Features:


BackTest : EURUSD on H1

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

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 : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDCAD on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDCHF on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : USDJPY on H1

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

Request Backtest for Goblin_BiPolar_FixedLots_alassio


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

Pair: Period: