需要帮助解决错误#130无效止损的问题 - 页 2

 

正确设置止损的最好方法是正确考虑价差。点差是卖出价和买入价之间的距离。因此,当你使用Bid-SL为买入订单 添加止损时,会自动包括点差,你不需要为它编码,你能够有效地完全忽略点差。对于卖出交易,使用Ask + SL也有同样的效果。然而,请注意 --- 在交易量低的时候,点差会变大,你很可能最终的SL离你期望的位置很远 --- 因此你可能想添加一些代码来防止SL超过设定的点差大小。

现在点差的问题已经解决了,导致130错误的下一个主要原因是,当您的EA仍在执行时,价格已经改变。这可能是由于EA需要很长的时间来执行,或者服务器正忙于为交易提供服务而延迟了EA的执行。其结果是,一个刻度线导致您的EA开始执行,但在执行结束前又出现了另一个刻度线,现在的价格是无效的。

无论哪种情况,你都需要使用RefreshRates刷新价格: while (RefrshRates() == 1) Sleep(5); ------ 或任何你想要的等待时间。

 
BigAl:


无论哪种情况,你都需要使用RefreshRates来刷新价格: while (RefrshRates() == 1) Sleep(5); ------ 或任何你想作为等待时间的东西。

这只有在代码使用预定义变量的情况下才是正确的https://docs.mql4.com/predefined/variables 如果代码使用MarketInfo的Bid和Ask,那么RefreshRates将没有影响。
 
qjol:
AFAIK RefreshRates()与错误130没有关系

我同意使用MODE_ASK等可以消除RefreshRates()的必要性,但我认为,正如shinobi的代码示例....。

我发送一个订单,比如说。

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

正在使用预定义变量ASK,因此卖出价/买入价以及价差值 可能已经改变,导致错误130。在这种情况下,RefreshRates()可以在OrderSend之前立即使用。

 
BigAl:

RaptorUK的观点是正确的,我同意使用MODE_ASK等可以消除RefreshRates()的必要性,但我认为,正如shinobi的代码例子....

我发送一个订单,比如说。

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

正在使用预定义变量ASK,因此卖出价/买入价以及价差值可能已经改变,导致错误130。在这种情况下,RefreshRates()可以在OrderSend之前立即使用。

谢谢大家的精彩建议
我现在有点忙,但一旦我有机会,我会尝试你们所有的建议,然后写一个总结性的帖子,供任何可能偶然发现这个主题有同样问题的人阅读。

谢谢你,保重!

忍者
 
BigAl: 我发送一个订单,比如说。

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

并没有说明一切。你是如何计算initial_stop的 - 使用Bid?

你是如何计算SLIPPAGE的 - 为4/5位数 的经纪人进行调整

 
嘿,伙计们

我不得不休息了一段时间(搬到一个新的城市,新的工作)。
但现在我想接过这个话题,终于找到了解决这个被诅咒的#130止损错误的办法。

我很感谢你的所有建议,并试图将其全部纳入。

1:价差。
为了消除可能导致错误的价差,我将止损设置为
Bid-stoploss (Long)
Ask+stoploss (Short)

2:改变市场汇率
为了消除可能导致订单发送前市场汇率改变的原因,
我改变了我的代码,用
MarketInfo(Symbol(), MODE_ASK) 和 MarketInfo(Symbol(), MODE_BID) 取代所有出现的 Ask 和 Bid

3:4-5位-经纪人
为了消除可能导致无效位数的原因,我根据 WHRoeders 代码对止损进行了四舍五入。
int     pips2points;    // slippage  3 pips    3=points    30=points
double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)

//init digit adjustment
if (Digits % 2 == 1) {      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
} else {
    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; 
}

OrderSend(Symbol(), OP_BUY, position_size, MarketInfo(Symbol(), MODE_ASK), SLIPPAGE, (MarketInfo(Symbol(), MODE_BID) - stoploss) * pips2dbl, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);
如前所述,在我的案例中,变量SLIPPAGE和TAKEPROFIT始终为0。所以它们也不应该造成问题。

