专家顾问 - 杂项问题 - 页 4

 
  1. 是的,他们大量地使用它。所有这些都是在只有货币的时候写的。现在有了金属,如果tick size != point,那就完全错了。
  2. 02:00:00.069- 自定义专家 EURUSD,H1:| _lotSize -NormalizeDouble: 0.07000000000000001
    OP一直在打印出一个双数到15位的数字,不明白为什么不是0.07的准确数字。因为有些数字不能准确地表示为1/8.可以1/10.不可以。
 
honest_knave:
double LotCalculator(double lots)
  {
   ...
   return(NormalizeDouble(lots,2));
  }

这条评论对我帮助很大,这很有用,但它给了我更多的小数。
(更多的小数是正常的 - 因为我已经读过了)

我仍然担心'NormalizeDouble',我正在寻找另一种方法,哪种方法比'NormalizeDouble'好?

谢谢!

 

非常感谢写评论的人。

@whroeder1- 我将广泛研究你的评论(/链接),非常感谢。
@Marco- 我将在LotSize LotStep问题后使用它。谢谢!

 
Max Enrik:

这个评论真的对我帮助很大,这很有用,但这让我有了更多的小数。
(更多的小数是正常的,因为我已经读过了)。

我仍然担心"NormalizeDouble",我正在寻找另一种方法,哪种方法比 "NormalizeDouble "更好?

谢谢!

也许最好先确定你要实现的具体目标。

如果你想用一个函数 来返回有效的手数来下单,你不需要使用NormalizeDouble()。我的原始代码片段或WHRoeder的代码将为你实现这一目标。它们之间有细微的差别,这将是一个个人偏好的问题。

但是,如果你直接用Print()打印该批次的数值,你可能会得到一些 "奇怪 "的结果......比如你的0.07000000000000001

这对OrderSend()来说不是问题,但可能不是你期望看到的。

如果你想看到数字以 "正常 "方式显示,你有两个选择。

1.你可以在函数中使用NormalizeDouble()。对于一个标准的打印输出,数值将是你所期望的那样。但是如果你(手动)打印足够多的小数位,你最终会发现这个数字并不完全是你想象的那样。这就是WHRoeder想要表达的意思(我想)。这个解决方案不是最优雅的,但它是最简单的。或者...

2.你可以让手数保持原样(即不使用NormalizeDouble),然后在需要的时候为显示目的调整数值。你可以使用DoubleToStr() 或StringFormat()或printf()来实现,这取决于你的需要。这是一个更灵活的方法。

记住,实际值和该值的显示方式不一定相同。你永远不可能精确地存储0.07。

   double myVal=0.07;
   printf("%.24f",myVal);

Result: 0.070000000000000006661338

但如果你需要,你肯定可以显示0.07。
 
honest_knave:

也许最好先确定你要实现的具体目标。
...

哇,你写得很好,我几乎理解了你的评论。
所以我将写新的评论,很快。

//----第二次编辑

正如我所提到的,我不需要LotSize和LotStep只在显示屏上显示,我需要LotSize和LotStep可以在任何地方显示相同的东西。
我只是担心这个问题。

 

好吧,如果是关于动态批次的问题,你总是可以插入一个简单的变速箱。

//Gearbox//
double Lots;
Balance=AccountInfoDouble(ACCOUNT_BALANCE);

if(Balance>10000)
{Lots=10;Print(" Gear Two");}
if(Balance>100000)
{Lots=100;Print(" Gear Three");}
if(Balance>1000000)
{Lots=1000;Print(" Gear Four");}
if(Balance>10000000)
{Lots=10000;Print(" Gear Five");}

if(Balance<10000000)
{Lots=1000;Print(" Gear Four");}
if(Balance<1000000)
{Lots=100;Print(" Gear Three");}
if(Balance<100000)
{Lots=10;Print(" Gear Two");}
if(Balance<10000)
{Lots=1;Print(" Gear One");}
if(Balance>1000000000)
{Lots=0;}
 

我需要把我的部分EA发布给你,所以我希望它能帮助你更清楚地了解我。
所以,我需要知道这是好的代码还是什么?

请给我好的(明确的)建议或帮助,提前感谢。

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{

    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, _btnLotMinus, OBJPROP_STATE, false );
        _lotSize -= _lotStep;

        if ( NormalizeDouble( _lotSize, 2 ) <= 0 ) _lotSize = _lotMin;
        _calcUpdade( CALC_CHANGE_LOT );

        Print( " | Lot:   ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

double _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
    return( NormalizeDouble( _lotSize, 2 ) );
}
 
Max Enrik:

我需要把我的部分EA发布给你,所以我希望它能帮助你更清楚地了解我。
所以,我需要知道这是好的代码还是什么?

请给我好的(明确的)建议或帮助,提前感谢。

深夜,未编译,未测试。

我们看不到你第一次设置_lotSize的地方......记住,你需要确保_lotSize始终是_lotStep的倍数。

我认为,如果你把所有的手数计算放在一起,而不是在OnChartEvent()和_lotCalc()之间分割,会更好。一个函数 可以检查最小/最大/步长,并进行增量/减量。

void OnChartEvent(const int      id     , // Event ID
                  const long   & lparam , // Parameter of type long event
                  const double & dparam , // Parameter of type double event
                  const string & sparam   // Parameter of type string events
                  )
{
    _lotCalc();
    //-------Process Button---------------------------------------------------------|
    if ( sparam == _btnLotMinus )
    {
        ObjectSetInteger( 0, sparam, OBJPROP_STATE, false );
        _lotSize = fmax(_lotMin, _lotSize-_lotStep);
        _calcUpdade( CALC_CHANGE_LOT );
        printf( " | Lot: %.2f  ", _lotSize );
        return;
    }   //---if Close
    //                          ...
}

void _lotCalc()
{
    //---
    _lotMin  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  );
    _lotMax  = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  );
    _lotStep = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );

    //---
}
 
honest_knave:

深夜,未编译,未测试。
我们看不到你第一次设置_lotSize的地方......记住,你需要确保_lotSize总是_lotStep的倍数。
我认为,如果你把所有的手数计算放在一起,而不是在OnChartEvent()和_lotCalc()之间分割,会更好。一个函数可以检查最小/最大/步长,并进行增量/减量。

这对我帮助很大,这意味着解决了我的lotSizelosStep 问题。
非常感谢你。

#Lot 0(零)&(在解决地段大小和地段阶梯问题之间)--关闭

 

是的,我忘记了lotSize代码,所以我在init 函数 中使用它。
_lotSize的位置好吗?

谢谢!

int OnInit()
{
    _pip = Point;
    if( Digits == 0 || Digits == 2 || Digits == 3 || Digits == 5 ) _pip = 10 * Point;
    _lotSize = _lotValue * MarketInfo( Symbol(), MODE_MINLOT );

    //...
}
原因: