- 由于小括号的缺失,你有几个错位的代码块。虽然是平衡的,但它们是缺失的,比如在 "for "和几个 "if "块的开头
- 这一行"if(OrderSymbol()!=Symbol()) continue;{"非常可疑,让人很难看出代码流程应该是怎样的。只需将其改为"if(OrderSymbol()==_Symbol) {"。不使用"Symbol()",也可以使用"_Symbol"
- 使用"OrderClosePrice()",而不是"Ask"或"Bid"。
- 在做比较时要加括号,以便于阅读,同时保证事情的顺序。例如,不使用"if(Bid-OrderOpenPrice()>TrailingStart*Pip)",而使用"if( ( OrderClosePrice()- OrderOpenPrice() ) > ( TrailingStart * Pip )"
- 试着将买入和卖出的代码块合并成一个处理两者的代码块。这将使调试的代码更少,并且在未来更容易阅读和修改。
PS!NB!也要为订单使用一个神奇的数字!
PS!还记得要考虑到可能导致130错误的滑移。仅仅是StopLevel的最小值是不够的。让它稍微大一点,以考虑到可能的滑点,如增加一个当前价差的系数。经纪人也可能有一个FreezeLevel!
- 你有几个错位的代码块,因为小括号丢失了。尽管是平衡的,但它们是缺失的,例如在 "for "和几个 "if "块的开头处
- 这一行"if(OrderSymbol()!=Symbol())continue;{"非常可疑,让人很难看出代码流程应该是怎样的。
只需将其改为"if(OrderSymbol()==_Symbol) {"。你也可以用"_ 符号 "代替 "Symbol()"。 - 使用"OrderClosePrice()",而不是"Ask"或"Bid"。
- 在做比较时添加小括号,使其更容易阅读,以及保证事情的顺序。
例如,不使用"if(Bid-OrderOpenPrice()>TrailingStart*Pip)",而使用"if( ( OrderClosePrice()- OrderOpenPrice() ) > ( TrailingStart * Pip )"。 - 试着将买入和卖出的代码块合并成一个处理两者的代码块。这将使调试的代码更少,并在将来更容易阅读和修改。
PS!NB!也要为订单使用一个神奇的数字!
PS!还记得要考虑到可能导致130错误的滑点。仅仅是StopLevel的最小值是不够的。让它稍微大一点,以考虑到可能的滑移,如增加一个当前点差的系数。经纪人也可能有一个冻结水平(FreezeLevel)。
非常感谢你的回答和对我的帮助。 我有几个问题/评论。
1.在#1中,你建议我添加小括号(),我按照你在#4中的建议做了。 但我不知道如何在 "for "的开头添加小括号()。 请你解释一下,或者你是指大括号{}?
2.我已经把它改成了_Symbol,但为了提高我的知识水平,我想请你解释一下,使用_Symbol比Symbol()有什么好处/优势?
3.我已经把所有的Asks和Bids改为OrderClosePrice(),但是,请你解释一下这样做的好处/优点是什么?
4.我是这样做的
5.我将尝试看看如何能更简化。
6.由于我是手动输入交易,我的理解是我不能使用MagicNumbers。 这不是真的吗?
7.我没有看到如何或在哪里可以计算滑点,请告诉我在哪里或如何添加滑点。 对于OrderModify,它只允许以下参数。
bool OrderModify( int ticket, // ticket double price, // price double stoploss, // stop loss double takeprofit, // take profit datetime expiration, // expiration color arrow_color // color );
在我的代码中,我已经在最低止损点上增加了1个点(10个点),这在大多数情况下应该可以考虑到点差。
9.我已经打印了所有货币对的冻结水平,它们都是0.0,所以似乎不是一个问题。
10.尽管我仍然收到错误130 和错误1,但当EA工作时,它仍然修改和关闭订单。 因此,根据这些结果,我收到错误,因为订单同时被修改。 仿佛它是一个时间问题。
2016.04.15 13:11:06.183 Trailing_v18 USDCAD,M15: modify #50202284 buy 0.01 USDCAD at 1.28477 sl: 1.28598 tp: 0.00000 ok
2016.04.15 13:11:05.860 Trailing_v18 USDCAD,M15: Buy = 130
2016.04.15 13:10:58.939 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28597 tp: 0.00000 ok
2016.04.15 13:10:57.835 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28596 tp: 0.00000 ok
2016.04.15 13:10:56.974 Trailing_v18 USDCAD,M15: Buy = 130
2016.04.15 13:10:56.531 Trailing_v18 USDCAD,M15: Buy = 130
2016.04.15 13:10:56.263 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28590 tp: 0.00000 ok
2016.04.15 13:10:54.318 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28582 tp: 0.00000 ok
2016.04.15 13:10:53.175 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28581 tp: 0.00000 ok
2016.04.15 13:10:52.879 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28577 tp: 0.00000 ok
2016.04.15 13:10:51.810 Trailing_v18 USDCAD,M15: Buy = 130
2016.04.15 13:10:51.085 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28575 tp: 0.00000 ok
2016.04.15 13:10:50.744 Trailing_v18 USDCAD,M15: Buy = 130
2016.04.15 13:10:50.020 Trailing_v18 USDCAD,M15: Buy = 1
2016.04.15 13:10:50.020 Trailing_v18 USDCAD,M15: 修改 #50202284 买入 0.01 USDCAD at 1.28477 sl: 1.28571 tp: 0.00000 ok
下面是另一个例子,跟踪止损明显高于止损水平(10点/100点),但它仍然产生错误130。
2016.04.15 14:15:03.432 Trailing_v18 EURAUD,M15: Buy error = 130
2016.04.15 14:15:03.432 Trailing_v18 EURAUD,M15: TS = 20
2016.04.15 14:15:03.432 Trailing_v18 EURAUD,M15: TrailingStop = 5
2016.04.15 14:15:03.432 Trailing_v18 EURAUD,M15: TrailingStart = 25
2016.04.15 14:15:03.432 Trailing_v18 EURAUD,M15: stoplevel = 10.0
请提供带有你所做的更新的最新代码。否则,我无法对你最近的修改进行评论,看它们是否正确。
- 对不起,我是指大括号。你必须解决这个问题,否则它将继续失败。这是所有要点中最重要的一点。
- a) 这一点主要不是关于"_符号",而是关于"!="和 "继续"。
b) "_Symbol "的执行速度较快,因为它是一个变量,而 "Symbol() "将作为一个函数调用执行,速度较慢。 - OrderClosePrice() 是订单的当前收盘价。如果仍然开放,它会根据订单类型 自动报告出价或要价。请阅读此函数的文档。
- 好的!让我们看看你所做的代码修改。
- OK!让我们看看你所做的代码修改。
- 然而,在你的代码中,将 "魔法号码 "定义为 "外部 "或 "输入",将其指定为 "0 "作为默认值,然后在你的代码中使用该变量。这样,你就可以很容易地将EA用于其他情况,或者将你的代码重复用于其他EA。
- 我已经解释了如何计算滑点的问题。确保 "TrailStop > ( StopLevel + ( CurrentSpread * Factor ))",其中Factor至少是 "1.0"(最好是 "1.5 "或 "2.0";如果你看到由于过度滑点,你仍然遇到Error 130,则更大)。
- 不能保证10个点能占到点差,因为点差根据符号的不同而不同,而且一直在变化,特别是在新闻事件期间和流动性低的时候,如非工作时间。
- 好的!如果不使用 "FreezeLevel "是可以的,但我建议你仍然在你的代码中满足它,这样万一你在不同的经纪人那里使用它(可能有),EA仍然可以工作。
- 请提供带有变化的新代码,以便对其进行分析。
请提供带有你所做的更新的最新代码。否则,我无法对你最近的修改进行评论,看它们是否正确。
- 对不起,我是指大括号。你必须解决这个问题,否则它将继续失败。这是所有要点中最重要的一点。
- a) 这一点主要不是关于"_符号",而是关于"!="和 "继续"。
b) "_Symbol "的执行速度较快,因为它是一个变量,而 "Symbol() "将作为一个函数调用执行,速度较慢。 - OrderClosePrice() 是订单的当前收盘价。如果仍然开放,它会根据订单类型自动报告出价或要价。请阅读此函数的文档。
- 好的!让我们看看你所做的代码修改。
- OK!让我们看看你所做的代码修改。
- 然而,在你的代码中,将 "魔法号码 "定义为 "外部 "或 "输入",将其分配为 "0 "作为默认值,然后在你的代码中使用该变量。这样,你就可以很容易地将EA用于其他情况,或者将你的代码重复用于其他EA。
- 我已经解释了如何计算滑点的问题。确保 "TrailStop > ( StopLevel + ( CurrentSpread * Factor ))",其中Factor至少是 "1.0"(最好是 "1.5 "或 "2.0";如果你看到由于过度滑移,你仍然遇到Error 130,则更大)。
- 不能保证10个点能占到点差,因为点差根据符号的不同而不同,而且一直在变化,特别是在新闻事件期间和流动性低的时候,如非工作时间。
- 好的!如果不使用 "FreezeLevel "是可以的,但我建议你仍然在你的代码中满足它,这样万一你在不同的经纪人那里使用它(可能有),EA仍然可以工作。
- 请提供带有变化的新代码,以便对其进行分析。
非常感谢你,我会研究上述所有的意见和建议。 同时,这是最新的代码。 另外,我认为我在这一行发现了一个错误。
#property strict; extern string Label_TrailingStart="Pip threshold to activate TrailingStop"; extern int TrailingStart=12; extern int TrailingStop=5; double stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10; int TS=TrailingStart-TrailingStop; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int init(){ if(TS<stoplevel){ MessageBox("Please note: Your inputs for TrailingStart and/or TrailingStop cannot"+ "\nbe less than the minimum levels required by your broker and the"+ "\nTrailingStart has been increased automatically to "+StringConcatenate(stoplevel+TrailingStop+2)+" Pips"); } return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int deinit(){ return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start(){ double Pip=Point*10; int ticket=0; if(TS<stoplevel) TrailingStart=(int)stoplevel+TrailingStop+2; /*Print("stoplevel = ",stoplevel); Print("TrailingStart = ",TrailingStart); Print("TrailingStop = ",TrailingStop); Print("TS = ",TS); Print("Buy error = ",GetLastError()); Print("OrderOpenPrice = ",OrderOpenPrice()); Print("OrderClosePrice()-OrderOpenPrice()>TrailingStart*Pip = ", OrderClosePrice()-OrderOpenPrice()>TrailingStart*Pip); Print("OrderClosePrice-TrailingStop*Pip = ",OrderClosePrice()-TrailingStop*Pip); Print("TrailingStart*Pip = ",TrailingStart*Pip); Print("TrailingStop*Pip = ",TrailingStop*Pip); Print("OrderClosePrice = ",OrderClosePrice()); Print("OrderStopLoss = ",OrderStopLoss()); Print("OrderSymbol = ",OrderSymbol()); Print("OrdersTotal = ",OrdersTotal()); Print("OrderSelect = ",OrderSelect(OrderTicket(),SELECT_BY_TICKET)); Print("ticket = ",ticket); Print("OrderTicket = ",OrderTicket()); Print("Selectbyticket = ",SELECT_BY_TICKET); Print("Selectbypos = ",SELECT_BY_POS); Print("Ask = ",Ask); Print("OrderModify = ",OrderModify(OrderTicket(),OrderOpenPrice(),OrderClosePrice()-(TrailingStop*Pip), OrderTakeProfit(),Blue));*/ for(int i=OrdersTotal()-1; i>=0; i--) if(OrderSelect(i,SELECT_BY_POS)){ ticket++; if(OrderSymbol()==_Symbol){ if(OrderType()==OP_BUY){ if(OrderSelect(OrderTicket(),SELECT_BY_TICKET)){ if((OrderClosePrice()-OrderOpenPrice())>(TrailingStart*Pip)){ if(TrailingStop<OrderClosePrice()-(TrailingStop*Pip)){ RefreshRates(); if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderClosePrice()-(TrailingStop*Pip),OrderTakeProfit(),Blue)) Print("Buy error = ",GetLastError()); } } } } if(OrderType()==OP_SELL){ if(OrderSelect(OrderTicket(),SELECT_BY_TICKET)){ if((OrderOpenPrice()-OrderClosePrice())>(TrailingStart*Pip)){ if(TrailingStop>OrderClosePrice()+(TrailingStop*Pip)){ RefreshRates(); if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderClosePrice()+(TrailingStop*Pip),OrderTakeProfit(),Red)) Print("Sell error = ",GetLastError()); /*Print("Ask = ",Ask); Print("Ask+TrailingStop*Pip = ",Ask+TrailingStop*Pip); Print("TrailingStart*Pip = ",TrailingStart*Pip);*/ } } } } } } return(0); } //+------------------------------------------------------------------+
我做的一个相当大的改动是我把下面的第一行改为第二行,因为我认为止损必须有一个高于零的值。 是这样吗?
if(OrderStopLoss()<OrderClosePrice()-(TrailingStop*Pip)){if(TrailingStop<OrderClosePrice()-(TrailingStop*Pip)){
下面的代码例子可以作为你的代码的一个可能的解决方案/替代方案。然而,请注意,这些代码没有经过测试或调试(只经过编译),所以只能作为 "伪 "代码使用。
#property strict extern double dblTrailStartPips = 11.0, // Trailing Start (Pips) dblTrailStopPips = 5.0, // Trailing Stop (Pips) dblPipMultiplier = 10.0, // Pips to Points Multiplier dblSpreadFactor = 2.0; // Spread Factor for Slippage Compensation extern int intMagicNumber = 0; // Magic Number (0 for Manual Orders) double dblTickSizeDelta, // Size of a Tick (Delta) dblStopLevelDelta, // Market Stop Level (Delta) dblTrailStartDelta, // Trailing Start (Delta) dblTrailStopDelta; // Trailing Stop (Delta) // Initialisation int OnInit() { dblTickSizeDelta = MarketInfo( _Symbol, MODE_TICKSIZE ); dblStopLevelDelta = MarketInfo( _Symbol, MODE_STOPLEVEL ) * _Point; dblTrailStartDelta = dblTrailStartPips * dblPipMultiplier * _Point; dblTrailStopDelta = dblTrailStopPips * dblPipMultiplier * _Point; return( INIT_SUCCEEDED ); } // Process Tick Event void OnTick() { double dblSpreadDelta = Ask - Bid, dblMinStopDelta = dblStopLevelDelta + ( dblSpreadDelta * dblSpreadFactor ), dblTrailDelta = ( dblTrailStopDelta > dblMinStopDelta ) ? dblTrailStopDelta : dblMinStopDelta; for( int i = OrdersTotal() - 1; i >= 0; i-- ) { if( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) ) { if( ( OrderSymbol() == _Symbol ) && ( OrderMagicNumber() == intMagicNumber ) ) { int intDirection = 0; switch( OrderType() ) { case OP_BUY: intDirection = +1; break; case OP_SELL: intDirection = -1; break; default: continue; } double dblOpenPrice = OrderOpenPrice(), dblCloseDelta = ( OrderClosePrice() - dblOpenPrice ) * intDirection; if( dblCloseDelta > dblTrailStartDelta ) { double dblStopLossPrice = OrderStopLoss(), dblStopLossDelta = ( dblStopLossPrice - dblOpenPrice ) * intDirection, dblTrailingDelta = dblCloseDelta - dblTrailDelta; if( ( dblTrailingDelta > dblStopLossDelta ) || ( dblStopLossPrice == 0 ) ) { double dblStopLoss = round( ( dblOpenPrice + ( dblTrailingDelta * intDirection ) ) / dblTickSizeDelta ) * dblTickSizeDelta; if( dblStopLoss != dblStopLossPrice ) { if( !OrderModify( OrderTicket(), dblOpenPrice, dblStopLoss, OrderTakeProfit(), OrderExpiration() ) ) { Print( "Order Modification Failed with Error: ", GetLastError() ); } } } } } } } }
试试这个 Trader3000
将此代码与你已有的代码进行比较......它非常相似,我已经使用它多年,它像炸弹一样有效......
//+------------------------------+ //| TRAILING STOP Function | //+------------------------------+ void Trailing_Stop_Function() { bool Ticket_TS_Long; for(int iTS_Long = OrdersTotal() - 1; iTS_Long >= 0 ; iTS_Long --) { if(OrderSelect(iTS_Long,SELECT_BY_POS,MODE_TRADES) == true && OrderSymbol() == Symbol() && OrderType() == OP_BUY && OrderMagicNumber() == MagicNumberLong && Trailing_Stop_In_Pips > 0 && Bid - OrderOpenPrice() > Trail_After_Pips_Profit*PipMultiplier && OrderStopLoss() < Bid - (Trailing_Stop_In_Pips*PipMultiplier)) { Ticket_TS_Long = (OrderModify(OrderTicket(),OrderOpenPrice(),Bid - (Trailing_Stop_In_Pips*PipMultiplier),NULL,0,Green)); if (Ticket_TS_Long != true) { Print("TS-Order Modify Error ",GetLastError()); } } } bool Ticket_TS_Short; for(int iTS_Short = OrdersTotal() - 1; iTS_Short >= 0 ; iTS_Short --) { if(OrderSelect(iTS_Short,SELECT_BY_POS,MODE_TRADES) == true && OrderSymbol() == Symbol() && OrderType() == OP_SELL && OrderMagicNumber() == MagicNumberShort && Trailing_Stop_In_Pips > 0 && OrderOpenPrice() - Ask > Trail_After_Pips_Profit*PipMultiplier && OrderStopLoss() > Ask + (Trailing_Stop_In_Pips*PipMultiplier)) { Ticket_TS_Short = (OrderModify(OrderTicket(),OrderOpenPrice(),Ask + (Trailing_Stop_In_Pips*PipMultiplier),NULL,0,Green)); if (Ticket_TS_Short != true) { Print("TS-Order Modify Error ",GetLastError()); } } } }
Trail_After_Pips_Profit是一个外部的双变量,由用户填写...和
PipMultiplier是一个计算货币小数点值 的简单函数......。
如果你不使用MagicNumbers,那么请删除该标准....。
这将...或者说 "应该 "跟踪任何图表上的任何订单.....
我接受纠正,但它对我有用....
//+------------------------------------------+ //| Check for 5 Digits - Pipmultiplier | //+------------------------------------------+ if(Digits==5||Digits==3) { PipMultiplier = 10*Point; } else if(Digits==2) { PipMultiplier = 100*Point; } else { PipMultiplier = Point; }
我对你的帮助印象深刻,FMIC....好样的
@Mike.T: 你的PipMulytiplier代码似乎有些不对劲。
else if(Digits==2) { PipMultiplier = 100*Point; }
这似乎并不正确!为什么对2位数的符号要乘以100?它根本就不应该被乘以!它应该与4位数符号的条件相同。
这里有一个例子。如果美元/日元的价格从108.65上升到108.77;那是12个点的增长,而不是1200个点!谢谢你!
一些建议;不要使用 "Ask "或 "Bid" - 使用 "OrderClosePrice()"。它是一个实时值,无论它是买单还是卖单。
谢谢...不知道.... 所以...(在不影响这个主题的情况下)...我应该使用OrderClosePrice()而不是Bid或Ask...?
大家好,我无法让我的EA正常工作,我同时在10个不同的货币对/图表上运行它,似乎有两个问题。
1.大部分时间它不能触发追踪止损,但有时它可以工作。 我认为问题出在我的订单选择上,但无法解决它。
2.它有时给我错误130,但我看不出我的SL/TP怎么会无效。 我打印的所有数值都高于所有货币对的止损水平。 即使我得到错误130,它实际上有时确实修改了订单,好像没有什么问题。
下面是整个EA,请您看一下,让我知道问题出在哪里?