MQL4 - automated forex trading   /  

Forum

A couple questions from BugReport

Back to topics list To post a new topic, please log in or register

avatar
Moderator
28803
Rosh 2007.03.01 15:50 

I have received the letter of the following maintenance and have decided to answer it at a forum.

Hi,

I found 2 bugs and I am pretty sure they are bugs:

1. When you have:
double x = 0.0003/Point;
int y = x;
sometimes you get 2 and sometimes 3! Cannot convert double into int variable even with the NormalizeDouble().

2. When you use:
double margin_used_per_lot = AccountFreeMargin() - AccountFreeMarginCheck(Symbol(), OP_BUY, 1.0)
sometimes you get correct i.e. 2495.23 and sometimes you get -0.28!!!!! Which means AccountFreeMarginCheck resulting sometimes values greater than AccountFreeMargin which shoud be impossible!!!


1. I have written a special script which should reveal this mistake. This endless lopped script worked within all day, but and has not given out any mistake. Please, try it at itself.

//+------------------------------------------------------------------+
//|                                         CheckNormalizeDouble.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.ru/"
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
  int prevValue,currValue,counter;
  double x=0.0003;
//----
   while (!IsStopped())
      {
      currValue=x/Point;
      if (currValue!=prevValue)
         {
         Alert("currValue=",currValue,"    prevValue=",prevValue,"   counter=",counter);
         Print("currValue=",currValue,"    prevValue=",prevValue,"   counter=",counter);
         prevValue=currValue;
         }
      counter++;
      Sleep(300);   
      }   
//----
   return(0);
  }
//+------------------------------------------------------------------+

article

Video interview with Rashid Umarov

The main conclusion is that it is insufficient to have a profitable strategy: it is necessary to strengthen its advantages and smooth its disadvantages. This is the point in money management: You should gain the largest profit from your approach, your Expert Advisor, your system with minimal risk and in maximal amounts, without being short of it. This is the most important thing, to my mind.


avatar
Moderator
28803
Rosh 2007.03.01 16:16 
2. I think that you have the same number of orders for sale when you checked.
The free margin required for open one BUY order, and free margin required for open one BUY order and one SELL order(hedged both) are considered differently.
The required level for open hedged oder is show in the Contract specification/




Here is shown property for EURUSD on MQ-demo server. Value "0" means thats two hedged positions required less then 2*margin .
Run my script on the new demo account, and all can see the difference.

//+------------------------------------------------------------------+
//|                                       CheckAccountFreeMargin.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.ru/"
 
 
//+------------------------------------------------------------------+
//| return time of last time of openong or closing operation         |
//+------------------------------------------------------------------+
datetime lastTradeTime()
   {
   datetime res=0;
   int i;
   for (i=0;i<OrdersTotal();i++)
      {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
         if (OrderOpenTime()>res) res=OrderOpenTime();
         }
      }
 
   for (i=0;i<OrdersHistoryTotal();i++)
      {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         {
         if (OrderCloseTime()>res) res=OrderOpenTime();
         }
      }
   return(res);
   }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   int maxTrades=10,ordersCounter;
//----
   double curr_margin_used_per_lot,prev_margin_used_per_lot;
   int ticket;
   bool res;
      
   datetime delayTime=60; // 60 seconds delay between open and close
 
   if (!IsDemo()) 
      {
      Alert("This is real account!!!");
      return;
      }
   while (!IsStopped())
      {
      curr_margin_used_per_lot=AccountFreeMargin()-AccountFreeMarginCheck(Symbol(), OP_BUY, 1.0);
      if (prev_margin_used_per_lot==0) prev_margin_used_per_lot=curr_margin_used_per_lot;
      if (MathAbs(1-curr_margin_used_per_lot/prev_margin_used_per_lot)>0.2) 
         {
         Print("We have ",OrdersTotal(),": required curr margin=",curr_margin_used_per_lot,"  prev margin=",prev_margin_used_per_lot);
         }
      if (OrdersTotal()==0 && TimeCurrent()-lastTradeTime()>delayTime)
         {
         RefreshRates();
         ticket=OrderSend(Symbol(),OP_SELL,1,Bid,5,0,0,"need hedge",12345,0,Red);
         if (ticket<0) Print("Order SELL fails witt error code=",GetLastError());
         else 
            {
            ordersCounter++;
            Print("ordersCounter=",ordersCounter,"   maxTrades=",maxTrades);
            }
         }
      else
         {
         if (OrdersTotal()>0 &&TimeCurrent()-lastTradeTime()>delayTime)
            {
            for (int i=OrdersTotal()-1;i>=0;i--)
               {
               if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
                  {
                  if (OrderType()==OP_SELL && OrderSymbol()==Symbol())
                     {
                     RefreshRates();
                     res=OrderClose(OrderTicket(),OrderLots(),Ask,5,Green);
                     }
                  }
               }
            }
         }   
      Sleep(10000);
      prev_margin_used_per_lot=curr_margin_used_per_lot;
      if (ordersCounter>=maxTrades) 
         {
         Print("Test finished");
         break;
         }
      } 
