Need help with function

 

I am trying to create a function that will not allow MT4 to place a pending trade at the same price as a currently open trade.

for example:
if I have a buy order open at "x" price and my entry rules later say place a buystop at "x" price it will not allow this to happen.

This is what I have right now and it currently is not working.

function:

int buytradeok()
   {
   int trade=0;
//----
   for(int f=0;f<OrdersTotal();f++)
     {
      if(OrderSelect(f,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol())
        {
         if(OrderType()==OP_BUY)
            {
            if (OrderOpenPrice() == entry1)  trade++;
            }
        }
     }
//---- return orders volume
   if(trade>0)return(1);
   else  return(0);
   }

Ordersend:

      if (total < MaxOrders)
            {
                  if (CalculateBuyOrders()==0 && Close[0]<frac_up)                                                                                                                      //only opens buystop order if buystops are equal to 0                                                                   
                     {
                     if (buytradeok() < 1)
                        {
                        if (RiskManagement==true)
                           {
                           ticket=OrderSend(Symbol(),OP_BUYSTOP,LotValue,entry1,MaxSlippage,stoploss1,takeprofit1,NULL,0,0,Blue);
                           if(ticket>0)
                                 {
                                 if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                                 Print("BUYSTOP opened : ",OrderOpenPrice());
                                 }
                           else Print("Error opening BUYSTOP order : ",GetLastError());
                           }
 
bauerjj10:

function:

//...
         if(OrderType()==OP_BUY)
            {
            if (OrderOpenPrice() == entry1)  trade++;
            }
//...
Assuming 'entry1' is a double, this part won't work properly. See section 4 in this article -> https://www.mql5.com/en/articles/1561.
 
bool CompareDoubles(double number1,double number2)
  {
   if(NormalizeDouble(number1-number2,Digits)==0) return(true);
   else return(false);
  }
//----------------------------------------------------------------
//----------------------------------------------------------------

int buytradeok()
   {
   int trade=0;
//----
   for(int f=0;f<OrdersTotal();f++)
     {
      if(OrderSelect(f,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol())
        {
         if(OrderType()==OP_BUY)
            {
            if (CompareDoubles(OrderOpenPrice(),entry1)  trade++;
            }
        }
     }
//---- return orders volume
   if(trade>0)return(1);
   else  return(0);
   }

Gordon,

thank you for pointing me to that article, Here is my new function after reading section 4. Unfortunately I will not be able to test it until I get home but if you have a sec to look at it and let me know if it looks like it may work I would appreciate it.

Thanks again.

 

Some remarks:

  • It's better to include the standard library (instead of adding the code for CompareDoubles() function). Just add the following line to the head of your file:
#include <stdlib.mqh>
  • Your function loops on all orders, but eventually u return 1 for trade>0... Why not return 1 the moment u find one order that fits the criteria? You can do it inside the loop:
if (CompareDoubles(OrderOpenPrice(),entry1))  return(1);
  • You should limit the use of your globals as much as possible. In this case, it's recommended to pass 'entry1' to the function instead of having it on a global scope:
int buytradeok( double entry1 )
 
gordon wrote >>

Some remarks:

  • It's better to include the standard library (instead of adding the code for CompareDoubles() function). Just add the following line to the head of your file:
  • Your function loops on all orders, but eventually u return 1 for trade>0... Why not return 1 the moment u find one order that fits the criteria? You can do it inside the loop:
  • You should limit the use of your globals as much as possible. In this case, it's recommended to pass 'entry1' to the function instead of having it on a global scope:


I understand the first two bullets, I dont understand the 3rd bullet.

What does this do?

int buytradeok( double entry1 )

I thought I didnt want anything inside of the parenthesis because what is underneith that line will decide the value of int buytradeok()

 

This is from the explanation about functions in the book (which I recommend you read -> https://book.mql4.com/basics/functions):

If you put 'entry1' in the header as I did, it will be used as a formal parameter. It's value will be passed to the function... This is better than having the variable on a global scope. If you do not understand what I just said, then u definitely need to do some reading...

 
gordon wrote >>

This is from the explanation about functions in the book (which I recommend you read -> https://book.mql4.com/basics/functions):

If you put 'entry1' in the header as I did, it will be used as a formal parameter. It's value will be passed to the function... This is better than having the variable on a global scope. If you do not understand what I just said, then u definitely need to do some reading...


I already have read that whole book, I have never done any type of programing in my entire life so this is all new to me, I feel I am lightyears ahead of where I was a week ago.

Looks like I need to reread that book, this time around I am sure I will pick up more then I did my first time reading it.

You have been a great help and for me it is easier learning when someone like you gives a little more explanation then what the book says.

I hope my questions are not frustrating.

Btw, the explanation above makes sense to me now, Thank you

 

Now why can't all forum newcomers be like bauerjj10?

CB

 

cloudbreaker, I appreciate the compliment, I try to be respectful especially to those who I am seeking advice from.

I went through my code and turned much of it into functions after reading up on it. I was, however, unable to add in Formal Parameters without getting quite a few errors such as Parameter count errors, parameter definition expected, and unbalanced right parenthesis <--- even though they definately were balanced.

I decided to remove all the parameters and the code compiled just fine. Now my issue is when running it in metatrader tester I am getting ordersend error 4107. I added a print statement into the code to see if my lot size calculation was making it from the calculation function to the ordersend function and it was coming up as a value of 0.

I am assuming that my values assigned to my variables are not being recognized from function to function.

Could someone please look at my code and give me some feedback on what I may be doing wrong?

Its attached.

Thanks

 
  • Error 4107 is probably due to usage of unnormalized prices in the OrderSend() function. You should normalize Open Price, SL and TP to the number of digits of the specific symbol used (if it's the same symbol as the chart's then u can use the predefined variable 'Digits'). Using the function is explained in it's documentation: https://docs.mql4.com/convert/NormalizeDouble.
  • Regarding lot size - if it's the result of some complicated calculation (as in your case), then it's recommended to normalize lot size to the number of digits lot size uses (this is broker/account specific). Lot size also has to confirm to MODE_MINLOT, MODE_LOTSTEP, MODE_MAXLOT. These values can be read via MarketInfo() function. Their meaning is self explanatory here -> https://docs.mql4.com/constants/marketinfo.
  • All your functions have no formal parameters... And most variables are defined on global scope. Obviously this is not good and is something you need to work on. I recommend putting aside this EA for a while (since it has quite a few lines of code) and trying to understand the concepts of structured programming on simpler examples. Specifically how to move information in and out of functions without using global variables. A good starting point is the section about functions in the book: https://book.mql4.com/basics/functions.
 

Ok read the functions book about 5 times now and I think I am finally grasping things.

Here is my calculations for lot size loaded in a function, I also call another function inside of this function. When I get home I will check to see if it works.

//--- AccType,RiskPercent are both extern variables, and frac_up,frac_dn are both icustom variables.
//--- here is how I get the value of "LotValuefunc"
//
double LotValuefunc(AccType,RiskPercent,frac_up,frac_dn);
//
//
//
//--- lot value function  <--- goes outside of Start() function---
double LotValuefunc (double AccountType, double RiskPercent1, double fracline1, double fracline2)
   {
   double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE)*AccountType;
   double AccDollarToRisk = (AccountEquity()*RiskPercent1) /100; 
   double SLDollarAmount= pipsatriskfunc(fracline1,fracline2) * TickValue; 
   double Lots = AccDollarToRisk / SLDollarAmount; 
   double LotValue1 =  Lots * TickValue;
   return (LotValue1);
   }
//
//
//--- pips at risk function <-- goes outside of Start() function--
double pipsatriskfunc(double fracline1,double fracline2)
   {
   return(NormalizeDouble(fracline1,Digits)-NormalizeDouble(fracline2,Digits)/Point);
   }