0% found this document useful (0 votes)
247 views

OrderSendReliable mq4

Configuração de ordem binary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
247 views

OrderSendReliable mq4

Configuração de ordem binary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 15

//===========================================================================

// OrderReliable.mqh
//
// A library for MT4 expert advisors, intended to give more
// reliable order handling. This is under development.
//
// Instructions:
//
// Put this file in the experts/include directory.
// Include the line
// #include <OrderReliable_V?_?_?.mqh>
//
// in the beginning of your EA with the question marks replaced by
// the actual version number and file name of the library, i.e.
// this file.
//
// YOU MUST EDIT THE EA MANUALLY IN ORDER TO USE THIS LIBRARY,
// BY BOTH SPECIFYING THE INCLUDE FILE AND THEN MODIFYING THE EA
// CODE TO USE THE FUNCTIONS. In particular you must change, in the EA,
// OrderSend() commands to OrderSendReliable() and OrderModify() commands
// to OrderModifyReliable(), or any others which are appropriate.
//
// DO NOT COMPILE THIS FILE ON ITS OWN. It is meaningless. You only
// compile your "main" EA.
//
//===========================================================================
// Version: 0.2.4
// Contents:
//
// OrderSendReliable()
// This is intended to be a drop-in replacement for OrderSend() which,
one hopes
// is more resistant to various forms of errors prevalent with
MetaTrader.
//
// OrderModifyReliable
// A replacement for OrderModify with more error handling, similar to
// OrderSendReliable()
//
// OrderModifyReliableSymbol()
// Adds a "symbol" field to OrderModifyReliable (not drop in any more)
// so that it can fix problems with stops/take profits which are
// too close to market, as well as normalization problems.
//
// OrderReliableLastErr()
// Returns the last error seen by an Order*Reliable() call.
// NOTE: GetLastError() WILL NOT WORK to return the error
// after a call. This is a flaw in Metatrader design, in that
// GetLastError() also clears it. Hence in this way
// this library cannot be a total drop-in replacement.
//
//===========================================================================
// History:
// 2006-07-14: ERR_TRADE_TIMEOUT now a retryable error for modify 0.2.4
// only. Unclear about what to do for send.
// Adds OrderReliableLastErr()
//
// 2006-06-07: Version number now in log comments. Docs updated. 0.2.3
// OP_BUYLIMIT/OP_SELLLIMIT added. Increase retry time
// 2006-06-07: Fixed int/bool type mismatch compiler ignored 0.2.2
// 2006-06-06: Returns success if modification is redundant 0.2.1
// 2006-06-06: Added OrderModifyReliable 0.2.0
// 2006-06-05: Fixed idiotic typographical bug. 0.1.2
// 2006-06-05: Added ERR_TRADE_CONTEXT_BUSY to retryable errors. 0.1.1
// 2006-05-29: Created. Only OrderSendReliable() implemented 0.1
//
// LICENSING: This is free, open source software, licensed under
// Version 2 of the GNU General Public License (GPL).
//
// In particular, this means that distribution of this software in a binary format,
// e.g. as compiled in as part of a .ex4, must be
// accompanied by the non-obfuscated source code of both this file, AND the
// .mq4 source files which it is compiled with, or you must make such files
available at
// no charge to binary recipients. If you do not agree with such terms
// you must not use this code. Detailed terms of the GPL are widely
// available on the Internet. The Library GPL (LGPL) was intentionally not used,
// therefore the source code of files which link to this are subject to
// terms of the GPL if binaries made from them are publicly distributed or sold.
//
// Copyright (2006), Matthew Kennel
//===========================================================================

//===========================================================================
// OrderSendReliable()
//
/* This is intended to be a drop-in replacement for OrderSend() which, one
hopes
is more resistant to various forms of errors prevalent with MetaTrader.

syntax:

int OrderSendReliable(string symbol, int cmd, double volume, double price,


int slippage, double stoploss, double takeprofit,
string comment, int magic, datetime expiration =
0, color arrow_color = CLR_NONE) //

returns: ticket number or -1 under some error conditions.

Features:
* re-trying under some error conditions, sleeping
a random time defined by an exponential probability distribution.
* automatic normalization of Digits
* automatically makes sure that stop levels are more than
the minimum stop distance, as given by the server.
* automatically converts limit orders to market orders
when the limit orders are rejected by the server for being
to close to market.
* displays various error messages on the log for debugging.

Matt Kennel, [email protected] 2006-05-28


*/

//===========================================================================
#include <stdlib.mqh>
#include <stderror.mqh>
string OrderReliableVersion = "V0_2_3";

int retry_attempts = 10;


double sleep_time = 4.0, sleep_maximum = 25.0; // in seconds

string OrderReliable_Fname = "OrderReliable fname unset";

static int _OR_err = 0; //


//Matt's O-R stuff
int O_R_Setting_max_retries = 10;
double O_R_Setting_sleep_time = 4.0; /* seconds */
double O_R_Setting_sleep_max = 15.0; /* seconds */

int OrderSendReliable(string symbol, int cmd, double volume, double price,


int slippage, double stoploss, double takeprofit,
string comment, int magic, datetime expiration =
0, color arrow_color = CLR_NONE) {

//
// check basic conditions see if trade is possible.
//
OrderReliable_Fname = "OrderSendReliable";
OrderReliablePrint(" attempted "+OrderReliable_CommandString(cmd)+" "+volume+"
lots @"+price+" sl:"+stoploss+" tp:"+takeprofit);
if (!IsConnected()) {
OrderReliablePrint("error: IsConnected() == false");
_OR_err = ERR_NO_CONNECTION;
return(-1);
}
if (IsStopped()) {
OrderReliablePrint("error: IsStopped() == true");
_OR_err = ERR_COMMON_ERROR;
return(-1);
}
int cnt = 0;
while(!IsTradeAllowed() && cnt < retry_attempts) {
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
cnt++;
}
if (!IsTradeAllowed()) {
OrderReliablePrint("error: no operation possible because
IsTradeAllowed()==false, even after retries.");
_OR_err = ERR_TRADE_CONTEXT_BUSY;

return(-1);
}

// let's normalize all price/stoploss/takeprofit to the proper # of digits.


int digits = MarketInfo(symbol,MODE_DIGITS);
if (digits > 0) {
price = NormalizeDouble(price,digits);
stoploss = NormalizeDouble(stoploss,digits);
takeprofit = NormalizeDouble(takeprofit,digits);
}
if (stoploss != 0) OrderReliable_EnsureValidStop(symbol,price,stoploss);

int err = GetLastError(); // so we clear the global variable.


err = 0;
_OR_err = 0;
bool exit_loop = false;
bool limit_to_market = false;
// limit/stop order.
int ticket=-1;

if ((cmd == OP_BUYSTOP) || (cmd == OP_SELLSTOP) || (cmd == OP_BUYLIMIT) || (cmd


== OP_SELLLIMIT)) {
cnt = 0;
while (!exit_loop) {
if (IsTradeAllowed()) {
ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss,
takeprofit, comment, magic, expiration, arrow_color);
err = GetLastError();
_OR_err = err;
} else {
cnt++;
}
switch (err) {
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
cnt++; // a retryable error
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue; // we can apparently retry immediately according to MT
docs.
case ERR_INVALID_STOPS:
double servers_min_stop =
MarketInfo(symbol,MODE_STOPLEVEL)*MarketInfo(symbol,MODE_POINT);
if (cmd == OP_BUYSTOP) {
if (MathAbs(Ask - price) <= servers_min_stop)
// we are too close to put in a limit/stop order so go to market.
limit_to_market = true;
} else if (cmd == OP_SELLSTOP) {
if (MathAbs(Bid - price) <= servers_min_stop)
limit_to_market = true;
}
exit_loop = true;
break;
default:
// an apparently serious error.
exit_loop = true;
break;
} // end switch

if (cnt > retry_attempts) exit_loop = true;


if (exit_loop) {
if (err != ERR_NO_ERROR) {
OrderReliablePrint("non-retryable error: "
+OrderReliableErrTxt(err));
}
if (cnt > retry_attempts) {
OrderReliablePrint("retry attempts maxed at "+retry_attempts);
}
}
if (!exit_loop) {
OrderReliablePrint("retryable error ("+cnt+"/"+retry_attempts+"): " +
OrderReliableErrTxt(err));
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
RefreshRates();
}
}
// we have now exited from loop.
if (err == ERR_NO_ERROR) {
OrderReliablePrint("apparently successful OP_BUYSTOP or OP_SELLSTOP order
placed, details follow.");
OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
OrderPrint();
return(ticket); // SUCCESS!
}
if (!limit_to_market) {
OrderReliablePrint("failed to execute stop or limit order after "+cnt+"
retries");
OrderReliablePrint("failed trade: " + OrderReliable_CommandString(cmd)+"
"+symbol+"@"+price+" tp@"+takeprofit+" sl@"+stoploss);
OrderReliablePrint("last error: "+OrderReliableErrTxt(err));
return(-1);
}
} // end

if (limit_to_market) {
OrderReliablePrint("going from limit order to market order because market is
too close.");
if ((cmd == OP_BUYSTOP) || (cmd == OP_BUYLIMIT)) {
cmd = OP_BUY;
price = Ask;
} else if ((cmd == OP_SELLSTOP) || (cmd == OP_SELLLIMIT)) {
cmd = OP_SELL;
price = Bid;
}
}

// we now have a market order.


err = GetLastError(); // so we clear the global variable.
err = 0;
_OR_err = 0;
ticket=-1;

if ((cmd == OP_BUY) || (cmd == OP_SELL)) {


cnt = 0;
while (!exit_loop) {
if (IsTradeAllowed()) {
ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss,
takeprofit, comment, magic, expiration, arrow_color);
err = GetLastError();
_OR_err = err;
} else {
cnt++;
}
switch (err) {
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
cnt++; // a retryable error
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue; // we can apparently retry immediately according to MT
docs.
default:
// an apparently serious, unretryable error.
exit_loop = true;
break;
} // end switch

if (cnt > retry_attempts) exit_loop = true;


if (!exit_loop) {
OrderReliablePrint("retryable error ("+cnt+"/"+retry_attempts+"): " +
OrderReliableErrTxt(err));
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
RefreshRates();
}
if (exit_loop) {
if (err != ERR_NO_ERROR) {
OrderReliablePrint("non-retryable error: "
+OrderReliableErrTxt(err));
}
if (cnt > retry_attempts) {
OrderReliablePrint("retry attempts maxed at "+retry_attempts);
}
}
}
// we have now exited from loop.
if (err == ERR_NO_ERROR) {
OrderReliablePrint("apparently successful OP_BUY or OP_SELL order placed,
details follow.");
O_R_CheckForHistory(ticket);
OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
OrderPrint();
return(ticket); // SUCCESS!
}
OrderReliablePrint("failed to execute OP_BUY/OP_SELL, after "+cnt+"
retries");
OrderReliablePrint("failed trade: " + OrderReliable_CommandString(cmd)+"
"+symbol+"@"+price+" tp@"+takeprofit+" sl@"+stoploss);
OrderReliablePrint("last error: "+OrderReliableErrTxt(err));
return(-1);
}
} // end

bool OrderModifyReliable(int ticket, double price, double stoploss, double


takeprofit, datetime expiration, color arrow_color=CLR_NONE) {
// Replacement for OrderModifyReliable
OrderReliable_Fname = "OrderModifyReliable";

OrderReliablePrint(" attempted modify of #"+ticket+" price:"+price+"


sl:"+stoploss+" tp:"+takeprofit);

if (!IsConnected()) {
OrderReliablePrint("error: IsConnected() == false");
_OR_err = ERR_NO_CONNECTION;
return(false);
}
if (IsStopped()) {
OrderReliablePrint("error: IsStopped() == true");
return(false);
}
int cnt = 0;
while(!IsTradeAllowed() && cnt < retry_attempts) {
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
cnt++;
}
if (!IsTradeAllowed()) {
OrderReliablePrint("error: no operation possible because
IsTradeAllowed()==false, even after retries.");
_OR_err = ERR_TRADE_CONTEXT_BUSY;
return(false);
}

if (false) {
// This section is 'nulled out', because
// it would have to involve an 'OrderSelect()' to obtain
// the symbol string, and that would change the global context of the
// existing OrderSelect, and hence would not be a drop-in replacement
// for OrderModify().
//
// See OrderModifyReliableSymbol() where the user passes in the Symbol
// manually.

OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
string symbol = OrderSymbol();
int digits = MarketInfo(symbol,MODE_DIGITS);
if (digits > 0) {
price = NormalizeDouble(price,digits);
stoploss = NormalizeDouble(stoploss,digits);
takeprofit = NormalizeDouble(takeprofit,digits);
}
if (stoploss != 0) OrderReliable_EnsureValidStop(symbol,price,stoploss);
}
int err = GetLastError(); // so we clear the global variable.
err = 0;
_OR_err = 0;
bool exit_loop = false;
cnt = 0;
bool result = false;

while (!exit_loop) {
if (IsTradeAllowed()) {
result = OrderModify(ticket,price, stoploss, takeprofit, expiration,
arrow_color);
err = GetLastError();
_OR_err = err;
} else {
cnt++;
}
if (result == true) {
exit_loop = true;
}
switch (err) {
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_NO_RESULT:
// modification without changing a parameter.
// if you get this then you may want to change the code.
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT: // for modify this is a retryable error, I hope.
cnt++; // a retryable error
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue; // we can apparently retry immediately according to MT docs.
default:
// an apparently serious, unretryable error.
exit_loop = true;
break;
} // end switch

if (cnt > retry_attempts) exit_loop = true;


if (!exit_loop) {
OrderReliablePrint("retryable error ("+cnt+"/"+retry_attempts+"): " +
OrderReliableErrTxt(err));
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
RefreshRates();
}
if (exit_loop) {
if ((err != ERR_NO_ERROR) && (err != ERR_NO_RESULT)) {
OrderReliablePrint("non-retryable error: " +OrderReliableErrTxt(err));
}
if (cnt > retry_attempts) {
OrderReliablePrint("retry attempts maxed at "+retry_attempts);
}
}
}
// we have now exited from loop.
if ((result == true) || (err == ERR_NO_ERROR)) {
OrderReliablePrint("apparently successful modification order, updated trade
details follow.");
OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
OrderPrint();
return(true); // SUCCESS!
}
if (err == ERR_NO_RESULT) {
OrderReliablePrint("Server reported modify order did not actually change
parameters.");
OrderReliablePrint("redundant modification: " +ticket+" "+symbol+"@"+price+"
tp@"+takeprofit+" sl@"+stoploss);
OrderReliablePrint("Suggest modifying code logic to avoid.");
return(true);
}
OrderReliablePrint("failed to execute modify after "+cnt+" retries");
OrderReliablePrint("failed modification: " +ticket+" "+symbol+"@"+price+"
tp@"+takeprofit+" sl@"+stoploss);
OrderReliablePrint("last error: "+OrderReliableErrTxt(err));
return(false);

bool OrderModifyReliableSymbol(string symbol, int ticket, double price, double


stoploss, double takeprofit, datetime expiration, color arrow_color=CLR_NONE) {
// This has the same calling sequence as OrderModify() except that the user must
provide the symbol.
// This function will then be able to ensure proper normalization and stop levels.

int digits = MarketInfo(symbol,MODE_DIGITS);


if (digits > 0) {
price = NormalizeDouble(price,digits);
stoploss = NormalizeDouble(stoploss,digits);
takeprofit = NormalizeDouble(takeprofit,digits);
}
if (stoploss != 0) OrderReliable_EnsureValidStop(symbol,price,stoploss);

return(OrderModifyReliable(ticket,price,stoploss,takeprofit,expiration,arrow_color)
);

int OrderReliableLastErr() {
return (_OR_err);
}
//===========================================================================

//===========================================================================
// Utility Functions
//===========================================================================

string OrderReliableErrTxt(int err) {


return (""+err+":"+ErrorDescription(err));
}

void OrderReliablePrint(string s) {
// Print to log prepended with stuff;
Print(OrderReliable_Fname+" "+OrderReliableVersion+":"+s);
}

void OrderReliable_EnsureValidStop(string symbol, double price, double& sl) {


// adjust stop loss so that it is legal.
if (sl == 0) return;

double servers_min_stop =
MarketInfo(symbol,MODE_STOPLEVEL)*MarketInfo(symbol,MODE_POINT);

if (MathAbs(price-sl) <= servers_min_stop) {


// we have to adjust the stop.
if (price > sl) { // we are buying
sl = price - servers_min_stop;
} else if (price < sl) {
sl = price + servers_min_stop;
} else {
OrderReliablePrint("EnsureValidStop: error, passed in price == sl, cannot
adjust");
}
sl = NormalizeDouble(sl,MarketInfo(symbol,MODE_DIGITS));
}
}

string OrderReliable_CommandString(int cmd) {


if (cmd == OP_BUY) {
return("OP_BUY");
}
if (cmd == OP_SELL) {
return("OP_SELL");
}
if (cmd == OP_BUYSTOP) {
return("OP_BUYSTOP");
}
if (cmd == OP_SELLSTOP) {
return("OP_SELLSTOP");
}
if (cmd == OP_BUYLIMIT) {
return("OP_BUYLIMIT");
}
if (cmd == OP_SELLLIMIT) {
return("OP_SELLLIMIT");
}
return("(CMD=="+cmd+")");

}
void OrderReliable_SleepRandomTime(double mean_time, double max_time) {
// This sleeps a random amount of time defined by
// an exponential probability distribution. The mean time, in Seconds
// is given in 'mean_time'
// This is the back-off strategy used by Ethernet. This will
// quantize in tenths of seconds, so don't call this with a too
// small a number. This returns immediately if we are backtesting
// and does not sleep.
//
// Matt Kennel [email protected].
//
if (IsTesting()) return; // return immediately if backtesting.

double tenths = MathCeil(mean_time / 0.1);


if (tenths <= 0) return;

int maxtenths = MathRound(max_time/0.1);


double p = 1.0 - 1.0/tenths;

Sleep(1000); // one tenth of a second


for(int i=0; i<maxtenths; i++) {
if (MathRand() > p*32768) break;
// MathRand() returns in 0..32767
Sleep(1000);
}
}

//=============================================================================
// OrderCloseReliable()
//
// This is intended to be a drop-in replacement for OrderClose() which,
// one hopes, is more resistant to various forms of errors prevalent
// with MetaTrader.
//
// RETURN VALUE:
//
// TRUE if successful, FALSE otherwise
//
//
// FEATURES:
//
// * Re-trying under some error conditions, sleeping a random
// time defined by an exponential probability distribution.
//
// * Displays various error messages on the log for debugging.
//
//
// Derk Wehler, [email protected] 2006-07-19
//
//=============================================================================
bool OrderCloseReliable(int ticket, double lots, double price,
int slippage, color arrow_color = CLR_NONE)
{
OrderReliable_Fname = "OrderCloseReliable";

OrderReliablePrint(" attempted close of #" + ticket + " price:" + price +


" lots:" + lots + " slippage:" + slippage);

if (!IsConnected())
{
OrderReliablePrint("error: IsConnected() == false");
_OR_err = ERR_NO_CONNECTION;
return(false);
}

if (IsStopped())
{
OrderReliablePrint("error: IsStopped() == true");
return(false);
}

int cnt = 0;
while(!IsTradeAllowed() && cnt < retry_attempts)
{
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
cnt++;
}
if (!IsTradeAllowed())
{
OrderReliablePrint("error: no operation possible because
IsTradeAllowed()==false, even after retries.");
_OR_err = ERR_TRADE_CONTEXT_BUSY;
return(false);
}

int err = GetLastError(); // so we clear the global variable.


err = 0;
_OR_err = 0;
bool exit_loop = false;
cnt = 0;
bool result = false;

while (!exit_loop)
{
if (IsTradeAllowed())
{
result = OrderClose(ticket, lots, price, slippage, arrow_color);
err = GetLastError();
_OR_err = err;
}
else
cnt++;

if (result == true)
exit_loop = true;

switch (err)
{
case ERR_NO_ERROR:
exit_loop = true;
break;

case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT: // for modify this is a retryable
error, I hope.
cnt++; // a retryable error
break;

case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue; // we can apparently retry immediately
according to MT docs.

default:
// an apparently serious, unretryable error.
exit_loop = true;
break;
} // end switch

if (cnt > retry_attempts)


exit_loop = true;

if (!exit_loop)
{
OrderReliablePrint("retryable error (" + cnt + "/" +
retry_attempts +
"): " +
OrderReliableErrTxt(err));
OrderReliable_SleepRandomTime(sleep_time,sleep_maximum);
RefreshRates();
}

if (exit_loop)
{
if ((err != ERR_NO_ERROR) && (err != ERR_NO_RESULT))
OrderReliablePrint("non-retryable error: " +
OrderReliableErrTxt(err));

if (cnt > retry_attempts)


OrderReliablePrint("retry attempts maxed at " +
retry_attempts);
}
}

// we have now exited from loop.


if ((result == true) || (err == ERR_NO_ERROR))
{
OrderReliablePrint("apparently successful modification order, updated
trade details follow.");
OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
OrderPrint();
return(true); // SUCCESS!
}

OrderReliablePrint("failed to execute close after " + cnt + " retries");


OrderReliablePrint("failed close: Ticket #" + ticket + ", Price: " +
price + ", Slippage: " + slippage);
OrderReliablePrint("last error: " + OrderReliableErrTxt(err));

return(false);
}

bool O_R_CheckForHistory(int ticket)


{
//My thanks to Matt for this code. He also has the undying gratitude of all
users of my trading robots

int lastTicket = OrderTicket();

int cnt = 0;
int err = GetLastError(); // so we clear the global variable.
err = 0;
bool exit_loop = false;
bool success=false;
while (!exit_loop) {
/* loop through open trades */
int total=OrdersTotal();
for(int c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
if (cnt > 3) {
/* look through history too, as order may have opened and closed
immediately */
total=OrdersHistoryTotal();
for(c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
}

cnt = cnt+1;
if (cnt > O_R_Setting_max_retries) {
exit_loop = true;
}
if (!(success || exit_loop)) {
Print("Did not find #"+ticket+" in history, sleeping, then doing retry
#"+cnt);
O_R_Sleep(O_R_Setting_sleep_time, O_R_Setting_sleep_max);
}
}
// Select back the prior ticket num in case caller was using it.
if (lastTicket >= 0) {
OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
}
if (!success) {
Print("Never found #"+ticket+" in history! crap!");
}
return(success);
}//End bool O_R_CheckForHistory(int ticket)

//=============================================================================
// O_R_Sleep()
//
// This sleeps a random amount of time defined by an exponential
// probability distribution. The mean time, in Seconds is given
// in 'mean_time'.
// This returns immediately if we are backtesting
// and does not sleep.
//
//=============================================================================
void O_R_Sleep(double mean_time, double max_time)
{
if (IsTesting()) {
return; // return immediately if backtesting.
}

double p = (MathRand()+1) / 32768.0;


double t = -MathLog(p)*mean_time;
t = MathMin(t,max_time);
int ms = t*1000;
if (ms < 10) {
ms=10;
}
Sleep(ms);
}//End void O_R_Sleep(double mean_time, double max_time)

You might also like