从保证金的百分比中正确计算出该批次的金额 - 页 5

 
EverAlex:

因此lSL是指多少个点到SL

点=0.00001(在5位数的报价上)。

dLotStep = 0.01


公式(LSL*dLotCost*dLotStep))*dLotStep是 错误的

它应该是类似于(LSL*dLotCost*Point))*dLotStep 的东西。


你不需要编造什么。每家经纪公司的手数是不同的,你必须把它调整到合适的大小。积分与此无关
 
Vinin:

你不需要发明任何东西。每个经纪公司的拍品尺寸都不一样,我们必须把它带到合适的尺寸。分数与此无关。


在我们的案例中,lSL是 以报价点为单位 的缩减规模,而不是以手数为单位的缩减规模。

也就是说,积分确实与此有关。

因此,在计算公式中,我们应该乘以(括号中的内容)Point,而不是乘以dLotStep

另一件事是,这已经是以dLotCost 为代价完成的(连同转换为存款货币)......。

也就是说,我们是第一个在

MathRound(AccountFreeMargin()*lRisk*0.01/(lSL*dLotCost*dLotStep))

获得一个整数,然后通过乘以dLotStep ,重新计算回正确的批次单位?

 
double lotSize(double deposSize=1000.0, string currName="USDCHF", double proc=2.0, int pipsLoss=1000)// функция лота
{  
   //проверка достаточности средств 
   if(deposSize < 
   MarketInfo(currName,MODE_MARGINREQUIRED)*MarketInfo(currName,MODE_MINLOT))
   //для проведения торговли
   {
      Alert("Величина вашего депозита недостаточна \nдля торговли на инструменте\""+currName+"\" \nc минимальнодопустимым лотом");
      return 0.0;
   }
   //проверка, на стоп-аут
   ENUM_ACCOUNT_STOPOUT_MODE stopOutMode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   double procUsed;
   if(stopOutMode==ACCOUNT_STOPOUT_MODE_PERCENT)//если стоп-аут в процентах
     {
         if(proc > AccountInfoDouble(ACCOUNT_MARGIN_SO_SO))
           {
               Alert("Потеря выше уровня STOPOUT!\nРасчет лота производиться по величине STOPOUT.");
               procUsed=AccountInfoDouble(ACCOUNT_MARGIN_SO_SO)/100;
               //Print(MarketInfo(currName,MODE_MARGINREQUIRED)," ",procUsed);
               return deposSize/(pipsLoss+procUsed*MarketInfo(currName,MODE_MARGINREQUIRED));               
           }
     }
     //а вот здесь нужна доработка, для платформ, где стоп-аут в пунктах
     //как сказал один наш товарищ "у кого идеи ростут из нужного места".. доделает
     
   double currMove=deposSize*proc/100;// расчет процента от величины депозита
   double lotCount=currMove/(pipsLoss*MarketInfo(currName,MODE_TICKVALUE));//ну а тут и ведеться сам расчет лота

   if(lotCount<MarketInfo(currName,MODE_MINLOT))
   {
      return MarketInfo(currName,MODE_MINLOT);
   }
   if(lotCount>MarketInfo(currName,MODE_MAXLOT))
   {
      return MarketInfo(currName,MODE_MAXLOT);  
   }
   return NormalizeDouble(lotCount,2);
   //return lotCount;
}

还有一个选项,存款3英镑,可以交易欧元兑美元,把30%放在亏损方......但这是出于一系列的变态行为

 
EverAlex:


就问题而言,lSL是 以报价的点数为单位 的缩水大小,而不是以手数的点数为单位。

也就是说,积分与此无关。

因此,在计算公式中,我们应该乘以(括号中的内容)Point,而不是乘以dLotStep

另一件事是,这已经是以dLotCost 为代价完成的(连同转换为存款货币)......。

也就是说,我们首先在

得到一个整数,然后通过乘以dLotStep 重新计算回正确的批次单位




 
Vinin:


该公式仍然是错误的(对于iSL>0 的区块)。

TICKVALUE 给出了TICKSIZE 的价格。

lSL 的单位是POINT 点。

POINT 并不总是与TICKSIZE 相吻合(见Alpari的3位数货币对XAUUSD)。

所以你必须把lSL POINT转换为 TICKSIZE

否则,我们将获得10倍的高估手数(这是我在XAUUSD货币对上观察到的,直到我加入重新计算)。

如果(LSL>0){

lSL= (int)(MarketInfo(lSymbol,MODE_TICKSIZE) / MarketInfo(lSymbol,MODE_POINT) )* lSL; // TICKSIZE/POINT将给出一个整数(1或10),我们可以使用int类型的lSL

//这里是它的内容。

 double dLotCost=MarketInfo(lSymbol,MODE_TICKVALUE);
 dLot=MathRound(AccountFreeMargin()*lRisk*0.01/(lSL*dLotCost*dLotStep))*dLotStep;
}

PS:对于TC优化的许多通道(>10mln),符号的所有不可改变的参数(TICKSIZE,POINT,TICKVALUE,LOTSTEP,MINLOT,MAXLOT 等)应该被分配给函数init() 中的变量,并在计算中使用这些变量。

包括将TickSize/Point的 值放入一个变量。

 
EverAlex:

该公式仍然是错误的(对于iSL>0 的区块)。

TICKVALUE 给出了TICKSIZE 的价格。

lSL 的单位是POINT 点。

POINT 并不总是与TICKSIZE 相吻合(见Alpari的3位数货币对XAUUSD)。

所以你必须把lSL POINT转换为 TICKSIZE

否则,我们将获得10倍的高估手数(这是我在XAUUSD货币对上观察到的,直到我加入重新计算)。

如果(LSL>0){

lSL= (int)(MarketInfo(lSymbol,MODE_TICKSIZE) / MarketInfo(lSymbol,MODE_POINT) )* lSL; // TICKSIZE/POINT将给出一个整数(1或10),我们可以使用int类型的lSL

//这里是它的内容。

PS:对于优化许多通道(>10mln)的TS,所有不可改变的符号参数(TICKSIZE,POINT,TICKVALUE,LOTSTEP,MINLOT,MAXLOT 等)必须被分配到函数init() 中的变量,并在计算中使用变量。

包括将TickSize/Point的 值放入一个变量。




谢谢你
 
Vinin:

谢谢

该专题负责人在第一页上发送了他的敬意,然后再也没有回来。

几年前,在某个论坛上讨论过这个问题。我将根据记忆复述,但没有公式。

假设我们交易澳元兑瑞郎货币对。为了解释头寸的利润或亏损是如何形成的,它是相当随意地采取的。在https://www.mql5.com/ru/forum/150912, 也提出了大致相同的话题。

如果我们交易一手100000澳元,那么(按五位数计算)每一个点都能赚取1瑞士法郎(对分母)的利润或损失(这取决于我们走了哪条路,价格走向如何)。

因此,在任何时候,我们都知道我们已经获得/失去了多少瑞士法郎。如果存款货币是美元,收益/损失将被转换为存款货币,使用当时 的美元兑瑞士法郎汇率,如果存款货币是欧元,则使用欧元兑瑞士法郎。以此类推,对于所有货币对和存款货币。

这就是答案:我们不能总是估计准确的正确的地段尺寸。带有请求参数MODE_TICKVALUE的MarketInfo()可以作为一个指导。

 
Mislaid:

因此,答案是:我们不能总是估计准确的正确的地段大小。带有MODE_TICKVALUE请求参数的MarketInfo()可以作为一个指导。


长期以来都是这样核算的。至少在Vinin的 好帖子(TICKSIZE c POINT 不匹配的情况下,手数计算错误)和Martingeil的 旧帖子(手数计算正确,但没有可能设置缩减==0)。

最主要的是TICKVALUE 的正确值应该来自经纪公司(或者在客户上正确计算,如果它是在MT中计算的)。


当这个主题开始时,还没有TICKVALUE

而随着它的出现,一切都被简化了,这个话题也被冷落了一阵子。

PS:很快我将发布我的版本--Vinin的版本(它有更简单的公式和iSL==0)和Martingeil的版本(即使是最小手数也能控制资金不足)的混合版本。

特点:1)从AccountFreeMargin()计算余额,而不是从AccountBalance()计算。

2)而且(对于移仓者)考虑到当未平仓的交易在SL上关闭时,余额将减少一定数量。

如果没有足够的钱,即使是最小的余额 - 它将显示手数 -134(错误134 - 没有足够的钱来打开一个交易)。

在这方面,向维宁(和其他有经验的同志)提问:这个代码是自己着色还是你自己做?我试着将片段样式设置为 "代码",但它并没有着色。还是只有在提交帖子后才有颜色?

 
EverAlex:

有一个问题要问Vinin(和其他有经验的同志):代码是自己着色,还是你自己着色?我试着将片段样式设置为 "代码",但它没有颜色。还是只有在提交帖子后才有颜色?

它是由我自己着色的。但并不总是如此。
 

敲定了我的想法(针对有止损百分比的平台)......分享代码......接受建设性的批评

double lotSize(double deposSize=1000.0, string currName="USDCHF", double proc=2.0, int pipsLoss=1000)
{  
   double lotCount=0;
   //1) проверка достаточности средств для проведения торговли
   if(deposSize < 
   MarketInfo(currName,MODE_MARGINREQUIRED)*MarketInfo(currName,MODE_MINLOT))
   {
      //Alert("Величина вашего депозита недостаточна \nдля торговли на инструменте\""+currName+"\" \nc минимальнодопустимым лотом");
      return 0.0;
   }
   
   double currMove=deposSize*proc/100;// расчет процента от величины депозита
   
  
   //расчивываем максимально допустимый лот, до стоп-аута
   double SOlot = deposSize/(pipsLoss*MarketInfo(currName,MODE_TICKVALUE)+
   MarketInfo(currName,MODE_MARGINREQUIRED)*AccountInfoDouble(ACCOUNT_MARGIN_SO_SO)/100);     
   //расчет величины депозита, при котором сработает стоп-аут
   double SOval = SOlot*pipsLoss*MarketInfo(currName,MODE_TICKVALUE);
   
   
   ENUM_ACCOUNT_STOPOUT_MODE stopOutMode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   
   if(stopOutMode==ACCOUNT_STOPOUT_MODE_PERCENT)//если стоп-аут в процентах
   {  
     
     if((deposSize-currMove)<SOval)//проверяем остаток на депозите на превышение значения стоп-аут
     {     
         if(SOlot<MarketInfo(currName,MODE_MINLOT))//если лот стоп-аута меньше минимального лота
         {
             lotCount = MarketInfo(currName,MODE_MINLOT);
             //находим количесвто пунктов до вылета по стоп-ауту и выбрасываем предупреждение
             int pipsSO=(int)round((deposSize - SOval)/(lotCount * MarketInfo(currName,MODE_TICKVALUE)));
             Print("При прохождении ценой больше ", pipsSO," пп.- \nторговля будет прекращена по STOP OUT!");             
             
             
         }
         else//если наш стоп-аут лот больше равно минимального
         {
              lotCount = SOlot;              
              int pipsSO=(int)round((deposSize - SOval)/(lotCount * MarketInfo(currName,MODE_TICKVALUE)));
              Print("Достижение STOP OUT, произойдет через ", pipsSO, " и работа будет проведена с максимальнодоступимым лотом до STOP OUT");
                           
         }
     }
     else//если же остаток на депозите будет меньше стоп-аута
     {     
     lotCount = currMove/(pipsLoss*MarketInfo(currName,MODE_TICKVALUE));
         if(lotCount<MarketInfo(currName,MODE_MINLOT))//если лот меньше минимального лота
         {            
            int pipsProc=(int)round(currMove/(MarketInfo(currName,MODE_MINLOT)*MarketInfo(currName,MODE_TICKVALUE)));
            Print(proc,"%-й уровень депозита будет достигнут, з минимальнолопустимым лотом, за ",pipsProc," пп.");
            lotCount=MarketInfo(currName,MODE_MINLOT);      
         }         
     }     
     
   }
   else{
   //а вот здесь нужна доработка, для платформ, где стоп-аут в пунктах
   //как сказал один наш товарищ "у кого идеи ростут из нужного места".. доделает
   /*
   */}      
  
   //"прическа" для лота   
   lotCount = MathFloor(lotCount/MarketInfo(currName,MODE_MINLOT))*MarketInfo(currName,MODE_MINLOT);   

   if(lotCount<MarketInfo(currName,MODE_MINLOT))
   {
      return MarketInfo(currName,MODE_MINLOT);
   }
   if(lotCount>MarketInfo(currName,MODE_MAXLOT))
   {
      return MarketInfo(currName,MODE_MAXLOT);  
   }   
   return lotCount;
}