以我采纳了所有建议,但错误仍然存在。就我所知,它和以前一样经常发生,所以一定有其他原因。
这是最近的日志:

tickvalue: 12.50000000
pos size: 37.00000000
Ask/Bid 1262.00000000/1261.75000000
stoploss:12.59610000
position_size: 37
Spread 0.25000000

Error could not take long position.错误是。#130无效的止损

上述OrderSend代码行与记录的数值一起使用,试图采取多头头寸。
你还有什么想法吗,可能是什么原因?

谢谢!
shinobi
 

这是一个ECN经纪人吗?

WHRoeder 2011.09.15 20:36

在ECN经纪商,你必须先开仓,然后再设置止损。

 
shinobi:
为了消除无效数字的可能原因,我根据WHRoeders的代码四舍五入了止损。
  1. 我发布的代码中没有四舍五入的内容
  2. 在ECN经纪商,你必须先开仓,然后再设置止损。
  3. 在金属(TICKSIZE != Point)上,挂单的开盘价 必须四舍五入
    double TS=MarketInfo(pair, MODE_TICKSIZE);
    OOP = MathRound(OOP/TS)*TS;
    ,我不知道止损是什么。
  4. 不要再告诉我们数值是多少,以及你认为你做了什么。发布代码。
 

只要做

外置双倍止损=50。

外部双数TakeProfit = 50。

然后对于买入。

doubleSL=Bid - StopLoss* Point;

doubleTP=Bid + TakeProfit*Point;

int Ticket=OrderSend(Symbol(),0,1,Ask,2,SL,TP,"",12345)

if( Ticket<0) print("error="GetLastError())。

对于卖出。

double SL=Ask + StopLoss* Point;

double TP=Ask - TakeProfit*Point;

int Ticket=OrderSend(Symbol(),1,1,Bid,2,SL,TP,"",12345)

if( Ticket<0) print("error="GetLastError())。

如果不成功,就把日志文件贴出来。

 
谢谢Raptor, WHRoeder和SDC的回答。

SDC。
我试过你的代码是这样的。
   int result_ticket = -1;
   double stoploss            = 50;
   double takeprofit          = 50;
   double SL = 0.0;
   double TP = 0.0;
   if(long) {   //take long position
      SL = MarketInfo(Symbol(), MODE_BID) - stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_BID) + takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 0, 1, MarketInfo(Symbol(), MODE_ASK), 2, SL, TP, "", 12345);
   } else {     //take short position
      SL = MarketInfo(Symbol(), MODE_ASK) + stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_ASK) - takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 1, 1, MarketInfo(Symbol(), MODE_BID), 2, SL, TP, "", 12345);
   }

   //check for errors
   if(result_ticket == -1) {
      Log("error="+GetLastError());
      return(-1);
   }
唯一不同的是,我用MarketInfo替换了Point、Ask和Bid,以避免Raptor和BigAI提及的RefreshRates问题。
在这个简单的例子中,问题仍然存在。我仍然得到

#ESZ1,M5: 开盘位置
#ESZ1,M5: tickvalue: 12.50000000
#ESZ1,M5: 位置大小: 1.00000000
#ESZ1,M5: Ask/Bid 1244.50000000/1244.25000000
#ESZ1,M5: Spread 0.25000000
#ESZ1,M5: SL: 1244.00000000
#ESZ1,M5: TP: 1245.00000000
#ESZ1,M5: 错误=130

猛禽。
我目前使用UWC-Trader和一个模拟账户 进行测试。
如前所述,我正在交易期货。例如,ESZ1和FDXZ1。

WHRoeder:
对不起,我也不四舍五入。把 "四舍五入 "改为 "为4/5位数的经纪商调整"。也就是说,我只是应用了你的代码。
我还把OrderSend贴出来了,就像我在之前的回复中使用的那样。还有所有涉及的变量的值。我不确定该代码的其他部分是否有意义。
正如SDC建议的那个小例子所显示的,错误可以被分解到这个简单的代码。因此,它必须是更基本的。

我不是在交易金属,所以四舍五入应该不是很重要。

我接下来会尝试。
开盘(无止损),然后再修改(设置止损)。

再次感谢您的想法。

shinobi