问题描述
我试图在中对我的公开市场订单进行 ADD 止损,当头寸获得100点良好"收益时,等于开单价;
I'm trying to ADD a stop loss to my open market orders in when a position gets 100 pips "to the good" which is to be equal to the Order Open Price;
OrderStopLoss() == OrderOpenPrice()
但这没有发生.
我添加了Print()
& GetLastError()
功能正常,日记中没有任何内容,因此在我的编码中一定有问题-但看不到什么地方出了错.
I've added Print()
& GetLastError()
functions and nothing is coming up in the journal, so it must be something in my coding - but cannot see what would be wrong.
下面的代码如下;
/*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
trading algorithmic-trading mql4 metatrader4
shareeditdeleteflag
shareeditdeleteflag
刚刚编辑
2天前要求
托德·吉尔贝(Todd Gilbey)264
Todd Gilbey264
您可能想知道,StackOverflow不会推广重复的问题. (请参阅
You might want to know, StackOverflow does not promote duplicate questions. ( see the
推荐答案
除了满足MQL4
语法规则之外,
还有更多条件:
第一个隐藏的麻烦是数字舍入问题.
Besides meeting an MQL4
syntax-rules,
there are more conditions:
A first hidden trouble is in number rounding issues.
MetaQuotes,Inc.建议尽可能将浮点值标准化为适当的价格表示形式.
MetaQuotes, Inc., recommends wherever possible, to normalise float values into a proper price-representation.
因此,
只要价格进入服务器端指令 { OrderSend(), OrderModify(), ... }
,就应始终通过致电准备这样的aPriceDOMAIN
值
到 NormalizeDouble( ... , _Digits )
,直到归一化价格触及任何服务器端指令调用.
Thus,
wherever a price goes into a server-side instruction { OrderSend(), OrderModify(), ... }
one shall always prepare such aPriceDOMAIN
value
by a call to NormalizeDouble( ... , _Digits )
, before a normalised price hits any server-side instruction call.
听起来似乎很幼稚,但是此可以节省服务器端拒绝的问题.
May sound rather naive, but this saves you issues with server-side rejections.
将NormalizeDouble()
调用作为您的救生背心定期添加到您的代码中.
Add NormalizeDouble()
calls into your code on a regular base as your life-saving vest.
第二个甚至更好的隐藏故障出现在 STOP_ZONE
-s和 FREEZE_ZONE
-s
A second, even a better hidden trouble is in STOP_ZONE
-s and FREEZE_ZONE
-s
虽然不能直接显示,但任何经纪人集均在其各自的条款和条件中条件这些参数.
While not visible directly, any Broker set's in their respective Terms & Conditions these parameters.
实际上,这意味着,如果您指示{ OrderSend() | OrderModify() }
设置 /移动 aPriceDOMAIN
级别,使其设置太接近当前的实际 Ask
/ Bid
(违反了禁止经纪人的STOP_ZONE
)
或
删除/修改TP或SL的aPriceDOMAIN
级别,已设置,并且现在在与实际 Ask
/ Bid
的经纪人禁止的FREEZE_ZONE
距离内,
这样的指令将不会成功接受并执行.
In practice,
this means, if you instruct { OrderSend() | OrderModify() }
to set / move aPriceDOMAIN
level to be setup too close to current actual Ask
/Bid
( violating a Broker-forbidden STOP_ZONE
)
or
to delete / modify aPriceDOMAIN
level of TP or SL, that are already set and is right now, within a Broker-forbidden FREEZE_ZONE
distance from actual Ask
/Bid
,
such instruction will not be successfully accepted and executed.
因此,除了调用NormalizeDouble()
之外,还应等待更长的时间,以确保价格足够远"移动,并定期检查是否违反了禁止的STOP_
+ FREEZE_
区域,然后再在订单管理部件中订购任何修改产品您的谈判项目.
So besides calls to the NormalizeDouble()
, always wait a bit longer as the price moves "far" enough and regularly check for not violating forbidden STOP_
+ FREEZE_
zones before ordering any modifications in your order-management part of your algotrading projects.
无论如何,欢迎来到MQL4
的野生世界
Anyway, Welcome to Wild Worlds of MQL4
Update:
,尽管StackOverflow并非做家庭作业"网站,但让我为解决方案提出一些建议:
Update:
while StackOverflow is not a Do-a-Homework site, let me propose a few directions for the solution:
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()
}
}
}
这篇关于为什么MQL4 OrderModify()在回测时不会修改订单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!