instant buy back or sellback depending on the nature of the close of the previous order. also the usual decimals conversation

 

Hello friends in coding:

I am new to the game of coding, and have been experimenting with monitoring trailing stops internal to the EA, and then closing whatever open order there is when the internal Trailing Stop calculation triggers and OrderClose. The attached code begins first by opening a position based on Moving Averages. Once a position is open, my stoploss value (entered externally) is monitored as compared with the updated Ask or Bid as may be appropriate to the Sell and Buy positions respectively. Anyway, it seems to work.


Two questions, please. And if you care to give me the code snippets, I would be most grateful.


First, how to account for the fact that the buy is in five decimals, but OrderOpenPrice returns only 4 decimals. NormalizeDouble function does not seem to repair this. Yes, I can Print with the DoubletoStr function, but I can no longer use that value to compare to other double values, since an integer or double cannot be compared to a string. So, let's say my stoploss (which I am also calling my trailing stoploss) is 45 ticks (4.5 pips). For the moment, let's not consider OrderModify, because I want to calculate internally. Currently, when the stoploss of 45 is compared to the OrderOpenPrice, the stoploss is rounded, and so my trailing stop calculation in the code below is rounded. When all is said and done, when it's time to trigger an OrderClose at market, the trigger is usually NOT at my 45 ticks, but some larger number due to the rounding problem. Given that I have experimented with NormalizeDouble and DoubleToStr as indicated above, how can I have the EA calculate to the fifth? Please provide languaging if you have a solution. Does MT5 solve this?


Secondly, let's say that once my first ever trade is closed, that instead of doing the Moving Average calculation, that I want to immediately get right back in with the identical closing trade (I am experimenting...this may not make logical sense, but I need to know how to do it). For example, once my trigger hit to close an open buy with a sell, and OrderClose sell went through, I would immediately want to come back in with a OrderSend SELL. How to do this? I experimented with closing the order with two lots (well not closing it, but OrderSend(ing) 2 lots), but where I thought one lot would match up with my buy position and close it out, instead I now had One Lot Long, and Two Lots Short . So I think the question is this - is there a function that can be called upon that queries what the last know close was? And then from that query, an identical OrderOpen could be launched. Once again, if you could provide the code snippet, I would be most appreciative. Something like if previous Order Close was a sell order, OrdeOpen Sell. If the previous Order Close was a buy order, the OrderOpen Buy.


Thanks for whatever help anyone may provide...


//+------------------------------------------------------------------+
//| Stoploss adjustment test.mq4 |
//| Andre |
//| nolink |
//+------------------------------------------------------------------+
#property copyright "Andre"
#property link "nolink"

extern double Lots=0.1;
extern double StopLoss=50;
extern int Slip=0;//slippage
extern double MovingPeriod= 12;
extern double MovingShift= 6;

//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----

//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
return(0);
}




//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
static double HighestAskSinceEntryLONG;
static double LowestBidSinceEntrySHORT;
int total;
int i;
int TakeProfit;
total = OrdersTotal();
if (total<1)
{
double ma;
int res;
//---- go trading only for first ticks of new bar
if(Volume[0]>1) return;
//---- get Moving Average
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---- sell conditions
if(Open[1]>ma && Close[1]<ma)
{
res=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slip,0,0,"",12345,0,Red);
if (res>0)
{
if(OrderSelect(res,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened from MA calc : ",OrderOpenPrice());
LowestBidSinceEntrySHORT=OrderOpenPrice();
Print ("LowestBidSinceEntrySHORT = ",LowestBidSinceEntrySHORT," Initial trailing stop price is : ", (LowestBidSinceEntrySHORT + StopLoss*Point));
return(0);
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
//---- buy conditions
if(Open[1]<ma && Close[1]>ma)
{
res=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slip,0,0,"",12345,0,Blue);
if (res>0)
{
if(OrderSelect(res,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened from REACTION LOW : ",OrderOpenPrice());
HighestAskSinceEntryLONG=OrderOpenPrice();
Print ("HighestAskSinceEntryLONG = ",HighestAskSinceEntryLONG," Initial trailing stop price is : ", (HighestAskSinceEntryLONG - StopLoss*Point));
return(0);
}
else Print("Error opening SELL order : ",GetLastError());
return(0);
}
}
if (total>0)
{
for(i = 0; i < OrdersTotal(); i++)
{
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if ( OrderType() == OP_BUY )//buy order checking on conditions
{
if (HighestAskSinceEntryLONG - StopLoss*Point > Bid)//Has the trailing stop#stop loss combo been triggered?
{
OrderClose (OrderTicket( ), Lots, Bid, Slip, Violet);
return(0);
}
if (Ask>HighestAskSinceEntryLONG)//Does the trailing stop#stop loss need to be adjusted?
{
HighestAskSinceEntryLONG=Ask;
Print ("Updated HighestAskSinceEntryLONG = ",HighestAskSinceEntryLONG," Updated trailing stop price is : ", (HighestAskSinceEntryLONG - StopLoss*Point));
return(0);
}
}
if ( OrderType() == OP_SELL )
{
if (LowestBidSinceEntrySHORT + StopLoss*Point < Ask)//Has the trailing stop#stop loss combo been triggered?
{
OrderClose (OrderTicket( ), Lots, Ask, Slip, Violet);
return(0);
}
if (Bid<LowestBidSinceEntrySHORT)//Does the trailing stop#stop loss need to be adjusted?
{
LowestBidSinceEntrySHORT=Bid;
Print ("Updated LowestBidSinceEntrySHORT = ",LowestBidSinceEntrySHORT," Updated trailing stop price is : ", (LowestBidSinceEntrySHORT + StopLoss*Point));
return(0);
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+

 
andrenogues:

[...] but OrderOpenPrice returns only 4 decimals. [...]

It doesn't. With a 5 digit broker, it returns open price with 5 digits (just as expected).

[...] is there a function that can be called upon that queries what the last know close was? [...]

No. You need to loop on all orders in the history pool and search for the one with the latest OrderCloseTime().

 
gordon:

It doesn't. With a 5 digit broker, it returns open price with 5 digits (just as expected).

No. You need to loop on all orders in the history pool and search for the one with the latest OrderCloseTime().



Hi Gordon, thanks for the reply. If you don't mind, please help me with my own logic here. I am using the demo Alpari account. When an order is executed, indeed I see that the order was opened at 1.12345, but when I write the statement

Print ("Order opened at : ",OrderOpenPrice());

The return value is only printed to four decimals (1.1234). And then my updated HighestAskSinceEntryLONG, or LowestBidSinceEntrySHORT are all four decimal values when they are printed to expert journal output. I know I could put:

Print ("Order opened at : ",DoubleToStr(OrderOpenPrice(),5)); 

and I would see a printout of all five decimals positions, but why then are my calculations of moving High and Low Bids and Asks in four decimals? Can I trust that the "Hidden" calculations are happening in five decimal places if I am using a five decimal broker?


Notice I used the source button! Now I know...


Thanks

 
You can never trust any calculation where double is involved. So never make a == compare with a double value.. you can easily proof that with:
Alert( (18.9 * 10) == 189)

You can normalize all internal values with the NormalizeDouble function, but this is not needed.

Internally you are always calculating with maximum double precision.

 
As zzuengg says, your problem is with precision of float calculations... Please read this: Working with Doubles in MQL4. This has been discussed many times so I suggest u search for more info.