//----
   return(0);
  }
//+------------------------------------------------------------------+




avatar
74
4x4ever 2007.03.06 13:05 
Hi Rosh

This guy probably forgot to mention that this error only happens in tester.

The problem, I think, is that AccountFreeMargin, AccountFreeMarginCheck and MarketInfo(Symbol(), MODE_MARGINREQUIRED) use the current (today's!) rates for their calculations, which is wrong. Please see for yourself - I ran my expert a few minutes ago (see picture). As you can see these functions caculate the free margin amount, based on the real-time Bid/Ask values, which is wrong. When running in the tester they must use the simulated values for the tested period:




Attached files:
  AccountInfo.mq4 (3.66 KB)

avatar
Moderator
28803
Rosh 2007.03.06 15:40 

avatar
Moderator
28803
Rosh 2007.03.07 11:21 
//+------------------------------------------------------------------+
//|                                        CheckAccountFunctions.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string MarginLevel;
   string CommentString=StringConcatenate("Account Number = ",AccountNumber(),"n");
   CommentString=StringConcatenate(CommentString,"AccountCurrency=",AccountCurrency(),"n");
   CommentString=StringConcatenate(CommentString,"AccountCompany=",AccountCompany(),"n");
   CommentString=StringConcatenate(CommentString,"AccountName=",AccountName(),"n");
   CommentString=StringConcatenate(CommentString,"AccountServer=",AccountServer(),"n");
   CommentString=StringConcatenate(CommentString,"AccountStopoutLevel=",AccountStopoutLevel(),"n");
   CommentString=StringConcatenate(CommentString,"AccountStopoutMode=",AccountStopoutMode(),"n");
   CommentString=StringConcatenate(CommentString,"AccountBalance()=",AccountBalance(),"n");
   CommentString=StringConcatenate(CommentString,"AccountMargin=",AccountMargin(),"n");
   CommentString=StringConcatenate(CommentString,"AccountEquity=",AccountEquity(),"n");
   
   if (AccountMargin()>0) MarginLevel=StringConcatenate("MarginLevel=",DoubleToStr(AccountEquity()/AccountMargin()*100,2),"% ");
   else MarginLevel="MarginLevel=N/A";
 
   CommentString=StringConcatenate(CommentString,MarginLevel);
   Comment(CommentString);
//----
   return(0);
  }
//+------------------------------------------------------------------+

This script helps to explain Account... functions .
Drag & Drop it on a chart with opened orders.






avatar
Moderator
28803
Rosh 2007.03.07 17:25 
Another question from beginner on MQL4

program=MetaTrader
type=0
version=4.00

when you have 40 objects & want to delete them one by one with this instruction, it cannot find the object.

int obj_total=ObjectsTotal();
string name;

for(int f=0;f<obj_total;f++)
{
name=ObjectName(f);
Print(" name ",name, " f ",f);
ObjectDelete(name);
int err=GetLastError();
if(err!=0)
{
Print("error(",err,"): ",ErrorDescription(err));
}
}

Please inform me if this is really a bug
Thank You


It is an example will work correctly if to change the order of detour of objects in a cycle from the maximal index to zero.

 
         int    obj_total=ObjectsTotal();
         string name;
 
         for(int f=obj_total-1;f>=0;f--)
         {
         name=ObjectName(f);
            Print(" name ",name, " f ",f);
            ObjectDelete(name);
            int err=GetLastError();
            if(err!=0)
            {
            Print("error(",err,"): ",ErrorDescription(err));
            }
         }

Pay attention for(int f=obj_total-1;f>=0;f--)


avatar
Moderator
28803
Rosh 2007.03.08 10:21 
I added a several arrows to picture for more complete explain.


Back to topics list  

To add comments, please log in or register