Highest or Lowest candle problem

 

Hello guys,

I am not a programmer but i tried to figure out how to make a very simple EA, mostly just as a proof-of-concept.

EA will open order at different conditions (doesnt matter, in exemple i use a premade code that open orders using RSI).

The most important fact is that EA must place SL at X candles highest values (if sell conditions are fullfiled) and place SL at X candles lowest values (if buy conditions are fullfiled).


int HighestCandle=iHighest(NULL,0,MODE_HIGH,12,0);
int LowestCandle=iLowest(NULL,0,MODE_LOW,12,0);
double SLsellorder = NormalizeDouble(High[HighestCandle],Digits);
double SLbuyorder = NormalizeDouble(Low[LowestCandle],Digits);
///+////////////////////////////////////+////////////////////////////////////+/////////////////////////////////
//--------------------------------------------------------------------
void OnTick()
{
   for (int i=0; i<OrdersTotal(); i++)
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber()) return;
   double RSI0  = iRSI(NULL,0,period_RSI,PRICE_OPEN,0);
   double RSI1  = iRSI(NULL,0,period_RSI,PRICE_OPEN,1);
   double SL=0,TP=0;
   if (RSI0 > buy_level && RSI1 < buy_level && Low[LowestCandle]<Op(0))
   {
      if (takeprofit!=0) TP  = NormalizeDouble(Ask + takeprofit*Point,Digits);
      if (stoploss!=0)   SL  = SLbuyorder;    
      if (OrderSend(Symbol(),OP_BUY,Lot,NormalizeDouble(Ask,Digits),slippage,SL,TP,NULL,Magic)==-1) Print(GetLastError());
   }
   if (RSI0 < sell_level && RSI1 > sell_level && High[HighestCandle]>Op(0))
   {
      if (takeprofit!=0) TP = NormalizeDouble(Bid - takeprofit*Point,Digits);
      if (stoploss!=0)   SL = SLsellorder;            
      if (OrderSend(Symbol(),OP_SELL,Lot,NormalizeDouble(Bid,Digits),slippage,SL,TP,NULL,Magic)==-1) Print(GetLastError());
   }
}


Problems: The code that i introduced for SL doesnt use the highest / lowest values of the 12 candle in history. Sometimes use 5th candle, other times alsmost same as open price..

Can you guys please sugest what i can do?

 
int HighestCandle=iHighest(NULL,0,MODE_HIGH,12,0);
int LowestCandle=iLowest(NULL,0,MODE_LOW,12,0);
double SLsellorder = NormalizeDouble(High[HighestCandle],Digits);
double SLbuyorder = NormalizeDouble(Low[LowestCandle],Digits);

Shouldn't this be in OnTick() ?

I know that it is not obvious, but topics concerning MT4 and MQL4 have their own section.

In future please post in the correct section.

I will move your topic to the MQL4 and Metatrader 4 section.

 
Keith Watford:

Shouldn't this be in OnTick() ?

I know that it is not obvious, but topics concerning MT4 and MQL4 have their own section.

In future please post in the correct section.

I will move your topic to the MQL4 and Metatrader 4 section.

Thank you for fast reply! I will try now. Yes please move it in correct section.

 
Keith Watford:

Shouldn't this be in OnTick() ?

Thank you very very much! It works fine now :)

 
int HighestCandle=iHighest(NULL,0,MODE_HIGH,12,0);
int LowestCandle=iLowest(NULL,0,MODE_LOW,12,0);
double SLsellorder = NormalizeDouble(High[HighestCandle],Digits);
double SLbuyorder = NormalizeDouble(Low[LowestCandle],Digits);

That is not an assignment; it's initialization of a common (globally declared,) or static variable with a constant. They work exactly the same way in MT4/MT5/C/C++.

  1. They are initialized once on program load.

  2. They don't update unless you assign to them.

  3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

    MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and

    Don't try to use any price or server related functions in OnInit (or on load,) as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.
 

With your help guys i could make it work.

Now i want to make a function/code to calculate optimal lot size to risk 1% calculated by StopLoss. 

If BUY conditions are fullfiled, StopLoss will be the Lowest value from curent to 12th candle in past.

If SELL conditions are fullfiled, StopLoss will be the Highest value from curent to 12th candle in past.

//--------------------------------------------------------------------
input double   RiskPercent          = 1;
input double   TPMultiplier         = 1.5;
input int      CandleNumber         = 12;

//--------------------------------------------------------------------
void OnTick()
{

int HighestCandle=iHighest(NULL,0,MODE_HIGH,CandleNumber,0);
int LowestCandle=iLowest(NULL,0,MODE_LOW,CandleNumber,0);
double SLsellorder = NormalizeDouble(High[HighestCandle],Digits);
double SLbuyorder = NormalizeDouble(Low[LowestCandle],Digits);

   for (int i=0; i<OrdersTotal(); i++)
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber()) return;
   double SL=0,TP=0;
   
   //* BUY CONDITIONS
   if (OrdersTotal()==0 && (OPEN CONDITIONS))
   {
      if (takeprofit!=0)    TP  = NormalizeDouble(Ask + TPMultiplier*MathAbs(Ask-SLbuyorder),Digits);
      if (minstoploss!=0)   SL  = SLbuyorder;
      if (OrderSend(Symbol(),OP_BUY,LotCompoundBuy(),NormalizeDouble(Ask,Digits),slippage,SL,TP,NULL,Magic)==-1) Print(GetLastError());
   }
   
   //* SELL CONDITIONS
   if (OrdersTotal()==0 && (OPEN CONDITIONS))
   {
      if (takeprofit!=0)    TP = NormalizeDouble(Bid - TPMultiplier*MathAbs(SLsellorder-Bid),Digits);
      if (minstoploss!=0)   SL = SLsellorder;      
      if (OrderSend(Symbol(),OP_SELL,LotCompoundSell(),NormalizeDouble(Bid,Digits),slippage,SL,TP,NULL,Magic)==-1) Print(GetLastError());
   }
}
//--------------------------------------------------------------------


double GetPipValue()
{
   if(_Digits >=4)
   {
      return 0.0001;
   }
   else
   {
      return 0.01;
   }
}

double LotCompoundBuy()
{
int LowestCandle=iLowest(NULL,0,MODE_LOW,CandleNumber,0);
double SLbuyorder = NormalizeDouble(Low[LowestCandle],Digits);

  double accEquity = AccountEquity();
  double lotSize = MarketInfo(NULL,MODE_LOTSIZE);
  double tickValue = MarketInfo(NULL,MODE_TICKVALUE);
        if(Digits <= 3)
        {
        tickValue = tickValue/100;
        }
  double maxLoss = accEquity * RiskPercent;
  double maxLossInQuoteCurr = maxLoss / tickValue;
  double LotCompoundBuy = NormalizeDouble(maxLossInQuoteCurr /(MAXLOSSINPIPS * GetPipValue())/lotSize,2);
  return LotCompoundBuy; 
}

double LotCompoundSell()
{
int HighestCandle=iHighest(NULL,0,MODE_HIGH,CandleNumber,0);
double SLsellorder = NormalizeDouble(High[HighestCandle],Digits);
   
  double accEquity = AccountEquity();
  double lotSize = MarketInfo(NULL,MODE_LOTSIZE);
  double tickValue = MarketInfo(NULL,MODE_TICKVALUE);
        if(Digits <= 3)
        {
        tickValue = tickValue/100;
        }
  double maxLoss = accEquity * RiskPercent;
  double maxLossInQuoteCurr = maxLoss / tickValue;
  double LotCompoundSell = NormalizeDouble(maxLossInQuoteCurr /(MAXLOSSINPIPS * GetPipValue())/lotSize,2);
  return LotCompoundSell; 
}


Kinda what i have so far. 

Could you guys help me again with tip how can i modify / make a proper code?

As i said i am not a programer but i try to figure out what to write. Most likely i need to change in "LotCompoundBuy" the MAXLOSSINPIPS

 

I have found a solution but i am not sure how correctly is written :)

I changed MAXLOSSINPIPS with :

double LotCompoundBuy = NormalizeDouble(maxLossInQuoteCurr /(((Ask-Low[LowestCandle])*(MathPow(10,Digits))) * GetPipValue())/lotSize,2);

double LotCompoundSell = NormalizeDouble(maxLossInQuoteCurr /(((High[HighestCandle]-Bid)*(MathPow(10,Digits))) * GetPipValue())/lotSize,2);
Reason: