Intraday trading is a bug. Daily on open bar backtest

//+------------------------------------------------------------------+
//| Strategy 3.94.402 EA GBPUSD D1 2010
//|
//| Generated by StrategyQuant X Build 128 at 06/01/2020 11:24
//|
//| This EA uses 3rd party library OrderReliable for industry-strength
//| order handling. OrderReliable library is normally distributed under
//| GPL license. Its author provided it under MIT license limited to
//| usage only within strategies generated by StrategyQuant.
//|
//| This means that this library doesn't restrict you to use your EA
//| generated by SQ comercially in any way you want.
//| But if you'll use any method from OrderReliable library outside
//| of this EA in your own EAs or projects, its use will be governed
//| by its standard GPL license.
//|
//| Scroll to the very bottom of this source code for the full text
//| of OrderReliable license.
//+------------------------------------------------------------------+

#property copyright "StrategyQuant.com"
#property link "http://www.StrategyQuant.com"

#include
#include

const int SLPTTYPE_RANGE = 0;
const int SLPTTYPE_LEVEL = 1;

//+------------------------------------------------------------------+
// -- Variables
//+------------------------------------------------------------------+
extern string CustomComment = "Strategy 3.94.402";

extern int MagicNumber = 11111;
bool LongEntrySignal = false;
bool ShortEntrySignal = false;
bool LongExitSignal = false;
bool ShortExitSignal = false;
extern int RSIPeriod = 20;
extern int DeMarkerPeriod = 21;
extern int AvgVolumePeriod = 101;
extern int StochasticKPeriod = 199;
extern int StochasticDPeriod = 3;
extern int StochasticSlowing = 3;
extern int IchimokuTenkanPeriod = 9;
extern int IchimokuKijunPeriod = 180;
extern int IchimokuSenkouPeriod = 78;
extern int BBerPeriod = 10;
extern int BBBarOpensPeriod = 10;
extern int CCIPeriod = 40;
extern double PriceEntryMult = 2.5;
extern int BarsValid = 178;
extern int ExitAfterBars = 2;
extern int StopLoss = 30;
extern int Period = 50;
extern int BBWidthRatioPeriod = 79;
extern double PriceEntryMult2 = 0.1;
extern int BarsValid2 = 96;
extern int MoveSL2BE = 15;
extern int StopLoss2 = 10;
extern int TrailingStop = 70;
extern int BiggestRangePeriod = 10;

//+------------------------------------------------------------------+
// Money Management variables
//+------------------------------------------------------------------+
extern string smm = "----------- Money Management - Risk Fixed % Of Balance -----------";
extern double mmRiskPercent = 5.3;
extern int mmDecimals = 2;
extern double mmLotsIfNoMM = 1.0;
extern double mmMaxLots = 100;


//+------------------------------------------------------------------+
// Trading Options variables
//+------------------------------------------------------------------+

extern string seod = "----------- Exit At End Of Day -----------";
extern bool ExitAtEndOfDay = false;
extern string EODExitTime = "23:04";

extern string seof = "----------- Exit On Friday -----------";
extern bool ExitOnFriday = false;
extern string FridayExitTime = "20:40";

extern string sltr = "----------- Limit Time Range -----------";
extern bool LimitTimeRange = false;
extern string SignalTimeRangeFrom = "08:00";
extern string SignalTimeRangeTo = "16:00";
extern bool ExitAtEndOfRange = false;

extern string smtpd = "----------- Max Trades Per Day -----------";
extern int MaxTradesPerDay = 0;
extern string smmslpt = "----------- Min/Max SL/PT -----------";
extern int MinimumSL = 0; //Minimum SL in pips
extern int MinimumPT = 0; //Minimum PT in pips
extern int MaximumSL = 0; //Maximum SL in pips
extern int MaximumPT = 0; //Maximum PT in pips



extern string slts = "----------- Use Tick size from SQ (for CFDs) -----------";
// For exotic pairs (usually non forex CFDs) the default method of computing
// tick size in EA might not work correctly.
// By turning this on and specifying MainChartTickSizeSQ value you can let EA
// use the correct tick size
extern bool UseSQTickSize = false;
extern double MainChartTickSizeSQ = 1.0E-4;

//+------------------------------------------------------------------+
// OrderReliable library variables
//+------------------------------------------------------------------+
string OrderReliableVersion = "v36";
string OrderReliable_Fname = "OrderReliable (Function Name Not Set)";

int retry_attempts = 10000; // general retry attempts
int retry_attempts_bad_price = 3; // retry attempts if the error is bad price
double sleep_time = 2.0;
double sleep_maximum = 20.0;


int ErrorLevel = 3;

bool UseLimitToMarket = false;
bool UseForTesting = false;
bool AddSpreadToComment = false;

//+------------------------------------------------------------------+
// -- SQ internal variables
// add word "extern" in front of the variable you want
// to make configurable
//+------------------------------------------------------------------+
int sqMaxEntrySlippage = 5; //Max tolerated entry slippage in pips. Zero means unlimited slippage
int sqMaxCloseSlippage = 0; //Max tolerated close slippage in pips. Zero means unlimited slippage
bool autoCorrectMaxSlippage = true; //If set to true, it will automatically adjust max slippage according to symbol digits (*10 for 3 and 5 digit symbols)

//+------------------------------------------------------------------+
// Verbose mode values:
// 0 - don't print messages to log at all
// 1 - print messages to log only when trading (not when backtesting)
// 2 - print messages to log always
//+------------------------------------------------------------------+
int sqVerboseMode = 2;

extern bool sqDisplayInfoPanel = true;
extern bool ModifyInsteadOfReplacing = false;

extern int OpenBarDelay = 0; // open bar delay in minutes
// it can be used for Daily strategies to trigger trading a few minutes later -
// because brokers sometimes have technical delay after midnight and we have to postpone order execution

int sqLabelCorner = 1;
int sqOffsetHorizontal = 5;
int sqOffsetVertical = 20;
color sqLabelColor = White;

datetime _sqLastOpenBarTime = 0;
bool _sqIsBarOpen = false;
double gPointCoef = 0;
int _ticket;
bool cond[100];

double initialBalance = 0;

bool openingOrdersAllowed = true;
bool firstCall = true;

////////
//+------------------------------------------------------------------+
// -- Functions
//+------------------------------------------------------------------+

void OnTick() {

sqInitStart();

sqManageOrders(MagicNumber);

openingOrdersAllowed = sqHandleTradingOptions();

//------------------------
// Rule: Trading signals
//------------------------
if (sqIsBarOpen()) {
// init signals only on bar open
LongEntrySignal = (((sqIsFalling("sqWeekly(NULL,0, Close, 2)", 3, true, 1))
&& ((sqRSI(NULL,0, RSIPeriod, PRICE_WEIGHTED, 1+1) > sqDeMarker(NULL,0, DeMarkerPeriod, 1+1)) && (sqRSI(NULL,0, RSIPeriod, PRICE_WEIGHTED, 1) < sqDeMarker(NULL,0, DeMarkerPeriod, 1))))
&& (sqIsFalling("sqAvgVolume(NULL,0, AvgVolumePeriod, 3)", 2, true, 2)));

ShortEntrySignal = (TimeMinute(TimeCurrent()) <= sqStochastic(NULL,0, StochasticKPeriod, StochasticDPeriod, StochasticSlowing, 0, 1, 1, 3));

LongExitSignal = ((sqMonthly(NULL,0, "Low", 2) < sqIchimoku(NULL,0, IchimokuTenkanPeriod, IchimokuKijunPeriod, IchimokuSenkouPeriod, 3, 3))
&& (sqBands(NULL,0, BBerPeriod, 2, 0, PRICE_CLOSE, 0, 1+1) sqCCI(NULL,0, CCIPeriod, PRICE_CLOSE, 2)));

}



//------------------------
// Rule: Long entry
//------------------------
if (sqIsBarOpen()
&& LongEntrySignal)
{
// Action #1
_ticket = sqOpenOrder(OP_BUYSTOP, "Current", sqMMRiskFixedBalancePct("Current",OP_BUYSTOP,(sqHighest("NULL",0, PRICE_TYPICAL, Period, 3) + (PriceEntryMult * sqBBWidthRatio(NULL,0, BBWidthRatioPeriod, 2.8, PRICE_WEIGHTED, 2))),sqGetSLLevel("Current", OP_BUYSTOP, (sqHighest("NULL",0, PRICE_TYPICAL, Period, 3) + (PriceEntryMult * sqBBWidthRatio(NULL,0, BBWidthRatioPeriod, 2.8, PRICE_WEIGHTED, 2))), 1, StopLoss),mmRiskPercent,mmDecimals,mmLotsIfNoMM,mmMaxLots), (sqHighest("NULL",0, PRICE_TYPICAL, Period, 3) + (PriceEntryMult * sqBBWidthRatio(NULL,0, BBWidthRatioPeriod, 2.8, PRICE_WEIGHTED, 2))), MagicNumber, "", 0, true, false, CLR_NONE);

if(_ticket > 0 && OrderSelect(_ticket, SELECT_BY_TICKET)) {
// set or initialize all order exit methods (SL, PT, Trailing Stop, Exit After Bars, etc.)
sqSetOrderExpiration(_ticket, BarsValid);

// StopLoss & ProfitTarget
sqSetSLandPT(_ticket, sqGetSLLevel("Current", OP_BUYSTOP, OrderOpenPrice(), 1, StopLoss), 0);

// ExitAfterBars initialization
sqSetGlobalVariable(_ticket, "ExitAfterBars", ExitAfterBars);
}



}


//------------------------
// Rule: Short entry
//------------------------
if (sqIsBarOpen()
&& (ShortEntrySignal
&& (!(LongEntrySignal))))
{
// Action #1
_ticket = sqOpenOrder(OP_SELLSTOP, "Current", sqMMRiskFixedBalancePct("Current",OP_SELLSTOP,(sqGetAsk("Current") - (PriceEntryMult2 * sqBiggestRange("NULL",0, BiggestRangePeriod, 3))),sqGetSLLevel("Current", OP_SELLSTOP, (sqGetAsk("Current") - (PriceEntryMult2 * sqBiggestRange("NULL",0, BiggestRangePeriod, 3))), 1, StopLoss2),mmRiskPercent,mmDecimals,mmLotsIfNoMM,mmMaxLots), (sqGetAsk("Current") - (PriceEntryMult2 * sqBiggestRange("NULL",0, BiggestRangePeriod, 3))), MagicNumber, "", 0, true, false, CLR_NONE);

if(_ticket > 0 && OrderSelect(_ticket, SELECT_BY_TICKET)) {
// set or initialize all order exit methods (SL, PT, Trailing Stop, Exit After Bars, etc.)
sqSetOrderExpiration(_ticket, BarsValid2);

// StopLoss & ProfitTarget
sqSetSLandPT(_ticket, sqGetSLLevel("Current", OP_SELLSTOP, OrderOpenPrice(), 1, StopLoss2), 0);
// MoveSL2BE initialization
sqSetGlobalVariable(_ticket, "MoveSL2BE", sqStringHash("MoveSL2BE"));
sqSetGlobalVariable(_ticket, "MoveSL2BEType", SLPTTYPE_RANGE);

// TrailingStop initialization
sqSetGlobalVariable(_ticket, "TrailingStop", sqStringHash("TrailingStop"));
sqSetGlobalVariable(_ticket, "TrailingStopType", SLPTTYPE_RANGE);
// ExitAfterBars initialization
sqSetGlobalVariable(_ticket, "ExitAfterBars", ExitAfterBars);
}



}


//------------------------
// Rule: Long exit
//------------------------
if (sqIsBarOpen()
&& ((LongExitSignal
&& (!(LongEntrySignal)))
&& sqMarketPositionIsLong(MagicNumber, "Any", "")))
{
// Action #1
sqClosePosition(OrderLots(), // size: SQ.Formulas.CloseSize.FullPosition
MagicNumber, // magic number
"Any", // symbol
1, // direction
"" // comment
);

}


//------------------------
// Rule: Short exit
//------------------------
if (sqIsBarOpen()
&& ((ShortExitSignal
&& (!(ShortEntrySignal)))
&& sqMarketPositionIsShort(MagicNumber, "Any", "")))
{
// Action #1
sqClosePosition(OrderLots(), // size: SQ.Formulas.CloseSize.FullPosition
MagicNumber, // magic number
"Any", // symbol
-1, // direction
"" // comment
);

}


return;
}

//+------------------------------------------------------------------+

int OnInit() {
VerboseLog("--------------------------------------------------------");
VerboseLog("Starting the EA");

gPointCoef = calculatePointCoef(Symbol());

VerboseLog("--------------------------------------------------------");

if(sqDisplayInfoPanel) {
sqInitInfoPanel();
}

SQTime = new CSQTime();

if(!IsTesting() && !IsOptimization()) {
initTimer();
}

initialBalance = AccountInfoDouble(ACCOUNT_BALANCE);

objExitAtEndOfDay = new CExitAtEndOfDay();
objExitOnFriday = new CExitOnFriday();
objLimitTimeRange = new CLimitTimeRange();
objMaxTradesPerDay = new CMaxTradesPerDay();
objMinMaxSLPT = new CMinMaxSLPT();


return(0);
}

//+------------------------------------------------------------------+

void OnDeinit(const int reason) {
sqDeinitInfoPanel();

delete SQTime;
delete objExitAtEndOfDay;
delete objExitOnFriday;
delete objLimitTimeRange;
delete objMaxTradesPerDay;
delete objMinMaxSLPT;

return;
}

//+------------------------------------------------------------------+

void initTimer(){
int period = 20 * 3600; //20 hours
period += MathRand() % (10 * 3600); //add another 0-10 hours randomly

if(!EventSetTimer(period)){
VerboseLog("Cannot set timer. Error code: ", GetLastError());
}
}

//+------------------------------------------------------------------+

void OnTimer(){
//clear unused variables
int deletedCount = 0;

VerboseLog("Clearing variables...");

for(int a=GlobalVariablesTotal() - 1; a>=0; a--){
string variableName = GlobalVariableName(a);

if(GlobalVariableCheck(variableName)){
int endPos = StringFind(variableName, "_");
if(endPos <= 0) continue;

int ticketNo = StrToInteger(StringSubstr(variableName, 0, endPos));

bool variableUsed = false;

for(int i=0; i < OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS) == true) {
if(OrderTicket() == ticketNo){
variableUsed = true;
break;
}
}
}

ResetLastError();

if(!variableUsed){
if(GlobalVariableDel(variableName)){
deletedCount++;
}
else {
VerboseLog("Cannot delete variable. Error code: ", GetLastError());
}
}
}
}

VerboseLog(IntegerToString(deletedCount), " variables cleared");
}

//+------------------------------------------------------------------+

bool sqHandleTradingOptions() {
bool continueWithBarUpdate = true;

if(!objExitAtEndOfDay.onBarUpdate()) continueWithBarUpdate = false;
if(!objExitOnFriday.onBarUpdate()) continueWithBarUpdate = false;
if(!objLimitTimeRange.onBarUpdate()) continueWithBarUpdate = false;
if(!objMaxTradesPerDay.onBarUpdate()) continueWithBarUpdate = false;
if(!objMinMaxSLPT.onBarUpdate()) continueWithBarUpdate = false;

return(continueWithBarUpdate);
}

//+------------------------------------------------------------------+

bool checkMagicNumber(int magicNo){
if(magicNo == MagicNumber){
return true;
}
return false;
}

//+------------------------------------------------------------------+

double sqGetMarketTickSize(string symbol){
symbol = correctSymbol(symbol);

if(symbol == Symbol()){
return MainChartTickSizeSQ;
}


return -1;
}

//+------------------------------------------------------------------+

double sqGetGlobalSL(string symbol, int orderType, double price) {
return(sqGetSLLevel(symbol, orderType, price, 1, 0));
}

//+------------------------------------------------------------------+

double sqGetGlobalPT(string symbol, int orderType, double price) {
return(sqGetPTLevel(symbol, orderType, price, 1, 0));
}

//+------------------------------------------------------------------+

double sqGetIndicatorByIdentification(string idHash, int shift) {
if(idHash == "sqWeekly(NULL,0, Close, 2)") {
return (sqWeekly(NULL,0, "Close", 2+shift));
}
if(idHash == "sqAvgVolume(NULL,0, AvgVolumePeriod, 3)") {
return (sqAvgVolume(NULL,0, AvgVolumePeriod, 3+shift));
}

return(0);
}


//+------------------------------------------------------------------+

double sqGetValueByIdentification(string idHash) {

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("StopLoss")) {
return (sqConvertToRealPips(OrderSymbol(), StopLoss));
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("MoveSL2BE")) {
return (sqConvertToRealPips(OrderSymbol(), MoveSL2BE));
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("0")) {
return (0);
}

if(idHash == sqStringHash("StopLoss2")) {
return (sqConvertToRealPips(OrderSymbol(), StopLoss2));
}

if(idHash == sqStringHash("TrailingStop")) {
return (sqConvertToRealPips(OrderSymbol(), TrailingStop));
}

if(idHash == sqStringHash("0")) {
return (0);
}

return(0);
}

//----------------------------------------------------------------------------

void sqManageOrders(int magicNumber) {
if(_sqIsBarOpen) {
for(int i=OrdersTotal()-1; i>=0; i--) {
if (OrderSelect(i,SELECT_BY_POS)==true) {
if(OrderMagicNumber() != magicNumber) {
continue;
}

int ticket = OrderTicket();

if(OrderType() == OP_BUY || OrderType() == OP_SELL) {
// handle Exit Methods only for live orders

sqManageSL2BE(ticket);
sqManageTrailingStop(ticket);
sqManageExitAfterXBars(ticket);
}

sqManageOrderExpiration(ticket);
}

if(OrdersTotal() <= 0) return;
}
}
}

//----------------------------------------------------------------------------

void sqResetGlobalVariablesForTicket(int ticket) {
sqSetGlobalVariable(ticket, "sqOrderExpiration", 0);
sqSetGlobalVariable(ticket, "sqOrderOpenTime", Time[0]);

sqSetGlobalVariable(ticket, "MoveSL2BE", 0);
sqSetGlobalVariable(ticket, "SL2BEAddPips", 0);
sqSetGlobalVariable(ticket, "TrailingStop", 0);
sqSetGlobalVariable(ticket, "TrailingActivation", 0);
sqSetGlobalVariable(ticket, "ExitAfterBars", 0);

}

//+------------------------------------------------------------------+

void sqInitStart() {
// changed recognition of bar open to support also range/renko charts
if(_sqLastOpenBarTime == 0) {
_sqLastOpenBarTime = Time[0];
_sqIsBarOpen = true;
}
else {
if(_sqLastOpenBarTime != Time[0]) {
bool processBarOpen = true;

if(OpenBarDelay > 0) {
// set bar to open after X minutes from real open
processBarOpen = false;

int diffInSeconds = TimeCurrent() - Time[0];
if(diffInSeconds >= OpenBarDelay * 60) {
processBarOpen = true;
}
}

if(processBarOpen) {
_sqIsBarOpen = true;
_sqLastOpenBarTime = Time[0];
}
}
else {
_sqIsBarOpen = false;
}
}

if(_sqIsBarOpen && Bars<30) {
Print("NOT ENOUGH DATA: Less Bars than 30");
return;
}

if(!IsTesting() && !IsOptimization()) {
sqTextFillOpens();
if(_sqIsBarOpen) {
sqTextFillTotals();
}
}
}

//+------------------------------------------------------------------+

bool sqIsBarOpen() {
return(_sqIsBarOpen);
}

//+------------------------------------------------------------------+

int sqGetOrderExpiration(int ticket) {
return (sqGetGlobalVariable(ticket, "sqOrderExpiration"));
}

//+------------------------------------------------------------------+

void sqSetOrderExpiration(int ticket, int bars) {
sqSetGlobalVariable(ticket, "sqOrderExpiration", bars);
}

//+------------------------------------------------------------------+

void sqManageOrderExpiration(int ticket) {
int tempValue = 0;
int barsOpen = 0;

// Stop/Limit Order Expiration
if(OrderType() != OP_BUY && OrderType() != OP_SELL) {
// handle only pending orders
tempValue = sqGetOrderExpiration(ticket);
if(tempValue > 0) {
barsOpen = sqGetOpenBarsForOrder(ticket, tempValue+10);
if(barsOpen >= tempValue) {
Verbose("Order with ticket: ", ticket, " expired");
sqDeletePendingOrder(ticket);
}
}
}
}

//----------------------------------------------------------------------------

double sqIndicatorHighest(int period, int nthValue, string indicatorIdentification) {
if(period > 1000) {
Alert("Period used for sqIndicatorHighest function is too high. Max value is 1000");
period = 1000;
}

if(nthValue < 0 || nthValue >= period) {
return(-1);
}

double indicatorValues[1000];
int i;

for(i=0; i<1000; i++) {
indicatorValues[i] = -2147483647;
}

for(i=0; i= period) {
return(-1);
}

return(indicatorValues[nthValue]);
}

//----------------------------------------------------------------------------

double sqIndicatorLowest(int period, int nthValue, string indicatorIdentification) {
if(period > 1000) {
Alert("Period used for sqIndicatorLowest function is too high. Max value is 1000");
period = 1000;
}

if(nthValue < 0 || nthValue >= period) {
return(-1);
}

double indicatorValues[1000];
int i;

for(i=0; i<1000; i++) {
indicatorValues[i] = 2147483647;
}

for(i=0; i= period) {
return(-1);
}

return(indicatorValues[nthValue]);
}

//----------------------------------------------------------------------------

double sqIndicatorAverage(int period, int maMethod, string indicatorIdentification) {
double indicatorValues[10000];

for(int i=0; i previousValue) {
atLeastOnce = true;
}

previousValue = currentValue;
}

if(atLeastOnce) {
return(true);
}

// indicator was not rising once
return(false);
}

//----------------------------------------------------------------------------

bool sqIsFalling(string indicatorIdentification, int bars, bool allowSameValues, int shift) {
bool atLeastOnce = false;

double previousValue = NormalizeDouble(sqGetIndicatorByIdentification(indicatorIdentification, bars+shift-1), 6);

for(int i=1; i previousValue) {
// indicator was rising
return(false);
}
if(currentValue == previousValue && allowSameValues == false) {
// indicator was the same, not allowed
return(false);
}
if(currentValue < previousValue) {
atLeastOnce = true;
}

previousValue = currentValue;
}

if(atLeastOnce) {
return(true);
}

// indicator was not falling once
return(false);
}

//+------------------------------------------------------------------+

void sqSetGlobalVariable(int ticket, string name, double value) {
GlobalVariableSet(ticket+"_"+name, value);
}

//+------------------------------------------------------------------+

double sqGetGlobalVariable(int ticket, string name) {
return (GlobalVariableGet(ticket+"_"+name));
}

//+------------------------------------------------------------------+

int sqStringHash(string str){
int i, h, k;
for (i=0; i0) {
FileSeek(handle,0,SEEK_END);
FileWrite(handle, TimeToStr(TimeCurrent()), " ", st1, st2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12);
FileClose(handle);
}
}

//+------------------------------------------------------------------+

bool sqSelectOrder(int magicNumber, string symbol, int direction, string comment, bool goFromNewest=true, bool skipPending=true, bool skipFilled=false) {
int cc = 0;
if(goFromNewest){
for (cc = OrdersTotal() - 1; cc >= 0; cc--) {
if(orderFits(cc, magicNumber, symbol, direction, comment, skipPending, skipFilled)){
return true;
}
}
}
else {
for (cc = 0; cc < OrdersTotal(); cc++) {
if(orderFits(cc, magicNumber, symbol, direction, comment, skipPending, skipFilled)){
return true;
}
}
}
return(false);
}

//+------------------------------------------------------------------+

bool orderFits(int index, int magicNumber, string symbol, int direction, string comment, bool skipPending=true, bool skipFilled=false){
if (OrderSelect(index, SELECT_BY_POS)) {
// skip pending orders
if(skipPending && (OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)) {
return false;
}
// skip filled orders
if(skipFilled && (OrderType() == OP_BUY || OrderType() == OP_SELL)) {
return false;
}

if(direction != 0) {
if(direction > 0 && (OrderType() != OP_BUY && OrderType() != OP_BUYSTOP && OrderType() != OP_BUYLIMIT)) return false;
if(direction < 0 && (OrderType() != OP_SELL && OrderType() != OP_SELLSTOP && OrderType() != OP_SELLLIMIT)) return false;
}

if(magicNumber != 0) {
if(!checkMagicNumber(OrderMagicNumber()) || OrderMagicNumber() != magicNumber) return false;
}

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) return false;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) return false;
}

// otherwise we found the order
return(true);
}
else return false;
}

//+------------------------------------------------------------------+

void sqCloseAllPositions(string symbol, int magicNumber, int direction, string comment) {
int count = 100; // maximum number of positions to close
int lastTicket = -1;

while(count > 0) {
count--;
if(!sqSelectOrder(magicNumber, symbol, direction, comment, false, false)) {
// no position found
break;
}

if(lastTicket == OrderTicket()) {
// trying to close the same position one more time, there must be some error
break;
}
lastTicket = OrderTicket();

if(OrderType() == OP_BUY || OrderType() == OP_SELL) {
sqClosePositionAtMarket(OrderLots());
} else {
sqDeletePendingOrder(OrderTicket());
}
}
}

//+------------------------------------------------------------------+

void sqCloseBestPosition(string symbol, int magicNumber, int direction, string comment) {
double maxPL = -100000000;
int ticket = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(OrderProfit() > maxPL) {
// found order with better profit
maxPL = OrderProfit();
ticket = OrderTicket();
Verbose("Better position found, ticket: ", ticket,", PL: ", maxPL);
}
}
}

if(ticket > 0) {
if(OrderSelect(ticket, SELECT_BY_TICKET)) {
sqClosePositionAtMarket(OrderLots());
}
}
}

//+------------------------------------------------------------------+

void sqCloseWorstPosition(string symbol, int magicNumber, int direction, string comment) {
double minPL = 100000000;
int ticket = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(OrderProfit() < minPL) {
// found order with worse profit
minPL = OrderProfit();
ticket = OrderTicket();
Verbose("Worse position found, ticket: ", ticket,", PL: ", minPL);
}
}
}

if(ticket > 0) {
if(OrderSelect(ticket, SELECT_BY_TICKET)) {
sqClosePositionAtMarket(OrderLots());
}
}
}

//+------------------------------------------------------------------+

int sqGetMarketPosition(string symbol, int magicNumber, string comment) {
if(sqSelectOrder(magicNumber, symbol, 0, comment, false)) {
if(OrderType() == OP_BUY) {
return(1);
} else {
return(-1);
}
}
return(0);
}

//+------------------------------------------------------------------+

bool sqMarketPositionIsShort(int magicNo, string symbol, string comment){
return sqSelectOrder(magicNo, symbol, -1, comment, false);
}

//+------------------------------------------------------------------+

bool sqMarketPositionIsNotShort(int magicNo, string symbol, string comment){
if(sqSelectOrder(magicNo, symbol, 1, comment, false)) {
return false;
}

return true;
}

//+------------------------------------------------------------------+

bool sqMarketPositionIsLong(int magicNo, string symbol, string comment){
return sqSelectOrder(magicNo, symbol, 1, comment, false);
}

//+------------------------------------------------------------------+

bool sqMarketPositionIsNotLong(int magicNo, string symbol, string comment){
if(sqSelectOrder(magicNo, symbol, 1, comment, false)) {
return false;
}

return true;
}

//+------------------------------------------------------------------+

bool sqMarketPositionIsFlat(int magicNo, string symbol, string comment){
return sqGetMarketPosition(symbol, magicNo, comment) == 0;
}

//+------------------------------------------------------------------+

double sqGetOrderOpenPrice(string symbol, int magicNumber, int direction, string comment) {
if(sqSelectOrder(magicNumber, symbol, direction, comment, false)) {
return(OrderOpenPrice());
}
return(-1);
}

//+------------------------------------------------------------------+

double sqGetOrderStopLoss(string symbol, int magicNumber, int direction, string comment) {
if(sqSelectOrder(magicNumber, symbol, direction, comment, false)) {
return(OrderStopLoss());
}
return(-1);
}

//+------------------------------------------------------------------+

double sqGetOrderProfitTarget(string symbol, int magicNumber, int direction, string comment) {
if(sqSelectOrder(magicNumber, symbol, direction, comment, false)) {
return(OrderTakeProfit());
}
return(-1);
}

//+------------------------------------------------------------------+

double sqGetMarketPositionSize(string symbol, int magicNumber, int direction, string comment) {
double lots = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

lots += OrderLots();
}
}

return(lots);
}

//+------------------------------------------------------------------+

double sqGetOpenPL(string symbol, int magicNumber, int direction, string comment) {
double pl = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

pl += OrderProfit();
}
}

return(pl);
}

//+------------------------------------------------------------------+

double sqGetOpenPLInPips(string symbol, int magicNumber, int direction, string comment) {
double pl = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

if(OrderType() == OP_BUY) {
pl += sqGetBid(OrderSymbol()) - OrderOpenPrice();
} else {
pl += OrderOpenPrice() - sqGetAsk(OrderSymbol());
}
}
}

return(sqConvertToPips(OrderSymbol(), pl));
}

//+------------------------------------------------------------------+

int sqGetClosedPLInPips(string symbol, int magicNumber, int direction, string comment, int shift) {
int index = 0;

for(int i=OrdersHistoryTotal(); i>=0; i--) {
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true ) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

if(index == shift) {
if(OrderType() == OP_BUY) {
return(sqConvertToPips(OrderSymbol(), OrderClosePrice() - OrderOpenPrice()));
} else {
return(sqConvertToPips(OrderSymbol(), OrderOpenPrice() - OrderClosePrice()));
}
}

index++;
}
}

return(0);
}

//+------------------------------------------------------------------+

int sqGetClosedPLInMoney(string symbol, int magicNumber, int direction, string comment, int shift) {
int index = 0;

for(int i=OrdersHistoryTotal(); i>=0; i--) {
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true ) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

if(index == shift) {
return(OrderProfit());
}

index++;
}
}

return(0);
}

//+------------------------------------------------------------------+

int sqGetMarketPositionCount(string symbol, int magicNumber, int direction, string comment) {
double count = 0;

for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP ||OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

count++;
}
}

return(count);
}

//+------------------------------------------------------------------+

int sqGetBarsSinceOpen(string symbol, int magicNumber, int direction, string comment) {
if(sqSelectOrder(magicNumber, symbol, direction, comment, false, false)) {
datetime opTime = OrderOpenTime();

int numberOfBars = 0;
for(int i=0; i<10000; i++) {
if(opTime < Time[i]) {
numberOfBars++;
}
}

return(numberOfBars);
}

return(-1);
}

//+------------------------------------------------------------------+

int sqGetBarsSinceClose(string symbol, int magicNumber, int direction, string comment) {
if(sqSelectOrderInHistory(magicNumber, symbol, direction, comment)) {
datetime clTime = OrderCloseTime();

int numberOfBars = 0;
for(int i=0; i<10000; i++) {
if(clTime < Time[i]) {
numberOfBars++;
}
}

return(numberOfBars);
}

return(-1);
}


//+------------------------------------------------------------------+

int sqGetLastOrderType(string symbol, int magicNumber, string comment) {
if(sqSelectOrderInHistory(magicNumber, symbol, 0, comment)) {
if(OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT) {
return(1);
} else {
return(-1);
}
}

return(0);
}

//+------------------------------------------------------------------+

bool sqSelectOrderInHistory(int magicNumber, string symbol, int direction, string comment) {
for (int cc = OrdersHistoryTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS,MODE_HISTORY)) {

// skip pending orders
if(OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT) {
continue;
}

if(direction != 0) {
if(direction > 0 && OrderType() != OP_BUY) continue;
if(direction < 0 && OrderType() != OP_SELL) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

// otherwise we found the order
return(true);
}
}

return(false);
}

//+------------------------------------------------------------------+

bool sqSelectPendingOrderByType(int magicNumber, string symbol, int orderType, string comment) {
for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {
if(OrderType() == OP_BUY || OrderType() == OP_SELL) {
continue;
}

if(orderType != 0) {
if(OrderType() != orderType) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

// otherwise we found the order
return(true);
}
}

return(false);
}

//+------------------------------------------------------------------+

bool sqSelectPendingOrderByDir(int magicNumber, string symbol, int direction, string comment) {
for (int cc = OrdersTotal() - 1; cc >= 0; cc--) {
if (OrderSelect(cc, SELECT_BY_POS)) {
if(OrderType() == OP_BUY || OrderType() == OP_SELL) {
continue;
}

if(direction != 0) {
int orderDirection = sqGetDirectionFromOrderType(OrderType());
if(orderDirection != direction) continue;
}

if(magicNumber != 0) {
if(OrderMagicNumber() != magicNumber) continue;
}
else if(!checkMagicNumber(OrderMagicNumber())) continue;

if(symbol != "Any") {
if(OrderSymbol() != correctSymbol(symbol)) continue;
}

if(comment != "") {
if(StringFind(OrderComment(), comment) == -1) continue;
}

// otherwise we found the order
return(true);
}
}

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

bool sqClosePositionAtMarket(double size) {
int ticket = OrderTicket();

Verbose("Closing order with ticket: ", ticket);

int orderType = OrderType();

if(orderType != OP_BUY && orderType != OP_SELL) {
Verbose("Trying to close non-live order");
return(false);
}
if(!sqCheckConnected()) {
return(false);
}

bool result;

double price = sqGetClosePrice(orderType, OrderSymbol(), 0);
result = OrderCloseReliable(ticket, size, price, correctSlippage(sqMaxCloseSlippage, OrderSymbol()));
if(result) {
Verbose("Order deleted successfuly");
return(true);
}

return(false);
}

//+------------------------------------------------------------------+

double sqGetAsk(string symbol) {
if(symbol == "NULL" || symbol == "Current") {
return(NormalizeDouble(Ask, Digits));
} else {
return(NormalizeDouble(MarketInfo(symbol,MODE_ASK), Digits));
}
}

//+------------------------------------------------------------------+

double sqGetBid(string symbol) {
if(symbol == "NULL" || symbol == "Current") {
return(NormalizeDouble(Bid, Digits));
} else {
return(NormalizeDouble(MarketInfo(symbol,MODE_BID), Digits));
}
}

//+------------------------------------------------------------------+

bool sqDeletePendingOrder(int ticket) {
Verbose(" Deleting pending order, ticket: " + ticket);

int orderType = OrderType();

if(orderType == OP_BUY || orderType == OP_SELL) {
Verbose("Trying to delete non-pending order");
return(false);
}
if(!sqCheckConnected()) {
return(false);
}

bool result = OrderDeleteReliable(ticket);
if(result) {
Verbose("Order deleted successfuly");
return(true);
}

return(false);
}

//+------------------------------------------------------------------+

int sqOpenOrder(int orderType, string symbol, double size, double price, int magicNumber, string comment, datetime expirationInTime, bool replaceExisting, bool allowDuplicateTrades, color arrowColor) {
string correctedSymbol = correctSymbol(symbol);

double ask = sqGetAsk(correctedSymbol);
double bid = sqGetBid(correctedSymbol);

int direction = sqGetDirectionFromOrderType(orderType);

double marketPrice = direction == 1 ? ask : bid;

price = price > 0 ? price : marketPrice;
price = sqFixMarketPrice(price, correctedSymbol);

openingOrdersAllowed = openingOrdersAllowed && sqHandleTradingOptions();

if(!openingOrdersAllowed) return(0);

Verbose("Opening order type ", OrderTypeToString(orderType)," with price ", price, ". Current market prices: ", ask, " / ", bid);

// check if live order exists
if(sqSelectOrder(magicNumber, correctedSymbol, 0, comment) && !allowDuplicateTrades) {
Verbose("Order with these parameters already exists and duplicate trades are not allowed. Canceling order...");
Verbose("----------------------------------");
return(0);
}

// check if pending order exists
if(sqSelectOrder(magicNumber, correctedSymbol, direction, comment, false, false, true)) {
if(replaceExisting) {

if(ModifyInsteadOfReplacing) {
// modify existing pending order
if(OrderModifyReliable(OrderTicket(), price, 0, 0, expirationInTime)) {
// reset global variables for this order
sqResetGlobalVariablesForTicket(OrderTicket());
return ( OrderTicket() );

} else {
Verbose("Modifying order failed, deleting it");
sqDeletePendingOrder(OrderTicket());
return(0);
}
} else {
// delete existing pending order
sqDeletePendingOrder(OrderTicket());
}

} else {
Verbose("Pending Order with these parameters already exists, and replace is not allowed. Canceling order...", " ----------------");
return(0);
}
}

if(!checkOrderPriceValid(orderType, correctedSymbol, price, marketPrice)){
return 0;
}

string commentToUse = "";
if(comment != ""){
commentToUse = comment;
}
else {
commentToUse = CustomComment;
StringReplace(commentToUse, "Optimization", "Opt."); //shorten the name of optimized strategies
}
commentToUse = StringSubstr(commentToUse, 0, 30); //limit the length to 30 characters

int ticket = OrderSendReliable(correctedSymbol, orderType, size, price, correctSlippage(sqMaxEntrySlippage, correctedSymbol), 0, 0, commentToUse, magicNumber, expirationInTime, arrowColor);

if(ticket > 0) {
// reset global variables for this order
sqResetGlobalVariablesForTicket(ticket);
}

return(ticket);
}

//----------------------------------------------------------------------------

int correctSlippage(int slippage, string symbol = NULL){
if(slippage <= 0) return 100000;

if(autoCorrectMaxSlippage){
int realDigits = (int) MarketInfo(correctSymbol(symbol), MODE_DIGITS);
if(realDigits > 0 && realDigits != 2 && realDigits != 4) {
return slippage * 10;
}
}

return slippage;
}

//----------------------------------------------------------------------------

bool checkOrderPriceValid(int orderType, string symbol, double price, double marketPrice){
if(orderType == OP_BUY || orderType == OP_SELL){
if(marketPrice == price){
return true;
}
else {
Verbose("Strategy tried to place market order at incorrect price. Market price: ", marketPrice, ", order price: ", price);
return false;
}
}

return checkStopPriceValid(orderType, symbol, price, marketPrice, "stop/limit order");
}

//----------------------------------------------------------------------------

bool checkStopPriceValid(int orderType, string symbol, double price, double marketPrice, string name){
int stopLevel = (int) MarketInfo(symbol, MODE_STOPLEVEL);
double point = MarketInfo(symbol, MODE_POINT);
double minDistance = point * stopLevel;
double priceLevel;

if(orderType == OP_BUYLIMIT || orderType == OP_SELLSTOP){
priceLevel = marketPrice - minDistance;

if(price <= priceLevel){
return true;
}
else {
Verbose("Strategy tried to place ", name, " at incorrect price. Market price: ", marketPrice, ", max. price allowed: ", priceLevel, ", ", name, " price: ", price);
return false;
}
}
else if(orderType == OP_BUYSTOP || orderType == OP_SELLLIMIT){
priceLevel = marketPrice + minDistance;

if(price >= priceLevel){
return true;
}
else {
Verbose("Strategy tried to place ", name, " at incorrect price. Market price: ", marketPrice, ", min. price allowed: ", priceLevel, ", ", name," price: ", price);
return false;
}
}
else return true;
}

//+------------------------------------------------------------------+

int sqGetDirectionFromOrderType(int orderType) {
if(orderType == OP_BUY || orderType == OP_BUYSTOP || orderType == OP_BUYLIMIT) {
return(1);
} else {
return(-1);
}
}

//+------------------------------------------------------------------+

bool sqIsPendingOrder(int orderType) {
if(orderType != OP_BUY && orderType != OP_SELL) {
return(true);
}
return(false);
}

//+------------------------------------------------------------------+

void sqSetSLandPT(int ticket, double sl, double pt) {
if(sl == 0 && pt == 0) return;

if(!OrderSelect(ticket, SELECT_BY_TICKET)) {
Verbose("Cannot select order with ticket: ",ticket);
return;
}

if(sl == OrderOpenPrice()) {
Verbose("SL is the same as order price, cannot set it, so we'll delete the order!");
if(!OrderDeleteReliable(ticket)) {
Verbose("Warning! Cannot delete order and SL/PT was not set! Error: ", GetLastError());
}

return;
}

if(pt == OrderOpenPrice()) {
pt = 0;
}

if(sl > 0 || pt > 0) {
bool result = sqOrderModify(ticket, OrderOpenPrice(), sqFixMarketPrice(sl, OrderSymbol()), sqFixMarketPrice(pt, OrderSymbol()));
if(!result) {
Verbose("Cannot set SL / PT for this order, deleting it!");
if(!OrderDeleteReliable(ticket)) {
Verbose("Warning! Cannot delete order and Sl/PT was not set! Error: ", GetLastError());
}
}
}
}

//+------------------------------------------------------------------+

bool sqOrderModifySL(int ticket,double stopLoss, int type) {
if(!OrderSelect(ticket, SELECT_BY_TICKET)) {
Verbose("Cannot select order with ticket: ",ticket);
}

if(type == SLPTTYPE_RANGE) {
// convert range to price level
if(sqGetDirectionFromOrderType(OrderType()) == 1) {
// it is long order
stopLoss = OrderOpenPrice() - stopLoss;
} else {
stopLoss = OrderOpenPrice() + stopLoss;
}
}

return(sqOrderModify(ticket, OrderOpenPrice(), sqFixMarketPrice(stopLoss, OrderSymbol()), OrderTakeProfit()));
}

//+------------------------------------------------------------------+

bool sqOrderModifyPT(int ticket,double profitTarget, int type) {
if(!OrderSelect(ticket, SELECT_BY_TICKET)) {
Verbose("Cannot select order with ticket: ",ticket);
}

if(type == SLPTTYPE_RANGE) {
// convert range to price level
if(sqGetDirectionFromOrderType(OrderType()) == 1) {
// it is long order
profitTarget = OrderOpenPrice() + profitTarget;
} else {
profitTarget = OrderOpenPrice() - profitTarget;
}
}

return(sqOrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), sqFixMarketPrice(profitTarget, OrderSymbol())));
}

//+------------------------------------------------------------------+

bool sqOrderModify(int ticket, double price, double stopLoss, double profitTarget) {
if(!OrderSelect(ticket, SELECT_BY_TICKET)) {
Ver
Attachments
No attachments
  • Votes +1
  • Project StrategyQuant X
  • Type Bug
  • Status Fixed
  • Priority Normal

History

b
#1

gin

18.06.2020 11:28

Task created

E
#2

Emmanuel

25.06.2020 08:22
Voted for this task.
TB
#3

Tomas Brynda

26.06.2020 17:25

Status changed from New to Fixed

Hi Gin,

I would advise you not to use Open bar only precision when performing MT4 backtests. This method is not accurate and our EAs are supposed to be reacting on every tick.

You can't trade on open bar only in real trading unless you write the EA specifically to react on bar open only.


At least try to use control points precision, but you will get most reliable results by using every tick.


Best regards,

Tomas



Votes: +1

Drop files to upload

or

choose files

Max size: 5MB

Not allowed: exe, msi, application, reg, php, js, htaccess, htpasswd, gitignore

...
Wait please