% 보증금에서 정확한 로트 계산 - 페이지 5

 
EverAlex :

따라서 lSL은 SL에 대한 포인트 수입니다.

포인트 = 0.00001(5자리 따옴표의 경우)

dLotStep = 0.01


공식 (lSL*dLotCost* dLotStep ))*dLotStep이 잘못되었습니다.

(lSL*dLotCost* Point ))*dLotStep과 같아야 합니다.


당신은 아무것도 발명할 필요가 없습니다. 각 DC의 로트 크기가 다르므로 원하는 크기로 가져와야 합니다. 여기서 포인트는 중요하지 않습니다.
 
Vinin :

당신은 아무것도 발명할 필요가 없습니다. 각 DC의 로트 크기가 다르므로 원하는 크기로 가져와야 합니다. 여기서 포인트는 중요하지 않습니다.


문제의 조건에 따라 lSL 은 로트 포인트가 아닌 견적 포인트 의 축소 크기입니다.

저것들. 그것과 관련하여 여기를 가리킵니다.

이것은 계산 공식에서 dLotStep 이 아니라 Point 로 (괄호 안에 있는 것) 곱해야 함을 의미합니다.

또 다른 것은 이것이 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;
}

한 쌍의 "EURUSD"를 거래하고 손실에 대해 30%를 설정하기 위해 3달러의 보증금이 있는 또 다른 옵션이 있습니다. 그러나 이것은 이미 일련의 변태에서 나온 것입니다

 
EverAlex :


문제의 조건에 따라 lSL 은 로트 포인트가 아닌 견적 포인트 의 축소 크기입니다.

저것들. 그것과 관련하여 여기를 가리킵니다.

이것은 계산 공식에서 dLotStep 이 아니라 Point 로 (괄호 안에 있는 것) 곱해야 함을 의미합니다.

또 다른 것은 이것이 이미 dLotCost 를 희생시키면서 일어나고 있다는 것입니다(예금 통화로의 변환과 함께)...

저것들. 우리는 먼저

정수를 얻은 다음 dLotStep 을 곱하여 올바른 로트 단위로 다시 계산합니까?




 
Vinin :


어쨌든 공식이 잘못되었습니다( iSL>0 블록의 경우).

TICKVALUETICKSIZE 의 가격을 제공합니다.

그리고 lSL 은 포인트 POINT 에 지정됩니다.

POINT 가 항상 TICKSIZE 와 같은 것은 아닙니다(Alpari의 3자리 XAUUSD 쌍 참조).

따라서 POINT 에서 TICKSIZElSL 을 다시 계산해야 합니다.

그렇지 않으면 재계산을 추가할 때까지 XAUUSD 쌍에서 관찰한 값보다 10배 높은 가격이 책정됩니다.

if (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;
}

추신: 많은 패스(>1000만)에서 최적화된 차량의 경우 모든 변경 불가능한 기호 매개변수( TICKSIZE , POINT , TICKVALUE , LOTSTEP , MINLOT , MAXLOT 등)는 init () 함수 및 이러한 변수의 값은 계산에 사용되어야 합니다.

포함 TickSize/Point 값을 변수로 이동합니다.

 
EverAlex :

어쨌든 공식이 잘못되었습니다(블록 iSL>0 의 경우).

TICKVALUETICKSIZE 의 가격을 제공합니다.

그리고 lSL 은 포인트 POINT 에 지정됩니다.

POINT 가 항상 TICKSIZE 와 같은 것은 아닙니다(Alpari의 3자리 XAUUSD 쌍 참조).

따라서 POINT 에서 TICKSIZElSL 을 다시 계산해야 합니다.

그렇지 않으면 재계산을 추가할 때까지 XAUUSD 쌍에서 관찰한 값보다 10배 높은 가격이 책정됩니다.

if (lSL>0){

lSL= (int)(MarketInfo(lSymbol,MODE_TICKSIZE) / MarketInfo(lSymbol,MODE_POINT) )* lSL; // TICKSIZE/POINT는 정수(1 또는 10)를 제공하므로 int와 같은 lSL을 사용할 수 있습니다.

// 그대로 계속

추신: 많은 패스(>1000만)에서 최적화된 TS의 경우 모든 변경 불가능한 기호 매개변수( TICKSIZE , POINT , TICKVALUE , LOTSTEP , MINLOT , MAXLOT 등)는 i nit() 함수의 변수에 할당되고 사용되어야 합니다. 계산에서.

포함 TickSize/Point 값을 변수로 이동합니다.




감사해요
 
Vinin :

감사해요

Topikstarter는 첫 페이지에 경의를 표하고 다시 나타나지 않았습니다.

몇 년 전 포럼 어딘가에서 이 문제가 논의되었습니다. 나는 기억에서 다시 말할 것이지만 공식은 없습니다.

AUDCHF 쌍을 거래한다고 가정해 보겠습니다. 포지션에서 손익이 어떻게 형성되는지 설명하기 위해 상당히 자의적으로 취했습니다. 스레드 https://www.mql5.com/ru/forum/150912 에서 거의 동일한 주제가 제기되었습니다.

우리가 100,000 AUD의 한 로트를 거래하는 경우 (5자리 기준) 각 핍은 1CHF(쌍의 분모)의 이익 또는 손실을 가져옵니다(강철의 방향과 가격이 어디로 가는지에 따라 다름).

따라서 매 순간마다 우리는 얼마나 많은 CHF를 얻었는지/잃었는지 알고 있습니다. 예금 통화가 USD인 경우 승/패는 현재 USDCHF 환율로 예금 통화로 변환되고, 예금 통화가 EUR인 경우 EURCHF로 변환됩니다. 유추하여 모든 쌍 및 예금 통화에 대해.

따라서 답은 정확하고 정확한 로트 크기를 항상 추정할 수는 없습니다. 참조는 MODE_TICKVALUE 쿼리 매개변수가 있는 MarketInfo()일 수 있습니다.

 
Mislaid :

따라서 답은 정확하고 정확한 로트 크기를 항상 추정할 수는 없습니다. 참조는 MODE_TICKVALUE 쿼리 매개변수가 있는 MarketInfo()일 수 있습니다.


그래서 오랫동안 고려되었습니다. 적어도 - Vinin 의 아름답게 디자인된 게시물(일치하지 않는 TICKSIZE c POINT 에 대한 잘못된 로트 계산 포함)과 Martingeil 의 이전 게시물(올바른 로트 계산이 있지만 드로다운 ==0을 설정할 수 없음).

가장 중요한 것은 올바른 TICKVALUE 값이 DC에서 도착한다는 것입니다(또는 MT에서 계산된 경우 클라이언트에서 올바르게 계산됨).


이 주제가 시작되었을 때 TICKVALUE 가 아직 존재하지 않는다는 것을 이해했습니다.

그리고 그의 모습으로 모든 것이 단순화되었고이 주제는 잠시 시들었습니다.

추신: 곧 제 버전을 게시할 예정입니다. Vinin의 변형(공식이 더 단순하고 iSL==0 제공)과 Martingeil의 변형(최소 로트에 대한 자금 부족 제어)의 하이브리드입니다.

기능: 1) AccountBalance()가 아닌 AccountFreeMargin()에서 잔액 계산.

2) 그리고 (체인지링의 경우) SL이 오픈 거래를 마감할 때 잔액이 일정 금액만큼 감소하는 것을 고려합니다.

분이라도 자금이 충분하지 않은 경우. 균형 - 로트 크기 -134를 제공합니다(오류 134 - 거래를 열기 위한 자금 부족)

이와 관련하여 Vinin (및 기타 경험 많은 동료)에 대한 질문입니다. 코드 자체에 색상을 지정합니까 아니면 직접 채색합니까? 조각 스타일을 "코드"로 설정하려고 했지만 색상이 지정되지 않았습니다. 아니면 포스트를 그린 후에만 도색되나요?

 
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;
}