SLと口座リスクに基づいたマネーマネジメントのLOTサイズ計算式が必要! - ページ 3

 

OK みんな!このコードは私が書いたもので、私自身のEAで使用しているものです。このコードは非常に複雑で、Risk%とStopLossの他に、マージンリスクも考慮し、さらにMinimum, Maximum, Step Sizeに基づいてロットサイズを補正しています。また、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などは常に混乱します。quote->base currencyや 他のものは混乱しますが、今のところ私の式は良い仕事をしました。

SPREADは関係ないかもしれませんが、stoplevelは必要です。私はSLをorderopenpriceにできるだけ近いところに置きますが、変動やスパイクのために、私は時々それを手動で調整する必要があります。

FMIC

OK みんな!このコードは私が書いたもので、私自身のEAで使用しているものです。 このコードはかなり複雑で、Risk%とStopLossの他に、マージンリスクも考慮し、Minimum, Maximum, Step Sizeに基づいてLot Sizeを補正します。また、Current BalanceとEquityのどちらか一方だけを使用するのではなく、常に最小値を使用します。その方がより安全だと思います。

ただし、スプレッドについては、StopLossを計算する際に別途計算しているので、計算に使用しないことに注意してください。下の関数は、相対的なストップロス・サイズを使用します。私のEAでは、引数dblStopLossPipsは 戦略、スプレッド、ATRなどの様々な要因によって事前に計算されます。したがって、dblLotsRisk() 関数に渡される最終値は、使用するLotサイズを計算するためにすでに最終値になっているのです。

ありがとうございます、テストして私のフィードバックをお伝えします。

なぜ多くの変数をそこに置くのか理解できませんが、コード全体は1行に収まるはずです :)

 
Proximus:

しかし、pipvalueやtickvalueやその他は常に混乱します。quote->base currencyやその他は混乱しますが、今のところ、私の式は正しいかどうかわかりませんが、良い仕事をしました。

SPREADは関係ないかもしれませんが、stoplevelは必要です。私はSLをstoplevelであるorderopenpriceにできるだけ近いところに置きますが、変動やスパイクのために、私は時々それを手動で調整する必要があります。

ありがとうございます、テストしてフィードバックします。

でも、なぜそんなにたくさんの変数を入れたのか理解できませんが、コード全体は1行に収まるはずです :)


確かにコードはすべて1行にまとめることもできますが、信じてください、それは決して良いコーディング方法ではないのです。

だから、"GumRai " は、他のコードを理解するのに頭痛がすると文句を言ったのです。そのため、"GumRai "は他のコードを理解するのに苦労したと言っています。

私の方法は、より冗長かもしれませんが、デバッグやメンテナンスがしやすく、あなたのような他の人にも読みやすく、理解しやすい方法です。

しかし、すべてを1行にまとめるのは自由です。ただ、同じような結果が得られなくても、文句を言わないでくださいね。デバッグはあなたにお任せします。

 

このスレッドを再開して申し訳ありませんが、何かを確認することが重要なので、これは私が思いついた関数です(私はそれを公開しています。)

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ロット単位(MT4で同等の0.01ロット)になるはずです。

口座の通貨が ユーロであることが重要であり、それ以外のものはありません。

LOTUNITTORISK()を呼び出したら、結果を100.000で割って、MT4形式の実際のロットサイズを取得します(MT4では1000キャッシュユニット0.01ロット)。

RISKPERCENT=intで 、1,2,3,4とすることができ、リスクを負う%です。

STOPSIZE= はint 型で、ストップロスのサイズをピペット数(5桁のブローカーでは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(Note OOP-OSL は SPREAD を含む)
  3. TickValue を単独で使用しないでください -DeltaPerlot
  4. ストップアウトを 避けるために、FreeMarginもチェックする必要があります。
 
WHRoeder:
  1. ストップを置くべき場所、つまり取引の理由がもはや有効でない場所に置くのです。例:サポートの跳ね返りを取引する場合、ストップはサポートより下になります。
  2. 口座残高 * パーセント = リスク = (OrderOpenPrice - OrderStopLoss)*DIR * OrderLots *DeltaPerlot(Note OOP-OSL は SPREAD を含む)
  3. TickValue をそれ自体で使用しないでください -DeltaPerlot
  4. ストップアウトを 避けるために、FreeMarginもチェックする必要があります。

1) この関数はLOT SIZEをMT4単位ではなく、お金単位で返すだけです。

買いはASKで始まり、BIDで終了します。

売りはBIDでオープン、ASKでクローズ

2) OrderOpenprice manは使えません。なぜなら、この関数が計算される前に注文がオープンされていないからです。

しかし、その前に、我々はロットサイズを決定する必要があります、それは論理的です。

3) 私はこれを理解していません。

4) 当然ですが、注文の発注機能はこの後に実行され、この機能とはほとんど関係ないことを再度強調します。この関数の唯一の目的はロットサイズを決定することであり、それ以外には何もありません。


TickValue /  TickSize

私はそれらを分割した場合、私は間違った番号を取得し、多分米ドル口座のためにそうする必要がありますが、そのEUR account.Theyが乗算されなければならない、間違っている。

 
Proximus:

ASKで買い、BIDで売り、BIDで売り、ASKで買い。

2) OrderOpenpriceは使えません。

3) これがわからない。

4)t, if I divide them then i get the wrong number, maybe for USD accounts should be done so, but its an EUR account.They must be multiplied.

  1. Askは買いのOrderOpenPrice です。
  2. Bidは売りのOrderOpenPrice です。なぜそれを使うことができないのでしょうか。OrderSend に渡すには、それを知っていなければなりません。
  3. tickvalue/ticksizeを使用しなければなりません。tickvalue単体では意味がありません。
  4. 単位を正しく取得するためには、割り算をしなければなりません。10ドル/ピップ = 1ドル/ポイント = 値/変化 です。この結果は口座の通貨 であり、リスクで割ると純粋な数字になることを忘れないでください。もし、倍数でなければならないなら、何か間違ったことをしているか、ブローカーの値が狂っているのでしょう。
 
WHRoeder:
プロキシマス

買いはASKでオープン、BIDでクローズ 売りはBIDでオープン、ASKでクローズ

2)OrderOpenpriceが使えません。

3) これがわからない。

4)t, if I divide them then i get the wrong number, maybe for USD accounts should be done so, but its an EUR account.They must be multiplied.もし私がそれらを割ったら、私は間違った番号を得るでしょう。

  1. Askは買いのOrderOpenPrice です。
  2. Bidは売りのOrderOpenPrice です。なぜそれを使うことができないのでしょうか。OrderSend に渡すには、それを知っていなければなりません。
  3. tickvalue/ticksizeを使用しなければなりません。tickvalue単体では意味がありません。
  4. 単位を正しく取得するためには、割り算をしなければなりません。10ドル/ピップ = 1ドル/ポイント = 値/変化 です。この結果は口座の通貨であり、リスクで割ると純粋な数字になることを忘れないでください。もし、倍数でなければならないなら、何か間違ったことをしているか、ブローカーの値が狂っているのでしょう。


1,2 それは知っていますが、それは別の関数で処理され、この関数とは関係がないことを理解してください。

3) 私が理解しているように、tickvalueは基準通貨での1pipの値です。ですから、私が使用するペアによっては、それを割るか掛ける必要があります。

ここにそれをよりよく説明する写真があります。


EUR/USDで3%のリスクの取引では、1798単位を開く必要があり、それを達成するためにMT4単位で0.02ロットを丸めたものです。

ストップロスの大きさは別の機能で決定されます。

テストしたところ正しいようですが、この式が本当に正確なのかどうか、それを判断したいのです。

 

私も、SL、口座リスク、マージンコールレベルに基づくロットサイズの計算について、特にマージンコールレベルが100%ではなく、例えば120%である場合の計算を理解しようとしています。私が見つけた最良の答えは WHRoederがwhrea.mq4 コードで共有しているものです。 whrea.mq4コードには修正が必要ですが、WHRoederはRaptorUKの コメントに対する 彼の答えで すでにその修正を行っています。つまり、ロットサイズ計算の完全な答えはそこにありますが、WHRoederが共有したものを完全に理解するためには、多少の努力が必要です。

マージンコールレベルが100%以上のロングトレードのロットサイズを計算するために、WHRoederのwhrea.mq4からコードを抽出して修正し、最新の新しいMT4ビルドでコンパイルしたコードを添付しました。

しかし、マージンコールを回避するためにマージンコールレベル%を考慮するために、MarginCallLevel%を掛けることが正しいかどうかはわかりません。もしMarginCallLevelが100%であれば、どちらのコードも正しいのですが、もしMarginCallLevelが120%であれば、MarginCallLevel %を掛けることは正しいマージンコールテストとなるのでしょうか。そうでない場合、どのような方法が正しいのでしょうか?WHRoederさん、手伝ってくれませんか?William、頑張ってみました。

以下は、そのMargin TestセクションのLongトレードのコードです。

extern double MarginCallLevel = 120; //As a percentage

double MarginCallLevel1 = MarginCallLevel * 0.01; 

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

        //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 +への更新まではすべてOKでした...しかし、それ以来、それはもう動作しません。

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

そこで、何か新しいバージョンを投稿していただけないでしょうか・・・もちろん、まだご存じであればの話ですが。