SL과 Account Risk를 기반으로 한 자금관리 LOT 사이즈 공식이 필요합니다! - 페이지 3

 

좋아 얘들아! 이 코드는 제가 작성했으며 제 EA에서 사용하고 있습니다. Risk% 및 StopLoss 외에도 Margin Risk%를 고려하고 최소, 최대 및 단계 크기를 기반으로 로트 크기를 수정하기 때문에 매우 복잡합니다. 또한 Current Balance와 Equity 중 하나만 사용하지 않고 항상 최소값을 사용합니다. 나는 그것이 더 안전하다고 느낀다.

단, 사용할 StopLoss를 계산할 때 별도로 계산하기 때문에 계산에 스프레드를 사용하지 않음을 유의하십시오. 따라서 아래 함수는 상대 손절매 크기를 사용합니다. 내 EA의 인수에서 dblStopLossPips 는 전략, 스프레드, ATR 등과 같은 다양한 요소에 따라 미리 계산됩니다. 따라서 dblLotsRisk() 함수에 전달된 최종 값은 사용할 Lot 크기를 계산하기 위한 이미 최종 값입니다.

 // Function to Determine Tick Point Value in Account Currency

         double dblTickValue( string strSymbol )
        {
                 return ( MarketInfo ( strSymbol, MODE_TICKVALUE ) );
        }
        

// Function to Determine Pip Point Value in Account Currency

         double dblPipValue( string strSymbol )
        {
                 double dblCalcPipValue = dblTickValue( strSymbol );
                 switch ( MarketInfo ( strSymbol, MODE_DIGITS ) )
                {
                         case 3 :
                         case 5 :
                                dblCalcPipValue *= 10 ;
                                 break ;
                }
                
                 return ( dblCalcPipValue );
        }
        

// Calculate Lot Size based on Maximum Risk & Margin

         double dblLotsRisk( string strSymbol, double dblStopLossPips,
                 double dblRiskMaxPercent, double dblMarginMaxPercent,
                 double dblLotsMin, double dblLotsMax, double dblLotsStep )
        {
                 double
                        dblValueAccount = MathMin ( AccountEquity (), AccountBalance () )
                ,       dblValueRisk    = dblValueAccount * dblRiskMaxPercent / 100.0
                ,       dblValueMargin  = AccountFreeMargin () * dblMarginMaxPercent / 100.0
                ,       dblLossOrder    = dblStopLossPips * dblPipValue( strSymbol )
                ,       dblMarginOrder  = MarketInfo ( strSymbol, MODE_MARGINREQUIRED )
                ,       dblCalcLotMin
                                = MathMax ( dblLotsMin, MarketInfo ( strSymbol, MODE_MINLOT ) )
                ,       dblCalcLotMax
                                = MathMin ( dblLotsMax, MarketInfo ( strSymbol, MODE_MAXLOT ) )
                ,       dblModeLotStep  = MarketInfo ( strSymbol, MODE_LOTSTEP )
                ,       dblCalcLotStep  = MathCeil ( dblLotsStep / dblModeLotStep ) * dblModeLotStep
                ,       dblCalcLotLoss
                                = MathFloor ( dblValueRisk / dblLossOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLotMargin
                                = MathFloor ( dblValueMargin / dblMarginOrder / dblCalcLotStep ) * dblCalcLotStep
                ,       dblCalcLot = MathMin ( dblCalcLotLoss, dblCalcLotMargin )
                ;
                
                 if ( dblCalcLot < dblCalcLotMin ) dblCalcLot = dblCalcLotMin;
                 if ( dblCalcLot > dblCalcLotMax ) dblCalcLot = dblCalcLotMax;

                 return ( dblCalcLot );
        }
 
GumRai :

이것은 단지 대괄호를 해결하려고 노력하는 나에게 두통을 준다!

솔직히 말해서, 나는 당신이 여기서 달성하려는 것이 무엇인지 전혀 모릅니다.

MODE_STOPLEVEL 또는 SPREAD가 어떻게 관련되는지 알 수 없습니다. 확실히 현재 가격에서 손절매 거리를 기반으로 계산해야 합니까?

계정 통화가 무엇이든 차이가 없어야 하며 TICKVALUE가 계정 통화로 표시되기 때문에 계산이 동일해야 합니다.

코드 줄을 2줄로 배치하면 게시물이 그렇게 넓지 않고 좌우로 스크롤하지 않고도 쉽게 읽을 수 있습니다. :)

나는 몇 페이지를 다시 게시했습니다. 내 공식에서 로트를 계산하는 방법을 설명하는 그림입니다. 그러나 pipvalue 또는 tickvalue 또는 무엇이든 항상 엉망이 됩니다. 인용 -> 기본 통화 및 기타 혼란스러운 것이지만 지금까지는 내 공식 나는 그것이 정확하지 않지만 좋은 일을했습니다.

SPREAD는 관련이 없을 수 있지만 stoplevel은 필요합니다. 나는 SL을 stoplevel인 orderopenprice에 최대한 가깝게 넣었지만 변동과 스파이크 때문에 때때로 수동으로 조정해야 합니다. 그래서 SL을 변동성으로 조정할 수 있는 STOPSLIP 변수를 넣었습니다. .

FMIC :

좋아 얘들아! 이 코드는 제가 작성했으며 제 EA에서 사용하고 있습니다. Risk% 및 StopLoss 외에도 Margin Risk%를 고려하고 최소, 최대 및 단계 크기를 기반으로 로트 크기를 수정하기 때문에 매우 복잡합니다. 또한 Current Balance와 Equity 중 하나만 사용하지 않고 항상 최소값을 사용합니다. 나는 그것이 더 안전하다고 느낀다.

단, 사용할 StopLoss를 계산할 때 별도로 계산하기 때문에 계산에 스프레드를 사용하지 않음을 유의하십시오. 따라서 아래 함수는 상대 손절매 크기를 사용합니다. 내 EA의 인수에서 dblStopLossPips 는 전략, 스프레드, ATR 등과 같은 다양한 요소에 따라 미리 계산됩니다. 따라서 dblLotsRisk() 함수에 전달된 최종 값은 사용할 Lot 크기를 계산하기 위한 이미 최종 값입니다.

고마워, 나는 그것을 테스트하고 내 피드백을 말할 것입니다!

왜 그렇게 많은 변수를 넣었는지 이해가 가지 않지만 전체 코드를 한 줄에 맞출 수 있습니다. :)

 
Proximus :

나는 몇 페이지를 다시 게시했는데, 내 공식에서 로트를 계산하는 방법을 설명했습니다. 그러나 pipvalue 또는 tickvalue 또는 무엇이든 항상 엉망이 됩니다. 인용-> 기준 통화 및 기타 혼란스러운 것이지만 지금까지는 내 공식 나는 그것이 정확하지 않지만 좋은 일을했습니다.

SPREAD는 관련이 없을 수 있지만 stoplevel은 필요합니다. 나는 SL을 stoplevel인 orderopenprice에 최대한 가깝게 넣었지만 변동과 스파이크 때문에 때때로 수동으로 조정해야 합니다. 그래서 SL을 변동성으로 조정할 수 있는 STOPSLIP 변수를 넣었습니다. .

고마워, 나는 그것을 테스트하고 내 피드백을 말할 것입니다!

왜 그렇게 많은 변수를 넣었는지 이해가 가지 않지만 전체 코드를 한 줄에 맞출 수 있습니다. :)


예, 코드를 모두 한 줄에 넣을 수 있지만 저를 믿으십시오. 코드의 모든 마지막 CPU 주기를 지구상에서 가장 빠르게 짜내려고 하지 않는 한 결코 좋은 코딩 방법이 아닙니다.

그렇기 때문에 " GumRai" 는 다른 코드의 머리나 꼬리를 만들려고 하면 두통이 생긴다고 불평했습니다. 그것은 단순히 읽기 어렵거나 쉽게 이해되지 않았기 때문에 디버그하기가 매우 어렵습니다.

내 방식은 더 장황할 수 있지만 디버그 및 유지 관리가 더 쉬울 뿐만 아니라 자신과 같은 다른 사람들이 더 읽기 쉽고 이해하기 쉽습니다.

그러나 자유롭게 한 줄로 압축하십시오. 동일한 결과가 나오지 않더라도 불평하지 마십시오. 디버깅은 여러분에게 맡기겠습니다.

 

이 스레드를 다시 열어서 죄송하지만 무언가를 확인하는 것이 중요하므로 이것이 제가 생각해낸 기능입니다.

 double LOTUNITSTORISK()
{
double LOTS=((AccountBalance()*RISKPERCENT/ 100 ) / (  MarketInfo( Symbol (), MODE_TICKVALUE)*MarketInfo( Symbol (), MODE_TICKSIZE)*STOPSIZE     ));
return LOTS;
}


EUR는 항상 기본 통화이기 때문에 이 함수는 계정 위험을 기반으로 로트 단위를 반환해야 하며 EUR 계정을 통해 계산됩니다.

로트 단위는 위치의 실제 돈 크기를 의미하므로 1% 위험의 100€ 계정의 경우 1€를 반환해야 하며, 예를 들어 100파이펫 손절은 1000로트 단위여야 합니다(0.01 LOT IN MT4 EQUIVALENT).

계정 통화 가 다른 것이 아닌 EURO인 것이 중요합니다.

LOTUNITTORISK()를 호출하면 결과를 100.000으로 나누어 실제 로트 크기를 MT4 형식으로 얻습니다(MT4에서는 1000 현금 단위 0.01 LOT).

RISKPERCENT = 정수 이고 우리가 위험을 감수하는 위험 %는 1,2,3,4일 수 있습니다.

STOPSIZE =는 int 이고 stoploss 크기인 피펫 수(5자리 브로커의 경우 pips/10)이므로 예를 들어 60파이펫 SL은 6핍 SL입니다.

함수가 LOT UNITS를 올바르게 계산하는지 알고 싶습니다. 테스트해 보시고 실수가 있으면 도와주세요 :)

천만 감사합니다!

 
Proximus :
MarketInfo( Symbol (), MODE_TICKVALUE) * MarketInfo( Symbol (), MODE_TICKSIZE)*STOPSIZE

Risk  = lotsize * StopSize * TickValue / TickSize
         1       *   0.0100   *  $ 10.00    / 0.0001
$1000 = one lot * 100 pips *  $ 10.00    / pip
  1. 거래의 이유가 더 이상 유효하지 않은 곳에 중지를 둡니다. 예를 들어 지지 바운스를 거래하면 정지가 지지 아래로 떨어집니다.
  2. 계정 잔고 * 퍼센트 = 위험 = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (참고 OOP-OSL에는 SPREAD가 포함됨)
  3. TickValue 자체를 사용하지 마십시오 - DeltaPerlot
  4. 중단 을 피하기 위해 FreeMargin도 확인해야 합니다.
 
WHRoeder :
  1. 거래의 이유가 더 이상 유효하지 않은 곳에 중지를 둡니다. 예를 들어 지지 바운스를 거래하면 정지가 지지 아래로 떨어집니다.
  2. 계정 잔고 * 퍼센트 = 위험 = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots * DeltaPerlot (참고 OOP-OSL에는 SPREAD가 포함됨)
  3. TickValue 자체를 사용하지 마십시오 - DeltaPerlot
  4. 중단 을 피하기 위해 FreeMargin도 확인해야 합니다.

1) 이 함수는 MT4 단위가 아닌 화폐 단위로 LOT SIZE만 반환합니다. 주문을 입력하면 각각 STOPSIZE가 추가/중단됩니다. 매수의 경우 입찰가에서, 매도의 경우 매도인입니다. MT4는 TP와 SL을 처리합니다.

BUY는 ASK에서 열리고 BID에서 마감됨

BID에서 SELL 시작, ASK에서 마감

2) 이 함수가 계산되기 전에 개설된 주문이 없기 때문에 OrderOpenprice man을 사용할 수 없습니다. 스프레드는 포함되지 않으며, 주문이 열린 후 STOPSIZE를 더하거나 빼면 스프레드가 처리됩니다.

그러나 그 전에 로트 크기를 결정해야 하므로 논리적입니다.

3) 나는 이것을 이해하지 못한다.

4) 분명히, 그러나 나는 주문 배치 기능이 이 후에 실행되며 이 기능과 거의 관련이 없음을 다시 강조합니다. 이 기능의 유일한 목적은 로트 크기를 결정하는 것뿐입니다.


TickValue / TickSize

틀림, 나누면 잘못된 숫자가 나옵니다. USD 계정의 경우 그렇게 해야 하지만 EUR 계정은 곱해야 합니다.

 
Proximus :

ASK에서 BUY 오픈, BID에서 마감 SELL BID에서 오픈, ASK에서 마감

2) OrderOpenprice를 사용할 수 없습니다.

3) 나는 이것을 이해하지 못한다.

4) t, 나누면 잘못된 숫자가 나옵니다. USD 계정은 그렇게 해야 하지만 EUR 계정은 곱해야 합니다.

  1. Ask 는 구매에 대한 OrderOpenPrice 입니다.
  2. Bid 는 판매에 대한 OrderOpenPrice 입니다. 왜 그것을 사용할 수 없습니까? OrderSend에 전달하려면 알아야 합니까?
  3. 반드시 tickvalue/ticksize를 사용해야 합니다. Tickvalue 자체는 의미가 없습니다.
  4. 정확한 단위를 얻으려면 나누어야 합니다. (Change in price) * (tickValue) /(change in price)는 값을 제공합니다. 핍당 $10 = 포인트당 $1 = 가치/변경. 의 결과는 계정 통화 라는 것을 기억하십시오. 따라서 이를 위험으로 나눌 때 순수한 숫자를 얻게 되며, 다시 단위는 $risk(BAL%)/$risk(SL)을 취소합니다. 여러 번 수행해야 하는 경우 잘못된 작업을 수행하거나 브로커 값이 엉망이 됩니다.
 
WHRoeder :
근위부 :

ASK에서 BUY 오픈, BID에서 마감 SELL BID에서 오픈, ASK에서 마감

2) OrderOpenprice를 사용할 수 없습니다.

3) 나는 이것을 이해하지 못한다.

4) t, 나누면 잘못된 숫자가 나옵니다. USD 계정은 그렇게 해야 하지만 EUR 계정은 곱해야 합니다.

  1. Ask 는 구매에 대한 OrderOpenPrice 입니다.
  2. Bid 는 판매에 대한 OrderOpenPrice 입니다. 왜 그것을 사용할 수 없습니까? OrderSend에 전달하려면 알아야 합니까?
  3. 반드시 tickvalue/ticksize를 사용해야 합니다. Tickvalue 자체는 의미가 없습니다.
  4. 정확한 단위를 얻으려면 나누어야 합니다. (Change in price) * (tickValue) /(change in price)는 값을 제공합니다. 핍당 $10 = 포인트당 $1 = 가치/변경. 의 결과는 계정 통화라는 것을 기억하십시오. 따라서 이를 위험으로 나눌 때 순수한 숫자를 얻게 되며, 다시 단위는 $risk(BAL%)/$risk(SL)을 취소합니다. 여러 번 수행해야 하는 경우 잘못된 작업을 수행하거나 브로커 값이 엉망이 됩니다.


1,2 알지만 다른 함수에서 처리하는 것은 이 함수와 아무 관련이 없음을 이해합니다.

3) 내가 이해하는 것처럼 tickvalue는 기본 통화의 1핍 값이므로 사용하는 쌍에 따라 나누거나 곱해야 합니다. EUR 계정의 경우 곱하지 않아도 되는 것 같습니다. 나누다.

더 잘 설명하는 사진은 다음과 같습니다.


3% 위험 거래의 EUR/USD에서 1798개를 열어야 하며 이를 달성하려면 MT4 단위로 0.02LOTS를 반올림해야 합니다.

STOPLOSS 크기는 다른 함수에 의해 결정됩니다.

내가 테스트했을 때 올바른 것 같지만 공식이 정말 정확한지 확실하지 않습니다. 그것이 내가 여기서 결정하려고하는 것이므로 도와주세요.

 

저 역시 마진 콜 레벨이 100%가 아니라 예를 들어 120%일 때 SL, 계정 위험 및 마진 콜 레벨을 기반으로 하는 이 로트 크기 계산을 알아내려고 노력했습니다. 내가 찾은 최고의 답변은 WHRoeder가 그의 whrea.mq4 코드에서 공유한 입니다. whrea.mq4 코드는 약간의 수정이 필요했지만 WHRoederRaptorUK의 의견 에 대한 답변에서 이미 수정을 제공했습니다. 따라서 로트 크기 계산에 대한 완전한 답이 있지만 WHRoeder가 공유한 내용을 완전히 이해하려면 약간의 노력이 필요합니다.

나는 WHRoeder의 whrea.mq4에서 코드를 추출하고 수정하여 최신 새 MT4 빌드로 컴파일하여 마진 콜 레벨이 100% 이상인 장기 거래에 대한 로트 크기를 계산하는 코드를 첨부했습니다.

그러나 마진 콜을 피하기 위해 마진 콜 레벨 %를 고려하기 위해 MarginCallLevel %를 곱하는 것이 올바른지 확실하지 않습니다. MarginCallLevel이 100%이면 두 코드 줄 모두 정확하지만 MarginCallLevel이 120%이면 MarginCallLevel %를 곱하면 올바른 마진 호출 테스트가 될까요? 그렇지 않은 경우 이를 수행하는 올바른 방법은 무엇입니까? WHRoeder, 이것 좀 도와주시겠어요? 윌리엄, 나는 최선을 다했다.

다음은 장기 거래에 대한 마진 테스트 섹션의 코드입니다.

 extern double MarginCallLevel = 120 ; //As a percentage

double MarginCallLevel1 = MarginCallLevel * 0.01 ; 

         double   AFMC    = AccountFreeMarginCheck( Symbol (), OP_BUY, tradesize),
                        eRisk   = equityatrisk + atrisk new ;

         //Test for margin
         //Note: Not sure if multiplying by the MarginCallLevel % here is correct to 
         //take the Margin Call Level % into account for avoiding a margin call.
         //If the MarginCallLevel is 100% then both lines of code would be correct
         //but if the MarginCallLevel is 120% would multiplying by the MarginCallLevel %
         //be a correct Margin Call test? If not, then what is the correct way to do this?

         //if (AFMC*0.99 <= eRisk){
         if (AFMC* 0.99 <= eRisk*MarginCallLevel1){
            tradesize *= 0.95 ;     // Must still round to lotStep.
             continue ;   }   // Prevent margin call if new trade goes against us.
파일:
 

... 코드의 이 부분에서 새 컴파일에 문제가 있습니다(오류 ---> 'MarketInfo' - 잘못된 스위치 표현식 유형). 아마도 MT4 빌드 600+로 업데이트하기 전까지는 모두 괜찮았을 것입니다 ... 하지만 그 이후로는 더 이상 작동하지 않습니다.

 // Function to Determine Pip Point Value in Account Currency

         double dblPipValue( string strSymbol )
        {
                 double dblCalcPipValue = dblTickValue( strSymbol );
                 switch ( MarketInfo ( strSymbol, MODE_DIGITS ) )
                {
                         case 3 :
                         case 5 :
                                dblCalcPipValue *= 10 ;
                                 break ;
                }
                
                 return ( dblCalcPipValue );
        }
        

따라서 최신 버전을 게시해 주시겠습니까? 물론 아직 사용 중이라면.