我正在尝试开发一段MQL4代码,当Expert Advisor打开的职位在满足EA交易指定的条件时无法关闭/清算时,会向您发送通知。
以下是我到目前为止的情况。
当成功平仓时ClosePosition()
返回true
,当EA未能平仓时返回false
。else if (ClosePosition == false)
这就是//Order Close//
string sym = Symbol();
int ordersTotal = OrdersTotal();
for(int PosSel = ordersTotal-1; PosSel>=0; PosSel--)
{
if(OrderSelect(PosSel,SELECT_BY_POS,MODE_TRADES))
if(OrderTicket() > 0)
if(OrderMagicNumber() == Period())
if(OrderSymbol() == Symbol())
if(TimeCurrent() >=(OrderOpenTime() + 60 * Period()))
{
ClosePosition = OrderClose(OrderTicket(),8,MarketInfo(sym,MODE_BID) + MarketInfo(sym,MODE_SPREAD) * MarketInfo(sym,MODE_POINT),300,clrNONE);
if(ClosePosition == true)
{
Sleep(60000);
int PosSelHist = OrdersHistoryTotal()-1;
bool reshist = OrderSelect(PosSelHist,SELECT_BY_POS,MODE_HISTORY);
if(reshist == true && Digits == 5)
{
double ClosingPrice = OrderClosePrice();
double OpeningPrice = OrderOpenPrice();
double Profit = OrderProfit();
int Ticket = OrderTicket();
SendMail("Trade Notification Email (TNE)","Order# "+DoubleToStr(Ticket,0)+" has been closed on the account "+AccountName()+
"\n"+
"\nThe order exit price for this trade is "+DoubleToStr(ClosingPrice,5)+"with a profit/loss of"+DoubleToStr(Profit,2)+
"\n"+
"\nThe spread charge for this position is £"+DoubleToStr((spread*tickvalue)*LotSize,2)+
"\n"+
"\n-----------------------------------------------------------------------"+
"\n"+
SendNotification("Ticket # "+IntegerToString(Ticket,10)+"has closed with a profit/loss of "+DoubleToStr(Profit,2));
}
else if(reshist == true && Digits == 3)
{
double ClosingPrice = OrderClosePrice();
double OpeningPrice = OrderOpenPrice();
double Profit = OrderProfit();
int Ticket = OrderTicket();
SendMail("Trade Notification Email (TNE)","Order# "+DoubleToStr(Ticket,0)+" has been placed on the account "+AccountName()+
"\n"+
"\nThe order entry price for this trade is "+DoubleToStr(ClosingPrice,3)+"with a profit/loss of"+DoubleToStr(Profit,2)+
"\n"+
"\nThe spread charge for this position is £"+DoubleToStr((spread*tickvalue)*LotSize,2)+
"\n"+
"\n-----------------------------------------------------------------------"+
SendNotification("Ticket # "+IntegerToString(Ticket,10)+" has closed with a profit/loss of "+DoubleToStr(Profit,2));
}
}
else if(ClosePosition == false)
{
int failedClosePosition = OrdersTotal()-1;
bool fail = OrderSelect(failedClosePosition,SELECT_BY_POS,MODE_HISTORY);
if(fail == true)
{
SendNotification("Order Number #"+IntegerToString(OrderTicket(),10)+" has failed to close. Please refer to error code "+IntegerToString(GetLastError()));
}
}
}
}
开始的地方。
ClosePosition == true
首先,这是获得理想结果的正确方法,其次;这是对if
替代方案进行编码的正确方法,还是else if
而不是compile files('libs/lucene-6.2.0/queryparser/lucene-queryparser-6.2.0.jar')
compile files('libs/lucene-6.2.0/demo/lucene-demo-6.2.0.jar')
compile files('libs/lucene-6.2.0/core/lucene-core-6.2.0.jar')
compile files('libs/lucene-6.2.0/analysis/common/lucene-analyzers-common-6.2.0.jar')
?
答案 0 :(得分:0)
不,抱歉。代码很难被证实是正确的。
当然,可以修复一些语法错误。
很大一部分处理是重复的,这可能有效,但很难长期维护,并被认为是一个糟糕的软件工程实践/习惯。
您可能会受益于相当保留搜索OrderTicket()
然后直接db.POOL
后的唯一SELECT_BY_TICKET
值,这对{ MODE_TRADES | MODE_HISTORY }
db.POOL
部分Sleep( 60000 )
部分中的所有order_state / order_relative_position更改都很有效
接下来是提议的MQL4代码的最大敌人:
如果有人相信这一点,永远不会阻止代码的流动。 MQL4代码执行环境是基于事件的,由外部事件源(市场)触发,调用Sleep()
比在EuroTunnel退出时在轨道上休眠更糟糕。 OUCH !!
您的代码无法做出反应,更糟糕的是,无法让MQL4代码生态系统的其他部分与市场事件流同步呼吸。相信我,肯定有更好的方法,如何“几乎不做”,而不是Digits
。
效率提示:
避免代码重复,而是使用StringFormat()
- 特定的格式,无论是通过设置为实际小数位数的变量,还是通过OrderTicket()
模式。
可能会享受一些不同的代码布局,这将有助于您避免语法错误,错过括号等。
更喜欢使用全球唯一的,与指针类似的OrderClose()
数字,如OrderClose()
中所评估,而是预先存储它的值,因为您希望稍后在代码中重复使用它,但是没有从if(){}else if(){}
时刻获得它。
可以享受另一个用于MQL4代码工作的IDE,其中折叠和柱状块变得非常方便(Geany,SciTe,JEdit,Notepad ++)。在这里,您很快就会在{True|False}
代码中查看效率低下的情况-blocks,其中else
部分重复了自然的共同//Order Close//
string sym = Symbol();
int ordersTotal = OrdersTotal();
for ( int PosSel = ordersTotal - 1; // loopVar .SET
PosSel >= 0; // loopVar .PRE-condition
PosSel-- // loopVar .DEC at loop-end
)
{
if ( OrderSelect( PosSel, SELECT_BY_POS, MODE_TRADES ) )
if ( OrderTicket() > 0 )
if ( OrderMagicNumber() == Period() )
if ( OrderSymbol() == Symbol() )
if ( OrderOpenTime() <= TimeCurrent() - ( 60 * Period() ) )
{
ClosePosition = OrderClose( OrderTicket(),
8,
MarketInfo( sym, MODE_BID )
+ MarketInfo( sym, MODE_SPREAD )
* MarketInfo( sym, MODE_POINT ),
300,
clrNONE
);
if ( ClosePosition == true )
{ // ===================||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||====================
Sleep( 60000 ); //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| BLOCKS EA-EXECUTION
// ===================||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||====================
int PosSelHist = OrdersHistoryTotal() - 1;
bool reshist = OrderSelect( PosSelHist, SELECT_BY_POS, MODE_HISTORY );
if ( reshist == true
&& Digits == 5
)
{
double ClosingPrice = OrderClosePrice();
double OpeningPrice = OrderOpenPrice();
double Profit = OrderProfit();
int Ticket = OrderTicket();
SendMail( "Trade Notification Email (TNE)",
"Order# " + DoubleToStr( Ticket, 0 )
+ " has been closed on the account " + AccountName()
+ "\n"
+ "\nThe order exit price for this trade is " + DoubleToStr( ClosingPrice, 5 )
+ "with a profit/loss of" + DoubleToStr( Profit, 2 )
+ "\n"
+ "\nThe spread charge for this position is £" + DoubleToStr( ( spread
* tickvalue
)
* LotSize, 2 )
+ "\n"
+ "\n-----------------------------------------------------------------------"
+ "\n"
+ SendNotification( "Ticket # "
+ IntegerToString( Ticket, 10 )
+ "has closed with a profit/loss of "
+ DoubleToStr( Profit, 2 )
)
);
}
else if ( reshist == true
&& Digits == 3
)
{
double ClosingPrice = OrderClosePrice();
double OpeningPrice = OrderOpenPrice();
double Profit = OrderProfit();
int Ticket = OrderTicket();
SendMail( "Trade Notification Email (TNE)",
"Order# " + DoubleToStr( Ticket, 0 )
+ " has been placed on the account " + AccountName()
+ "\n"
+ "\nThe order entry price for this trade is " + DoubleToStr( ClosingPrice, 3 )
+ "with a profit/loss of" + DoubleToStr( Profit, 2 )
+ "\n"
+ "\nThe spread charge for this position is £" + DoubleToStr( ( spread
* tickvalue
)
* LotSize, 2 )
+ "\n"
+ "\n-----------------------------------------------------------------------"
+ SendNotification( "Ticket # "
+ IntegerToString( Ticket, 10 )
+ " has closed with a profit/loss of "
+ DoubleToStr( Profit, 2 )
)
);
}
}
else if ( ClosePosition == false )
{
int failedClosePosition = OrdersTotal() - 1;
bool fail = OrderSelect( failedClosePosition, SELECT_BY_POS, MODE_HISTORY );
if ( fail == true )
{
SendNotification( "Order Number #"
+ IntegerToString( OrderTicket(), 10 )
+ " has failed to close. Please refer to error code "
+ IntegerToString( GetLastError() )
);
}
}
}
}
- 二分法。
无论如何,享受MQL4的狂野世界
cellForRowAtIndexPath
答案 1 :(得分:0)
您可能会尝试平仓,但由于一些常规问题而失败 - 重新报价,或交易环境繁忙或其他情况。 因此,您必须确保收盘价是新鲜的
RefreshRates();
您也可以尝试解决TradeContext问题和其他方式,替代方式 - 尝试发送一些关闭请求:
int ATTEMPTS; // declare on a global scope
int OnInit(){ // initialise
ATTEMPTS = IsTesting() ? 1 : 100; // ternary-op =boolA?valB:valC
//---
return(INIT_SUCCEEDED);
}
void Order_Close(){
int ticket = GetTicketNumberToClose(); // put all checks here
TradeClose(ticket);
}
void TradeClose(int ticket){ // change to bool
// returning T/F if you need
while(IsTradeContextBusy()) Sleep(5); // a blocking-loop
int current_attempt = 0, err=-1;
while(current_attempt < ATTEMPTS){
RefreshRates(); // get fresh prices from Market
if (!OrderClose(ticket,OrderLots(),OrderClosePrice(),5)){
err = GetLastError();
current_attempt++;
}else return;
}
Print( __LINE__,
"failed to close ticket#", ticket,
" at price", DoubleToStr( OrderClosePrice(), Digits ),
". err#", err
); // send notification
// instead of Print() if you need
}