Print(NormalizeDouble(1.88/2,2));
1.88 除以2 。结果是 0.9399999999999999。
我的需求是计算现在仓位的一半。双精度失真的这个问题是怎么解决的?
Print(DoubleToString(1.88/2,2));
部分浮点数在计算机中无法精确表示。
1.88/2= 0.94(数学上),计算机中0.94的真实表示在64位机器中是0.939999999999999947
所以NormalizeDouble(0.939999999999999947,2) = 0.94(数学上),计算机又把它表示为0.939999999999999947
所以要平仓一半可能存在问题?写个EA验证下,看看平仓有没有问题?
部分浮点数在计算机中无法精确表示。
1.88/2= 0.94(数学上),计算机中0.94的真实表示在64位机器中是0.939999999999999947
所以NormalizeDouble(0.939999999999999947,2) = 0.94(数学上),计算机又把它表示为0.939999999999999947
所以要平仓一半可能存在问题?写个EA验证下,看看平仓有没有问题?
ea 报错平不了的。
Print(DoubleToString(1.88/2,2));
我要的是浮点数。 toString 的数据不能传给 request 进行ea交易
我简单测试下,可以通过平半仓。
//+------------------------------------------------------------------+ //| test_094.mq5 | //| Copyright 2020,fxMeter | //| https://www.mql5.com/en/users/fxmeter | //+------------------------------------------------------------------+ #property copyright "Copyright 2020,fxMeter" #property link "https://www.mql5.com/en/users/fxmeter" #property version "1.00" #include <Trade\Trade.mqh> CTrade TradeObj; long MagicNumber = 1235; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- TradeObj.SetExpertMagicNumber(MagicNumber); TradeObj.SetMarginMode(); TradeObj.SetTypeFillingBySymbol(Symbol()); TradeObj.SetDeviationInPoints(30); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(!MQLInfoInteger(MQL_TESTER))return;//only test //...test double lots = 1.88; static datetime last = 0; if(PositionsTotal()==0) { TradeObj.Buy(lots); last=TimeCurrent(); return; } static int flag=0; if(PositionsTotal()>0 && flag==0 && TimeCurrent()>last+3600*10) { double lots2 = lots/2; lots2 = NormalizeDouble(lots2,2); //简单处理 ResetLastError(); if(!TradeObj.PositionClosePartial(Symbol(),lots2)) { Print("lots2 = ",lots2); Print("error = ",GetLastError()); } else { Print("lots2 = ",lots2); flag = 1; } } } //+------------------------------------------------------------------+ //2021.05.22 19:02:41.514 2021.04.01 10:00:20 lots2 = 0.9399999999999999
Print(NormalizeDouble(1.88/2,2));
1.88 除以2 。结果是 0.9399999999999999。
我的需求是计算现在仓位的一半。双精度失真的这个问题是怎么解决的?
一般仓位处理都需要格式化一下的
formatlots(string symbol,double dlots)
{
double min=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double step=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
if(dlots>=min)
{
double l=MathFloor(dlots/min)*min+MathFloor((dlots-MathFloor(dlots/min)*min)/step)*step;
return(l);
}
else
{
return(dlots);
}
}
Print(NormalizeDouble(1.88/2,2));
1.88 除以2 。结果是 0.9399999999999999。
我的需求是计算现在仓位的一半。双精度失真的这个问题是怎么解决的?
个人认为完整解决方案
double mstep=MarketInfo(m_sym,MODE_LOTSTEP); int digitslots=(int)log10(1/mstep); c_lots=NormalizeDouble(1.88/2.0,digitslots);你Print()试试。
Print(NormalizeDouble(1.88/2,2));
1.88 除以2 。结果是 0.9399999999999999。
我的需求是计算现在仓位的一半。双精度失真的这个问题是怎么解决的?