Help! Not sure how to save indicator values accross time.

 

Hello, I am writing an EA using Chaos theory, and I am trying to save the value of the fractal longer then just the bar it showed up in. For example, one bar will have the fractal value. In another 2-3 bars I may get the alligator cross over, and finally I am waiting for the price to cross over the original fractal price before I enter a trade. So pretty much by the book.


Code doesn't work as intended. Desired behavior is that the fractal value is somehow remembered up until the order either gets canceled or filled. But I end up getting the entryPrice overwritten with each new function run. I am not sure what to google at this point. Any approach suggestions? Thanks a million.


Below is where I pass the value of the fractal into a signal function.


//+------------------------------------------------------------------+
//             BREAKOUT DOWN
//+------------------------------------------------------------------+
double breakoutDown()
{
int conditionSell=0;
double entryPrice=Low[6];
double fractal=iFractals(NULL,0,MODE_LOWER,6);
double lips_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,1);
double teeth_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORTEETH,1);
double jaw_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORJAW,1);
double lips_val2=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,2);
double lips_val3=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,3);

Print("Fractal Down value is: "+StrToDouble(fractal));
//Print("Sell Entry Price value is: "+StrToDouble(entryPrice));
//Print("Lip Value 1 value is: "+StrToDouble(lips_val1));
//Print("Teeth Value 1 value is: "+StrToDouble(teeth_val1));
//Print("Jaw Value 1 value is: "+StrToDouble(jaw_val1));
//Print("Lip Value 2 value is: "+StrToDouble(lips_val2));
//Print("Lip Value 3 value is: "+StrToDouble(lips_val3));
 if  (fractal>0
      //&& Open[1]<lips_val1 && Close[1]<lips_val1
     // && Open[2]<lips_val2 && Close[2]<lips_val2
      && Open[3]<lips_val3 && Close[3]<lips_val3
      && lips_val1<teeth_val1
      && teeth_val1<jaw_val1)
      {
      conditionSell=1;
      }
      if (conditionSell==1) return(entryPrice);
      else return(0.0);
}
;


Here is my signal function:

void CheckForSignal()
  {
  if (TotalOpenOrders()==0) {

 
  // If fractal condition is met, search for price, set condition Buy to true.
  // Invalidate Buy = true if conditions meet, else buy on 1 pip over fractal high. Same for sell.
  double entryPrice;
 
  if(entryPrice>0 && orderInvalidatedSell()==1) entryPrice=0.0;
  else if (entryPrice>0 && Ask<= entryPrice)
      { EnterTrade(OP_SELL);   
        Print("Sell Order Placed from Signal");
       
      }
  else if (entryPrice==0 && breakoutDown()>0)
   {
   entryPrice=breakoutDown();
   Print("New Sell entry Price is: "+DoubleToStr(entryPrice));
   } 
   if(entryPrice>0 && orderInvalidatedBuy()==1) entryPrice=0.0;
   else if (entryPrice>0 && Ask>= entryPrice)
      {
        EnterTrade(OP_BUY);
        Print("Buy Order Placed from Signal");
      }
    else if (entryPrice==0 && breakoutUp()>0)
    {
   entryPrice=breakoutUp();
   Print("New Buy entry Price is: "+DoubleToStr(entryPrice));
   } 
}


Order invalidate is just a simple filter:



//+------------------------------------------------------------------+
//             SELL ORDER INVALIDATED
//+------------------------------------------------------------------+
int orderInvalidatedSell()
{ //if lips cross teeth down.
double lips_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,1);
double teeth_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORTEETH,1);
double lips_val2=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,2);
double teeth_val2=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORTEETH,2);

if (lips_val1>teeth_val1 && lips_val2<teeth_val2) return(1);
else return(0);

 

Please edit your posting to use code style. You can align indentation of your code with the code styler (Tools-Styler or the Comb symbol in MetaEditor.)

The usual way to keep values over repeated calls is to use either global or static variables, I suggest to use globals for now. For example you could remember the last fractal down in a global variable and if price drops below it, check if it coincides with a gator's down cross.

Then this will not work:

  double entryPrice;
 
  if(entryPrice>0 && orderInvalidatedSell()==1) entryPrice=0.0;

Note that when local variables are allocated they do not get assigned any value, that is the value of entryPrice is undefined (it can be anything.) So you need to initialize entryPrice befor you start working with it.

 
lippmaje:

Please edit your posting to use code style. You can align indentation of your code with the code styler (Tools-Styler or the Comb symbol in MetaEditor.)

The usual way to keep values over repeated calls is to use either global or static variables, I suggest to use globals for now. For example you could remember the last fractal down in a global variable and if price drops below it, check if it coincides with a gator's down cross.

Then this will not work:

Note that when local variables are allocated they do not get assigned any value, that is the value of entryPrice is undefined (it can be anything.) So you need to initialize entryPrice befor you start working with it.

Thank you for the code style tip! I was wondering how you guys did this.


So I moved it to global variable, and have the following code:

double fractalDown=0.0;

double fractalUp=0.0;

.

.

.

void OnTick()
  {
//---
   //static datetime candletime=0;
   //if(candletime!=Time[0])
   //  {
  if (fractalDown==0){
  if (breakoutDown()>0)
  {fractalDown = breakoutDown(); Print("Fractal Down is: "+DoubleToStr(fractalDown)); Sleep(1000);}}
 
  if (fractalUp=0){
  if (breakoutUp()>0) {fractalUp=breakoutUp();  Print("Fractal Up is: "+DoubleToStr(fractalUp)); Sleep(1000);}}


But I still don't get the result I want. In screenshot below you can see that the fractal does indeed get recorded,but only for the duration of the candle. Once new candle generates, I get values of 0 again. How do I retain the value until it is explicitly overwritten/deleted? I appreciate any tips. Thank you all!



Fractal Not Saved

 

You've already added a new bar check, good. You need to keep the fractal down recording task and the gator's down cross check independent. This is because both events may not occur at the same distance of bars. In your breakoutDown function you check for a fractal down 6 bars in the past, how often do you get this exact distance?

So for each new candle you need to do this:

  1. Look at the 2nd last bar if there's a fractal. (Or the 3rd last, from here on the fractals do not repaint, it's up to your taste.) Remember the fractal in its global, together with the current time.
  2. Check if in the last candle we had gator's down (up) cross. Set a gatorsbuysig or gatorssellsig flag.

And for any other tick do this:

  1. Check if Bid drops below recorded fractal down (if there's any but normally there is).
  2. If so, check if gators sell flag is set.
  3. If both is true, check also if the time of the last frac down fits your timing scale. If it's too far behind, do nothing, else go short.
 

Thank you so much for your help!

I did manage to somehow preserve the value of the fractal I wanted, which is great. Rest doesn't work as well as I would like, but for anybody interested, here is the final signal function. Please replace "Enter Trade" function I have with OrderSend() to get this to work.

PS Apologies for the late response...

void CheckForSignal()
  {
  if (TotalOpenOrders()==0) {

   static datetime candletime=0;
   if(candletime!=Time[0])
    {
   double fractalDown=iFractals(NULL,0,MODE_LOWER,3);
   double fractalUp=iFractals(NULL,0,MODE_UPPER,3);
   double lips_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,1);
   double teeth_val1=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORTEETH,1);
   double lips_val13=iAlligator(NULL,0,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN,MODE_GATORLIPS,3);


if(fractalDown!=0 && Close[3]<lips_val13 && Open[3]<lips_val13 && lips_val1<teeth_val1)
      {fractalXD=fractalDown;
      if (Bid<=fractalDown-(1*pips)){EnterTrade(OP_SELL);
      //Print("Close is: "+Close[3]+" open is: "+Open[3]+" lips 3 is: "+lips_val13+" fractal is: "+fractalXD);
      Print("Sell Order Placed from Signal");}
      }
if(fractalUp!=0 && Close[3]>lips_val13 && Open[3]>lips_val13 && lips_val1>teeth_val1)
      {fractalXD=fractalUp;
      if (Ask>=fractalUp+(1*pips)){ EnterTrade(OP_BUY);
       Print("Buy Order Placed from Signal");}
      }
  
   }}}

 

There's a part of your new bar check missing. From your code:

   static datetime candletime=0;
   if(candletime!=Time[0])

It doesn't suffice just to query candletime, you also need to update it. Do this:

   static datetime candletime=0;
   if(candletime!=Time[0])
     {
       candletime=Time[0];

I'd also recommend to move this code block into a function with a distinctive name. Like so:

bool IsNewBar()
  {
   static datetime candletime=0;
   if(candletime!=Time[0])
     {
       candletime=Time[0];
       return true;
     }
   return false;
  }


And keep the tasks that need to be done once a bar apart from tasks that need to be done per tick.

Tasks once per bar:

  1. Record Fractal high/low
  2. Check for Gator's cross

Tasks once per tick:

  1. Check for new bar and execute tasks once per bar if required
  2. Check if Bid bypasses previously recorded Fractal
  3. Maintain or close open trades
  4. Open new trades if advised by signals


Here's a coarse outline of the OnTick function:

void OnTick()
  {
   static string signal; // keep it sticky across calls

   if(IsNewBar())
     {
      // Perform tasks once a bar
      signal=CheckForSignal();
     }

   // --- From here we operate per tick ---


   // Refine signal

   if(Bid<=fractalDown-(1*pips) && signal=="gatorsdown") // Bid drops below Fractal on Gator's down signal
     {
      signal="sell";
     }


   // Maintain/close open trades

   if(signal=="sell") CloseOpenBuys(); // close opposite trade if signal is set
   MaintainStopLossAndTakeProfitForOpenTrades();

   // Open new trades if signal is set

   if(signal=="sell")
    {
      EnterTrade(OP_SELL);
      Print("Sell Order Placed from Signal");
      signal="";
    }
  }