I'm about to give up on this language. Need help building correctly...

 

I've racked my brain around this language. Nothing makes sense to me. All I want is to get in and out of trades based on a couple of indies. ANY help would be appreciated.


//+------------------------------------------------------------------+
//|                                               Underworldbros.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql4.com"
#property version   "1.00"
#property strict

extern double RiskPercent=2;
double magix=420;



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   double Lots=CalcLots();
//---
   double HMA_Slow=iCustom(NULL,0,"HMA",14,0,0);
   double HMA_Fast=iCustom(NULL,0,"HMA",10,0,0);
//---

//---
   double DRSI_UPZ=iCustom(NULL,0,"Dynamic Zone RSI_3",16,24,1,0);
   double DRSI_DNZ=iCustom(NULL,0,"Dynamic Zone RSI_3",16,24,2,0);
   double DRSI_BUF=iCustom(NULL,0,"Dynamic Zone RSI_3",16,24,0,0);
//---

//---
   double ATR_SL=iCustom(NULL,0,"ATR in SL-TP_2",14,1.5,1,0,0,1,0,1);
   double ATR_TP=iCustom(NULL,0,"ATR in SL-TP_2",14,1.5,1,0,0,1,1,1);
//---

   Print("ATR Buffer 0 = ",ATR_SL);
   Print("ATR Buffer 1 = ",ATR_TP);
   Print("DRSI Buffer 1 = ",DRSI_UPZ);
   Print("DRSI Buffer 2 = ",DRSI_DNZ);
   Print("DRSI Buffer 0 = ",DRSI_BUF);
   Print("HMA Period 10 = ",HMA_Fast);
   Print("HMA Period 14 = ",HMA_Slow);
   Print("Lots = ",Lots);

//---
//---
   static datetime LTF=0;
   if(LTF==0 || LTF<iTime(NULL,0,0))
     {
      double ATR[4];
      string PrintStr="";

      int bar=1;
      for(int i=0; i<4; i++)
        {
         ResetLastError();
         ATR[i]=iCustom(NULL,0,"ATR_in_SL-TP",14,1.5,1,0,0,1,i,bar);
         int Err=GetLastError();
         if(Err>0)
            Print("Err at i = ",i,", Code = ",Err);
         PrintStr=PrintStr+"ATR["+IntegerToString(i)+"] = "+DoubleToStr(ATR[i],2)+"  ";
        }
      Print("bar = ",IntegerToString(bar)," ",PrintStr);
      PrintStr="";

      LTF=iTime(NULL,0,0);
     }
//---

double TP=(Ask+ATR_TP*Point);
double SL=(Ask-ATR_TP*Point);

//---
      
   if((HMA_Fast<HMA_Slow)==true)
  {
   OrderSend(NULL,OP_BUY,Lots,Ask,3,SL,TP,"Buy",420,0,clrLime);
  }

   if((HMA_Fast>HMA_Slow)==true)
  {
   OrderSend(NULL,OP_SELL,Lots,Ask,3,SL,TP,"Sell",420,0,clrRed);
   
//---
   
}


  }
//+------------------------------------------------------------------+

double CalcLots()
  {
   double ATR_SL=iCustom(NULL,0,"ATR in SL-TP",14,1.5,1,0,0,1,0,1);

   double StopLoss=ATR_SL;

   double pipValue = MarketInfo(Symbol(),MODE_TICKVALUE); if(Digits==3 || Digits==5) pipValue *= 10;
   double step     = MarketInfo(Symbol(),MODE_LOTSTEP);
   int norm=0;
   if(step==1)    norm = 0;
   if(step==0.1)  norm = 1;
   if(step==0.01) norm = 2;
   double minLot = MarketInfo(Symbol(),MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(),MODE_MAXLOT);
   double lots   = AccountBalance()*(RiskPercent/100.0)/(StopLoss*pipValue);
   lots=NormalizeDouble(lots,norm);

   return (lots);
  }
//+------------------------------------------------------------------+





//+------------------------------------------------------------------+
 
underworlddjb: I've racked my brain around this language. Nothing makes sense to me.


You are frustrated because you don't know what is going on. Find out.
  1.  OrderSend(NULL,OP_BUY,Lots,Ask,3,SL,TP,"Buy",420,0,clrLime);
    You would know why, if you Check your return codes for errors, and report them including GLE/LE. Don't look at it unless you have an error. Don't just silence the compiler, it is trying to help you.
              What are Function return values ? How do I use them ? - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

  2. Don't use NULL.
    • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, iCustom does, MarketInfo does not. OrderSend does not.
    • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
    • Zero is the same as PERIOD_CURRENT which means _Period. Don't hard code numbers.
    • MT4: No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].

  3.    if((HMA_Fast<HMA_Slow)==true)
    You should be able to read your code out loud and have it make sense. You would never write if( (2+2 == 4) == true) would you? if(2+2 == 4) is sufficient. So don't write if(bool == true), just use if(bool) or if(!bool). Code becomes self documenting when you use meaningful variable names, like bool isLongEnabled where as Long_Entry sounds like a trigger price or a ticket number and "if long entry" is an incomplete sentence.

  4. double TP=(Ask+ATR_TP*Point);
    double SL=(Ask-ATR_TP*Point);
       OrderSend(NULL,OP_SELL,Lots,Ask,3,SL,TP,"Sell",420,0,clrRed);
    A SL must be above the market, TP below, for a sell order.
  5. What is the purpose of ATR_SL?
  6. You buy at the Ask and sell at the Bid. So for buy orders you pay the spread on open. For sell orders you pay the spread on close.
    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid reaches it. Not the Ask. Your SL is shorter by the spread and your TP is longer. Don't you want the same/specified amount for either direction?
    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25
    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (Control-O) → charts → Show ask line.)

  7. Never risk more than a small percentage of your account, certainly less than 2% per trade, 6% total.
    1. In code (MT4): Risk depends on your initial stop loss, lot size, and the value of the pair. It does not depend on margin and leverage.
      1. You place the stop where it needs to be - where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
      2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
      3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
                  MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
                  Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19
      4. You must normalize lots properly and check against min and max.
      5. You must also check FreeMargin to avoid stop out

      Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.


 
William Roeder:
You are frustrated because you don't know what is going on. Find out.
  1. You would know why, if you Check your return codes for errors, and report them including GLE/LE. Don't look at it unless you have an error. Don't just silence the compiler, it is trying to help you.
              What are Function return values ? How do I use them ? - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

  2. Don't use NULL.
    • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, iCustom does, MarketInfo does not. OrderSend does not.
    • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
    • Zero is the same as PERIOD_CURRENT which means _Period. Don't hard code numbers.
    • MT4: No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].

  3. You should be able to read your code out loud and have it make sense. You would never write if( (2+2 == 4) == true) would you? if(2+2 == 4) is sufficient. So don't write if(bool == true), just use if(bool) or if(!bool). Code becomes self documenting when you use meaningful variable names, like bool isLongEnabled where as Long_Entry sounds like a trigger price or a ticket number and "if long entry" is an incomplete sentence.

As far as GLE, I was going to work on that later. I'm just trying to get basic functionality at this point. I've been working on this for six months and getting nowhere. Thanx for the NULL correction. I'll get that changed. This is all good information. I'll impliment changes.
 
William Roeder:
What is the purpose of ATR_SL?

It's a stoploss based on the ATR of the previous candle. Best used on the daily chart. It's also used as a TP with a scale out.

 
underworlddjb: It's a stoploss based on the ATR of the previous candle. Best used on the daily chart. It's also used as a TP with a scale out.
   double ATR_SL=iCustom(NULL,0,"ATR in SL-TP_2",14,1.5,1,0,0,1,0,1);
   double ATR_TP=iCustom(NULL,0,"ATR in SL-TP_2",14,1.5,1,0,0,1,1,1);

The variable is not used.

 
William Roeder:

The variable is not used.

It's used. It's in the "OnTick" 
double TP=(Ask+ATR_TP*Point);
double SL=(Ask-ATR_TP*Point);
 
As far as the SL, I wanted to calculate 1%-2% of my current account. As to scale up or down with the balance. The more profit the larger the lot size and inverse. Did I not do that correctly? Where as the ATR was the determination of SL and TP.
double lots   = AccountBalance()*(RiskPercent/100.0)/(StopLoss*pipValue);
 

It is advisable to use

double TP = (Ask + ATR_TP*Point);
double SL = (Bid - ATR_TP*Point);

instead of

double TP = (Ask + ATR_TP*Point);
double SL = (Ask - ATR_TP*Point);

After that, you need to check those TP and SL for minimum allowable pip by using MarketInfo(Symbol, MODE_STOPLEVEL) or else you will face an error. I'm pretty sure you don't want that.

then, for.. ATR_TP and ATR_SL from iCustom i'm not sure what indicator you are using, but if it is this ATR, i don't think it will work.

If you are asking a question publicly, please make sure the information is complete.

If you are trying to hide something, try freelance instead.

 
underworlddjb: It's used. It's in the "OnTick" 
double TP=(Ask+ATR_TP*Point);
double SL=(Ask-ATR_TP*Point);

Look at your code, ATR_SL is not used.

 
Ahmad Zuhairdi Noh: It is advisable to use

No it is not.

You buy at the Ask and sell at the Bid. So for buy orders you pay the spread on open. For sell orders you pay the spread on close.
  1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid reaches it. Not the Ask. Your SL is shorter by the spread and your TP is longer. Don't you want the same/specified amount for either direction?
  2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25
  3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (Control-O) → charts → Show ask line.)
 
William Roeder:

No it is not.

well, yes it is.. using this TP and SL for BUY trade (long);
double TP = (Ask + ATR_TP*Point);
double SL = (Bid - ATR_TP*Point);
and this TP and SL for SELL trade (short);
double TP = (Bid - ATR_TP*Point);
double SL = (Ask + ATR_TP*Point);

This is to prevent error 130.

Reason: