Strategy Tester only simulates short trades with additional piece of code.

 

Hi there,

Thanks in advance.

I have this working code that in Strategy Tester detects a MACD crossover and places a trade in the relevant direction:

#property copyright "Brett"
#property link      "NA"

bool TradingConditionsChecked = false;

extern int TIMEFRAME = 0;

// MACD signal related variables.
extern int FAST_EMA = 12;
extern int SLOW_EMA = 26;
extern int SIGNAL = 9;

// Variables related to orders.
int OrderDirection = 0;
extern double LOTSIZE = 0.1;
extern double STOPLOSS = 20;
extern double TAKEPROFIT = 20;
double PipSize = 0;
extern int MAGICNUMBER = 123;
extern int SLIPPAGE = 3;
string COMMENT = "";
int EXPIRATION = 0;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   Print("Init method ran");
   CalculatePipSize();
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {

   return(0);
  }

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

int start()
   {
   // for each tick check for trading conditions, if market is open and place trade if possible.
   // Check if trading conditions confirm entry.
   // Ensure check runs on candles instead of every tick
   if(IsNewCandle())
      {
         TradingConditionsChecked = CheckTradingConditions();
            if(TradingConditionsChecked)
               OrderEntry(OrderDirection); // If yes then place trade
      }// IsNewCandle
   Print("Start method ran");
   return(0);
  }
//+------------------------------------------------------------------+

void CalculatePipSize()
   {
   double TickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
   if(TickSize == 0.00001 || TickSize == 0.001)
   PipSize = TickSize * 10;
   else PipSize = TickSize;
   }
   
bool IsNewCandle()
   {
   static int NumberOfBars = 0;
   if (NumberOfBars == Bars)
         return(false);
      NumberOfBars = Bars;
      Print("IsNewCandle method ran");
      return(true);
   }
   
bool CheckTradingConditions()
   {
   // determine if macd crossed signal up or down.
   if(MACDCrossedSignal())
      {
      Print("CheckTradingConditions = TRUE"); 
      return(true);
      }
   Print("CheckTradingConditions = FALSE");
   }

   
bool MACDCrossedSignal()
   {
   Print("MACDCrrosedSignal method called");
   if(iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_MAIN,2) < iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_SIGNAL,2))
      {
      Print("Previous MACD < previous signal = TRUE");
      if(iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_MAIN,1) > iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_SIGNAL,1))
         {
         Print("MACDCrossedSignal ran and crossed UP"); 
         OrderDirection = 0; 
         return(true);
         }// Current MACD > current signal
      }// Previous MACD < previous signal
   if(iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_MAIN,2) > iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_SIGNAL,2))
      {
      Print("Previous MACD > previous signal = TRUE");
      if(iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_MAIN,1) < iMACD(NULL,TIMEFRAME,FAST_EMA,SLOW_EMA,SIGNAL,PRICE_CLOSE,MODE_SIGNAL,1))
         {
         Print("MACDCrossedSignal ran and crossed DOWN"); 
         OrderDirection = 1; 
         return(true);
         }// Current MACD < previous signal
      }// Previous MACD > previous signal
   Print("MACDCrossedSignal ran with result FALSE");
   }

void OrderEntry(int OrderDirection)
   {
   // Place order.
   if(OrderDirection == 0)
      if(OrdersTotal() == 0)
         OrderSend(Symbol(),OP_BUY,LOTSIZE,Ask, SLIPPAGE,Ask-(STOPLOSS*PipSize),Ask+(TAKEPROFIT*PipSize),COMMENT,MAGICNUMBER,EXPIRATION, Green);
   if(OrderDirection ==1)
      if(OrdersTotal()==0)
         OrderSend(Symbol(),OP_SELL,LOTSIZE,Bid, SLIPPAGE,Bid+(STOPLOSS*PipSize),Bid-(TAKEPROFIT*PipSize),COMMENT,MAGICNUMBER,EXPIRATION, Red);
   }

 I want to add PSAR as the next criteria to be met and adjust the code to include this:

// PSAR related variables
extern double STEP = 0.02;
extern double MAX = 0.2;

//----------------------

bool CheckTradingConditions()
   {
   // determine if macd crossed signal up or down.
   if(MACDCrossedSignal())
      if(PSARConfirms())
         {
         Print("CheckTradingConditions = TRUE"); 
         return(true);
         }
   Print("CheckTradingConditions = FALSE");
   }

bool PSARConfirms()
   {
   if(OrderDirection == 0)
      if(iSAR(NULL,TIMEFRAME,STEP,MAX,1) < PRICE_CLOSE)
         {
         Print("PSARConfirms ran and confirmed SAR below price"); 
         return(true);
         }
   if(OrderDirection == 1)
      if(iSAR(NULL,TIMEFRAME,STEP,MAX,1) > PRICE_CLOSE)
         {
         Print("PSARConfirms ran and confirmed SAR above price");
         return(true);
         }
   }

Strategy Tester simulates long and short trades for the working code.  After I created the PSARConfirms function and called it from CheckTradingConditins function, ST only simulates short trades!  When I look in the journal, the time of the bar ST should detect as a long trade isn't there!

 

 ST should place a long trade at 2013.05.29 22.00 as both MACD and PSAR are indicating a long position but journal skips from 17:30 to 22:30.

Strangely ST appears to do the same thing in the journal with the working code but still actually simulates the code in the visual view and results sections as shown below.

 

 How can I get ST to sim both long and short trades.

Thanks so much. 

 

The OrderEntry function actually looks like this, sorry:

void OrderEntry()
   {
   // Place order.
   if(OrderDirection == 0)
      if(OrdersTotal() == 0)
         OrderSend(Symbol(),OP_BUY,LOTSIZE,Ask, SLIPPAGE,Ask-(STOPLOSS*PipSize),Ask+(TAKEPROFIT*PipSize),COMMENT,MAGICNUMBER,EXPIRATION, Green);
   if(OrderDirection ==1)
      if(OrdersTotal()==0)
         OrderSend(Symbol(),OP_SELL,LOTSIZE,Bid, SLIPPAGE,Bid+(STOPLOSS*PipSize),Bid-(TAKEPROFIT*PipSize),COMMENT,MAGICNUMBER,EXPIRATION, Red);
   }
 
brad:

The OrderEntry function actually looks like this, sorry:

Have you looked up what  PRICE_CLOSE  actually means ?  it's a constant,  most of the "variables" in upper case are constants,  it is zero.  So this explains why you only have Sell trades. 
 
  1. PRICE_CLOSE == 0
  2. OrderSend(Symbol(),OP_SELL,LOTSIZE,Bid, SLIPPAGE,Bid+(STOPLOSS*PipSize), ...

  3. if (NumberOfBars == Bars)
    bars is unreliable, volume is unreliable, always use time.
  4. bool MACDCrossedSignal()
    returns random result at end of function. No return(false)
 
Thanks for your comments! Very helpful.
Reason: