为什么 MQL4 OrderModify() 在回测时不会修改订单?
Why MQL4 OrderModify() will not modify the order when backtesting?
我正在尝试 ADD 在 MetaTrader 4 我的公开市场订单中止损,当头寸达到 100 点时“到good" 等于订单开仓价;
OrderStopLoss() == OrderOpenPrice()
但这并没有发生。
我已经添加了 Print()
和 GetLastError()
函数,但日志中没有出现任何内容,所以它一定是我编码中的东西 - 但看不出有什么问题。
好的,这就是我目前所拥有的,一个用于买入的 for 循环,一个用于卖出。我还按照建议对“双打”进行了规范化,并且还在最顶部将 BuyMod 和 SellMod 声明为“true”。这应该确保默认值不会求助于 false。我还认为如果我告诉您我有 MetaEditor 版本 5 build 1241 可能会有帮助:)
我的代码如下;
/*Breakeven Order Modification*/
bool BuyMod = true;
bool SellMod = true;
for(int b = OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
{
double aBidPrice = MarketInfo(Symbol(),MODE_BID);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (aBidPrice - anOpenPrice)/_Point;
double stopPoints = (aBidPrice - aNewSLPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType() == OP_BUY)
if(stopPoints >= stopLevel)
if(aTicket > 0)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
{
BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
for(int s = OrdersTotal()-1; s>=0; s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
{
double anAskPrice = MarketInfo(Symbol(),MODE_ASK);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (anOpenPrice - anAskPrice)/_Point;
double stopPoints = (aNewSLPrice - anAskPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType()== OP_SELL)
if(stopPoints >= stopLevel)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
if(aTicket > 0)
{
SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
交易算法-交易 mql4 metatrader4
shareeditdeleteflag
刚刚编辑
2 天前问过
托德·吉尔贝
264
您可能想知道,Whosebug 不提倡重复问题。 (见
问题出在您对内置 OrderModify()
函数的调用中。
OrderStopLoss() == OrderModify()
将评估为 false
反过来将评估为 0 因为 ==
是比较运算符。
一个OrderStopLoss()
是对另一个内置函数(不是变量)的调用,你不能向它保存任何东西所以 OrderStopLoss() = 4
也不行。
From the MQL4
documentation:
bool OrderModify( int ticket, // ticket
double price, // price
double stoploss, // stop loss
double takeprofit, // take profit
datetime expiration, // expiration
color arrow_color // color
);
在您的情况下,假设 ModBuy
已在代码中某处定义:
ModBuy = OrderModify( OrderTicket(), // <-ticket from record OrderSelect()'d
OrderOpenPrice(), // <-price from current record
OrderOpenPrice(), // <-price from current record
OrderTakeProfit(), // <-TP from current record
0, // ( cannot set P/O expiration for M/O )
buycolor // ( set a color for a GUI marker )
);
或者您可以使用任何其他有效值而不是第二个 OrderOpenPrice()
来设置新的止损。
除了满足 MQL4
语法规则外,
还有更多条件:
第一个隐患是数字四舍五入问题
MetaQuotes, Inc. 建议尽可能将浮动值规范化为适当的价格表示。
因此,
只要价格进入服务器端指令{ OrderSend(), OrderModify(), ... }
,就应该总是在标准化价格到达任何服务器端指令调用之前,通过调用 NormalizeDouble( ... , _Digits )
准备这样的 aPriceDOMAIN
值
。
可能听起来很幼稚,但是这 可以避免服务器端拒绝的问题。
添加 NormalizeDouble()
定期调用您的代码作为您的救生衣。
秒,更好的隐患在 STOP_ZONE
-s和FREEZE_ZONE
-s
虽然不直接可见,但任何经纪人都在其各自的条款和条件中设置了这些参数。
实际上,
这意味着,如果您指示 { OrderSend() | OrderModify() }
到 set / move aPriceDOMAIN
级别设置太接近当前实际值 Ask
/Bid
(违反 Broker-forbidden STOP_ZONE
)
或
删除/修改aPriceDOMAIN
止盈或止损水平,它们已经设置并且现在在经纪商禁止的范围内 FREEZE_ZONE
与实际相差Ask
/Bid
,
这样的指令将不会被成功接受和执行。
因此,除了调用 NormalizeDouble()
之外,请始终在价格移动 "far" 时等待更长时间,并定期检查是否违反禁止 STOP_
+ FREEZE_
区域在对算法交易项目的订单管理部分进行任何修改之前。
无论如何,欢迎来到 MQL4
的狂野世界
Update:
虽然 Whosebug 不是一个做功课的网站,但让我提出几个解决方案的方向:
for ( int b = OrdersTotal() - 1; b >= 0; b-- ) // ________________________ // I AM NOT A FAN OF db.Pool-looping, but will keep original approach for context purposes
{ if ( ( OrderSelect( b, SELECT_BY_POS, MODE_TRADES ) ) == true )
{ // YES, HAVE TO OPEN A CODE-BLOCK FOR if()-POSITIVE CASE:
// ------------------------------------------------------
double aBidPRICE = MarketInfo( Symbol(), MODE_BID ); // .UPD
double anOpenPRICE = OrderOpenPrice(); // .SET FROM a db.Pool Current Record
double aNewTpPRICE = OrderTakeProfit(); // .SET FROM a db.Pool Current Record
double aCurrentSlPRICE = OrderStopLoss(); // .SET FROM a db.Pool Current Record
double aNewSlPRICE = anOpenPRICE; // .SET
double pnlPOINTs = ( aBidPRICE - anOpenPRICE )/_Point; // .SET
double stopPOINTs = ( aBidPRICE - aNewSlPRICE )/_Point; // .SET
// ------------------------------------------------------------ // .TEST
if ( OP_BUY == OrderType() )
if ( Period() == OrderMagicNumber() )
if ( stopPOINTa > stopLevel )
if ( pnlPOINTs >= breakeven )
if ( aNewSlPRICE != aCurrentSlPRICE )
{ // YES, HAVE TO OPEN A BLOCK {...}-CODE-BLOCK FOR THE if()if()if()if()-chain's-POSITIVE CASE:
// -------------------------------------------------------------------------------------------
int aBuyMOD = OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( aNewSlPRICE, Digits ),
NormalizeDouble( aNewTpPRICE, Digits ),
0,
buycolor
);
switch( aBuyMOD )
{ case ( NULL ): { ...; break; } // FAIL ( ANALYSE ERROR )
default: { ...; break; } // PASS OrderModify()
}
}
}
真的很抱歉,我是 Whosebug 的新手,这是我现在根据下面大家的评论和推荐修改后的代码
**Local Declarations**
pnlPoints = 0;
point = MarketInfo(Symbol(),MODE_POINT);
stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo (Symbol(),MODE_SPREAD));
sl = NormalizeDouble(OrderStopLoss(),Digits);
tp = OrderTakeProfit();
cmd = OrderType();
breakeven = 100;
**Global Variables**
double pnlPoints;
double price,sl,tp;
double point;
int stopLevel;
int cmd;
int breakeven;
double newSL;
for(int b = OrdersTotal()-1; b>=0; b--)
{
if((OrderSelect(b,SELECT_BY_POS,MODE_TRADES))==true)
price = MarketInfo(Symbol(),MODE_BID);
newSL = NormalizeDouble(OrderOpenPrice(),Digits);
pnlPoints = (price - OrderOpenPrice())/point;
{
if(OrderType()==OP_BUY)
if(OrderMagicNumber() == Period())
if((price-newSL)/point>=stopLevel)
if(pnlPoints>=breakeven)
if(sl!=newSL)
ModBuy = OrderModify(OrderTicket(),OrderOpenPrice(),newSL,tp,buycolor);
else if(ModBuy == false)
{
Print("OrderModify failed with error #",GetLastError());
}
}
}
我正在尝试 ADD 在 MetaTrader 4 我的公开市场订单中止损,当头寸达到 100 点时“到good" 等于订单开仓价;
OrderStopLoss() == OrderOpenPrice()
但这并没有发生。
我已经添加了 Print()
和 GetLastError()
函数,但日志中没有出现任何内容,所以它一定是我编码中的东西 - 但看不出有什么问题。
好的,这就是我目前所拥有的,一个用于买入的 for 循环,一个用于卖出。我还按照建议对“双打”进行了规范化,并且还在最顶部将 BuyMod 和 SellMod 声明为“true”。这应该确保默认值不会求助于 false。我还认为如果我告诉您我有 MetaEditor 版本 5 build 1241 可能会有帮助:)
我的代码如下;
/*Breakeven Order Modification*/
bool BuyMod = true;
bool SellMod = true;
for(int b = OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
{
double aBidPrice = MarketInfo(Symbol(),MODE_BID);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (aBidPrice - anOpenPrice)/_Point;
double stopPoints = (aBidPrice - aNewSLPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType() == OP_BUY)
if(stopPoints >= stopLevel)
if(aTicket > 0)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
{
BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
for(int s = OrdersTotal()-1; s>=0; s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
{
double anAskPrice = MarketInfo(Symbol(),MODE_ASK);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (anOpenPrice - anAskPrice)/_Point;
double stopPoints = (aNewSLPrice - anAskPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType()== OP_SELL)
if(stopPoints >= stopLevel)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
if(aTicket > 0)
{
SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
交易算法-交易 mql4 metatrader4
shareeditdeleteflag
刚刚编辑
2 天前问过
托德·吉尔贝 264
您可能想知道,Whosebug 不提倡重复问题。 (见
问题出在您对内置 OrderModify()
函数的调用中。
OrderStopLoss() == OrderModify()
将评估为 false
反过来将评估为 0 因为 ==
是比较运算符。
一个OrderStopLoss()
是对另一个内置函数(不是变量)的调用,你不能向它保存任何东西所以 OrderStopLoss() = 4
也不行。
From the
MQL4
documentation:
bool OrderModify( int ticket, // ticket
double price, // price
double stoploss, // stop loss
double takeprofit, // take profit
datetime expiration, // expiration
color arrow_color // color
);
在您的情况下,假设 ModBuy
已在代码中某处定义:
ModBuy = OrderModify( OrderTicket(), // <-ticket from record OrderSelect()'d
OrderOpenPrice(), // <-price from current record
OrderOpenPrice(), // <-price from current record
OrderTakeProfit(), // <-TP from current record
0, // ( cannot set P/O expiration for M/O )
buycolor // ( set a color for a GUI marker )
);
或者您可以使用任何其他有效值而不是第二个 OrderOpenPrice()
来设置新的止损。
除了满足 MQL4
语法规则外,
还有更多条件:
第一个隐患是数字四舍五入问题
MetaQuotes, Inc. 建议尽可能将浮动值规范化为适当的价格表示。
因此,
只要价格进入服务器端指令{ OrderSend(), OrderModify(), ... }
,就应该总是在标准化价格到达任何服务器端指令调用之前,通过调用 NormalizeDouble( ... , _Digits )
准备这样的 aPriceDOMAIN
值
。
可能听起来很幼稚,但是这 可以避免服务器端拒绝的问题。
添加 NormalizeDouble()
定期调用您的代码作为您的救生衣。
秒,更好的隐患在 STOP_ZONE
-s和FREEZE_ZONE
-s
虽然不直接可见,但任何经纪人都在其各自的条款和条件中设置了这些参数。
实际上,
这意味着,如果您指示 { OrderSend() | OrderModify() }
到 set / move aPriceDOMAIN
级别设置太接近当前实际值 Ask
/Bid
(违反 Broker-forbidden STOP_ZONE
)
或
删除/修改aPriceDOMAIN
止盈或止损水平,它们已经设置并且现在在经纪商禁止的范围内 FREEZE_ZONE
与实际相差Ask
/Bid
,
这样的指令将不会被成功接受和执行。
因此,除了调用 NormalizeDouble()
之外,请始终在价格移动 "far" 时等待更长时间,并定期检查是否违反禁止 STOP_
+ FREEZE_
区域在对算法交易项目的订单管理部分进行任何修改之前。
无论如何,欢迎来到 MQL4
Update:
虽然 Whosebug 不是一个做功课的网站,但让我提出几个解决方案的方向:
for ( int b = OrdersTotal() - 1; b >= 0; b-- ) // ________________________ // I AM NOT A FAN OF db.Pool-looping, but will keep original approach for context purposes
{ if ( ( OrderSelect( b, SELECT_BY_POS, MODE_TRADES ) ) == true )
{ // YES, HAVE TO OPEN A CODE-BLOCK FOR if()-POSITIVE CASE:
// ------------------------------------------------------
double aBidPRICE = MarketInfo( Symbol(), MODE_BID ); // .UPD
double anOpenPRICE = OrderOpenPrice(); // .SET FROM a db.Pool Current Record
double aNewTpPRICE = OrderTakeProfit(); // .SET FROM a db.Pool Current Record
double aCurrentSlPRICE = OrderStopLoss(); // .SET FROM a db.Pool Current Record
double aNewSlPRICE = anOpenPRICE; // .SET
double pnlPOINTs = ( aBidPRICE - anOpenPRICE )/_Point; // .SET
double stopPOINTs = ( aBidPRICE - aNewSlPRICE )/_Point; // .SET
// ------------------------------------------------------------ // .TEST
if ( OP_BUY == OrderType() )
if ( Period() == OrderMagicNumber() )
if ( stopPOINTa > stopLevel )
if ( pnlPOINTs >= breakeven )
if ( aNewSlPRICE != aCurrentSlPRICE )
{ // YES, HAVE TO OPEN A BLOCK {...}-CODE-BLOCK FOR THE if()if()if()if()-chain's-POSITIVE CASE:
// -------------------------------------------------------------------------------------------
int aBuyMOD = OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( aNewSlPRICE, Digits ),
NormalizeDouble( aNewTpPRICE, Digits ),
0,
buycolor
);
switch( aBuyMOD )
{ case ( NULL ): { ...; break; } // FAIL ( ANALYSE ERROR )
default: { ...; break; } // PASS OrderModify()
}
}
}
真的很抱歉,我是 Whosebug 的新手,这是我现在根据下面大家的评论和推荐修改后的代码
**Local Declarations**
pnlPoints = 0;
point = MarketInfo(Symbol(),MODE_POINT);
stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo (Symbol(),MODE_SPREAD));
sl = NormalizeDouble(OrderStopLoss(),Digits);
tp = OrderTakeProfit();
cmd = OrderType();
breakeven = 100;
**Global Variables**
double pnlPoints;
double price,sl,tp;
double point;
int stopLevel;
int cmd;
int breakeven;
double newSL;
for(int b = OrdersTotal()-1; b>=0; b--)
{
if((OrderSelect(b,SELECT_BY_POS,MODE_TRADES))==true)
price = MarketInfo(Symbol(),MODE_BID);
newSL = NormalizeDouble(OrderOpenPrice(),Digits);
pnlPoints = (price - OrderOpenPrice())/point;
{
if(OrderType()==OP_BUY)
if(OrderMagicNumber() == Period())
if((price-newSL)/point>=stopLevel)
if(pnlPoints>=breakeven)
if(sl!=newSL)
ModBuy = OrderModify(OrderTicket(),OrderOpenPrice(),newSL,tp,buycolor);
else if(ModBuy == false)
{
Print("OrderModify failed with error #",GetLastError());
}
}
}