
MQL5レシピ - オープンヘッジポジションのプロパティを取得しましょう
概論
比較的最近、MetaTrader 5取引端末に多方向に注文を開く機能が現れました。この注文計算システムを『ヘッジ』といいます。この注文システムの存在により、全ての最新の利点を活用しながら、MetaTrader 4から5に取引アルゴリズムを簡単に転送することができます。MetaTrader 5のヘッジに関する詳細については、『MetaTrader 5にヘッジポジション計算システムが追加されました。』という資料をご参照ください。
この記事では、『ヘッジ』システムで扱われるポジション集計のプロパティに焦点を当てます。
1. ヘッジポジションとタイプ
ヘッジ(累積)ポジションは、いくつかのマーケットオーダーによって形成されるマーケットポジションです。狭義では、ヘッジポジション(ヘッジ)には多方向の注文(売りと買い)が含まれます。とはいえ、広義での『ヘッジ』という言葉を使うことを提案したいと思います。同時に、ヘッジポジションも一方向の注文に集約することにしましょう。このアプローチは、MetaTrader 5端末の、一方向への注文も、別の方向への注文も可能であるという機能に起因します。
ポジションの集約を分類するには、いくつかの方法があります。おそらく、最も人気のある基準は、1つまたは他の集計ポジションを形成するマーケットオーダーのタイプによってポジションを区別する基準です。では、どのような注文でこういったポジションにすることができるでしょうか?以下の表1は種々の組み合わせを示しています。
№ | タイプ | 説明 |
---|---|---|
1 | Hedge buy | 買いのみ |
2 | Hedge netting buy | 『純粋な』買い |
3 | Hedge sell | 売りのみ |
4 | Hedge netting sell | 『純粋な』売り |
5 | Hedge locked | ロック(完全なヘッジ) |
表1ヘッジタイプ
これらのタイプについて簡単に説明します。集約したポジションに買いまたは売りの注文のみある場合(MetaTrader 4ターミナル)、hedge buyまたはhedge sellでポジションを計算します。ポジションに複数の注文(買いと売りの両方)がある場合は、どの注文がより多いかを調べます。買い注文の方が多い場合、hedge netting buyポジションになります。売り注文が多い場合、hedge netting sellとなります。より正確に言うならば、注文の数ではなく、そのボリュームについて言及する必要があります。仮にポジションに1.25ロットのボリュームの買い注文が1つあり、0.5ロットと0.6ロットの売り注文が2つあるとします。その結果、ポジションは0.15ロットの純買いポジション(hedge netting buy)になります。
1,25 – (0,5 + 0,6) = 0,15
取引量の観点から買いと売りのバランスをとる、ポジションが混在する特別な種類のものがロックです。
記載されている種類のヘッジは、次のようになります。
//+------------------------------------------------------------------+ //| Hedge type | //+------------------------------------------------------------------+ enum ENUM_HEDGE_TYPE { HEDGE_BUY=0, // buy HEDGE_SELL=1, // sell HEDGE_NETTING_BUY=2, // netting buy HEDGE_NETTING_SELL=3, // netting sell HEDGE_LOCKED=4, // lock };
『ネッティング』のシステムに目を向けると、定義上累積的にそのポジションは、買いまたは売りの2つのタイプのうちの1つのみを参照することができます。識別子は、列挙値の1つ ENUM_POSITION_TYPEです。
1)POSITION_TYPE_BUY
2)POSITION_TYPE_SELL
『ヘッジ』システムでは、5種類の集約ポジションを取得します。
次のセクションでは、ヘッジポジションのプロパティを扱うクラスを作成します。
2. CHedgePositionInfoクラス
標準ライブラリには、オープンマーケットポジションのプロパティへのアクセスできるCPositionInfoクラスがあります。私たちの場合、このクラスは部分的にしか有用ではありません。というのも、これが処理するポジションは、別のマーケット注文(MetaTrader 4)として提示されるらです。そして私達には、集約ポジション(ヘッジ)を形成するすべてのポジションを一度に処理するクラスが必要です。
OOP-toolsを使って、CHedgePositionInfoクラスを作成してみましょう。
//+------------------------------------------------------------------+ //| Class CHedgePositionInfo | //| Purpose: Class for access to a hedge position info. | //| Derives from class CObject. | //+------------------------------------------------------------------+ class CHedgePositionInfo : public CObject { //--- === Data members === --- private: ENUM_HEDGE_TYPE m_type; double m_volume; double m_price; double m_stop_loss; double m_take_profit; ulong m_magic; //--- objects CArrayLong m_tickets; CSymbolInfo m_symbol; CPositionInfo m_pos_info; //--- === Methods === --- public: //--- constructor/destructor void CHedgePositionInfo(void){}; void ~CHedgePositionInfo(void){}; //--- initialization bool Init(const string _symbol,const ulong _magic=0); //--- get methods CSymbolInfo *Symbol(void) {return GetPointer(m_symbol);}; CArrayLong *HedgeTickets(void) {return GetPointer(m_tickets);}; CPositionInfo *PositionInfo(void) {return GetPointer(m_pos_info);}; ulong Magic(void) const {return m_magic;}; //--- fast access methods to the integer hedge properties datetime Time(void); ulong TimeMsc(void); datetime TimeUpdate(void); ulong TimeUpdateMsc(void); ENUM_HEDGE_TYPE HedgeType(void); //--- fast access methods to the double hedge properties double Volume(double &_buy_volume,double &_sell_volume); double PriceOpen(const ENUM_TRADE_TYPE_DIR _dir_type=TRADE_TYPE_ALL); double StopLoss(const ENUM_TRADE_TYPE_DIR _dir_type=TRADE_TYPE_ALL); double TakeProfit(const ENUM_TRADE_TYPE_DIR _dir_type=TRADE_TYPE_ALL); double PriceCurrent(const ENUM_TRADE_TYPE_DIR _dir_type=TRADE_TYPE_ALL); double Commission(const bool _full=false); double Swap(void); double Profit(void); double Margin(void); //--- fast access methods to the string hedge properties string TypeDescription(void); //--- info methods string FormatType(string &_str,const uint _type) const; //--- select bool Select(void); //--- state void StoreState(void); bool CheckState(void); private: //--- calculation methods bool AveragePrice( const SPositionParams &_pos_params, double &_avg_pr, double &_base_volume, double &_quote_volume ); int CheckLoadHistory(ENUM_TIMEFRAMES period,datetime start_date); }; //+------------------------------------------------------------------+
クラスデータの構成について少し触れたいと思います。
まず、ユニークなシンボルがあります。すなわちヘッジポジションには、任意の1つのシンボルのポジションを含めることができます。 CSymbolInfoクラスインスタンスを与える、m_symbolフィールドがシンボルを担当します。
第2に、マジック(m_magic)を必要なオーダーのフィルターとして設定することができます。このようにすることで、1つトレーディングアドバイザーが担当しているポジションを作成することが可能です。したがって、1つのシンボルで複数のヘッジを作成することができます。
また注文集計(m_tickets)のための動的配列もあります。ここにはヘッジポジションのチケットが入ります。
1つの選択したポジション(MetaTrader 4でのマーケットオーダー)のプロパティを取得する機能は、CPositionInfo(m_pos_info)クラスのインスタンスに割り当てられます。
ヘッジのその他のプロパティは、その状態を評価するために必要です。
- タイプ(m_type)
- ボリューム(m_volume)
- 開始値(m_price)
- ストップロス値(m_stop_loss)
- テイクプロフィット値(m_take_profit)
クラスを構築するための基礎として、CPositionInfoクラスの論理が採用されたことに注目することは重要です。 そして、それはとても自然なことです。したがって、新しいクラスには、整数プロパティ、doubleプロパティなどを返すメソッドがあります。もちろん、特別なメソッドもあります。
2.1初期化メソッド
クラスの機能を使用する前に、対応するインスタンスを初期化する必要があります。この方法は、第1にアドバイザーがヘッジシステム内で正確に動作し、第2に希望するシンボルが選択され、マジックナンバーが設定されているかをチェックします。
//+------------------------------------------------------------------+ //| Initialization | //+------------------------------------------------------------------+ bool CHedgePositionInfo::Init(const string _symbol,const ulong _magic=0) { //--- account margin mode ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); if(margin_mode!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) { Print(__FUNCTION__+": no retail hedging!"); return false; } if(!m_symbol.Name(_symbol)) { Print(__FUNCTION__+": a symbol not selected!"); return false; } ENUM_SYMBOL_CALC_MODE symbol_calc_mode=(ENUM_SYMBOL_CALC_MODE)SymbolInfoInteger(_symbol,SYMBOL_TRADE_CALC_MODE); if(symbol_calc_mode!=SYMBOL_CALC_MODE_FOREX) { Print(__FUNCTION__+": only for Forex mode!"); return false; } m_magic=_magic; //--- return true; } //+------------------------------------------------------------------+
このメソッドは、後続のヘッジクラス機能の使用に必須です。このメソッドでは、マージン計算モードがチェックされることに注意してください。『ヘッジ』と一致しない場合、メソッドはfalseを返します。また、契約価格を計算する方法もチェックされます。私たちはForex契約のみ取り扱うことにします。
2.2整数プロパティ
整数プロパティへのアクセスは、メソッドを使用して実行されます。
- datetime Time(void);
- ulong TimeMsc(void);
- datetime TimeUpdate(void);
- ulong TimeUpdateMsc(void);
- ENUM_HEDGE_TYPE HedgeType(void).
例として、CHedgePositionInfo::Time()メソッドのコードを見てみましょう。
//+------------------------------------------------------------------+ //| Get the hedge open time | //+------------------------------------------------------------------+ datetime CHedgePositionInfo::Time(void) { datetime hedge_time=WRONG_VALUE; int hedge_pos_num=m_tickets.Total(); //--- if any positions if(hedge_pos_num>0) { //--- find the first opened position for(int pos_idx=0;pos_idx<hedge_pos_num;pos_idx++) { ulong curr_pos_ticket=m_tickets.At(pos_idx); if(curr_pos_ticket<LONG_MAX) if(m_pos_info.SelectByTicket(curr_pos_ticket)) { datetime curr_pos_time=m_pos_info.Time(); if(curr_pos_time>0) { if(hedge_time==0) hedge_time=curr_pos_time; else { if(curr_pos_time<hedge_time) hedge_time=curr_pos_time; } } } } } //--- return hedge_time; } //+------------------------------------------------------------------+
ヘッジの開始時間、つまりヘッジの最初のポジションを取得するには、すべてのポジションを通過して、 一番早いものを見つける必要があります。
しかし、ヘッジを変更した時間、つまり最後の変更があったポジションを取得するには、以前のメソッドを少し修正する必要があります。
//+------------------------------------------------------------------+ //| Get the hedge update time | //+------------------------------------------------------------------+ datetime CHedgePositionInfo::TimeUpdate(void) { datetime hedge_time_update=0; int hedge_pos_num=m_tickets.Total(); //--- if any positions if(hedge_pos_num>0) { //--- find the first opened position for(int pos_idx=0;pos_idx<hedge_pos_num;pos_idx++) { ulong curr_pos_ticket=m_tickets.At(pos_idx); if(curr_pos_ticket<LONG_MAX) if(m_pos_info.SelectByTicket(curr_pos_ticket)) { //--- get the current position update time datetime curr_pos_time_update=m_pos_info.TimeUpdate(); if(curr_pos_time_update>0) if(curr_pos_time_update>hedge_time_update) hedge_time_update=curr_pos_time_update; } } } //--- return hedge_time_update; } //+------------------------------------------------------------------+
ヘッジの種類を識別するメソッドは、以下のように符号化されます。
//+------------------------------------------------------------------+ //| Get the hedge type | //+------------------------------------------------------------------+ ENUM_HEDGE_TYPE CHedgePositionInfo::HedgeType(void) { ENUM_HEDGE_TYPE curr_hedge_type=WRONG_VALUE; int hedge_pos_num=m_tickets.Total(); //--- if any positions if(hedge_pos_num>0) { //--- get the volumes double total_vol,buy_volume,sell_volume; buy_volume=sell_volume=0.; total_vol=this.Volume(buy_volume,sell_volume); //--- define a hedge type if(buy_volume>0. && sell_volume>0.) { if(buy_volume>sell_volume) curr_hedge_type=HEDGE_NETTING_BUY; else if(buy_volume<sell_volume) curr_hedge_type=HEDGE_NETTING_SELL; else curr_hedge_type=HEDGE_LOCKED; } else if(buy_volume>0. && sell_volume==0.) curr_hedge_type=HEDGE_BUY; else if(buy_volume==0. && sell_volume>0.) curr_hedge_type=HEDGE_SELL; } //--- return curr_hedge_type; }; //+------------------------------------------------------------------+
ヘッジの種類は、買いおよび売りのボリュームの違いによります。最初にヘッジが、実際に狭義のものであるかどうかをチェックします。買いの量と売りの量が等しい場合、ヘッジは完全なものです。不均等である場合、部分的なヘッジを扱っていることになります。
その後ヘッジが買いか売りのみによって表されていないかどうかをチェックします。
2.3Doubleプロパティ
ダブルプロパティへのアクセスは、以下のメソッドによって実行されます。
- double Volume(double &_buy_volume,double &_sell_volume);
- double PriceOpen(void);
- double StopLoss(void);
- double TakeProfit(void);
- double PriceCurrent(void);
- double Commission(void);
- double Swap(void);
- double Profit(void);
- double Margin(void).
ヘッジ量を判別するメソッドが、リンク形式のパラメータを持っていることは簡単にわかります。この実装では、ヘッジ自体のボリュームとそのコンポーネント(買いと売り)の両方を即座に取得することができます。
//+------------------------------------------------------------------+ //| Get the hedge volume | //+------------------------------------------------------------------+ double CHedgePositionInfo::Volume(double &_buy_volume,double &_sell_volume) { double total_vol=0.; int hedge_pos_num=m_tickets.Total(); //--- if any positions if(hedge_pos_num>0) { _buy_volume=_sell_volume=0.; //--- get the buy\sell volumes for(int pos_idx=0;pos_idx<hedge_pos_num;pos_idx++) { ulong curr_pos_ticket=m_tickets.At(pos_idx); if(curr_pos_ticket<LONG_MAX) if(m_pos_info.SelectByTicket(curr_pos_ticket)) { ENUM_POSITION_TYPE curr_pos_type=m_pos_info.PositionType(); double curr_pos_vol=m_pos_info.Volume(); if(curr_pos_vol>0.) { //--- for a buy position if(curr_pos_type==POSITION_TYPE_BUY) _buy_volume+=curr_pos_vol; //--- else for a sell position else if(curr_pos_type==POSITION_TYPE_SELL) _sell_volume+=curr_pos_vol; } } } total_vol=_buy_volume-_sell_volume; } //--- return total_vol; } //+------------------------------------------------------------------+
価格プロパティを操作するための補助メソッドCHedgePositionInfo::AveragePrice()が作成されました。価格レベルのタイプに応じてヘッジの平均価格を考慮するコードのブロックは以下の通りです。
//--- if the hedge volumes calculated if(hedge_base_volume!=0. && hedge_quote_volume!=0.) { _avg_pr=fabs(hedge_quote_volume/hedge_base_volume); _base_volume=hedge_base_volume; _quote_volume=hedge_quote_volume; return true; }
値アプローチは、見積通貨におけるヘッジの最終価値と基本通貨におけるヘッジの最終価値との比率です。
後で例を使って作業するときに、実際の計算をしてみましょう。
スワップおよび利益を得るためのメソッドは、ヘッジの各ポジションの対応する指標を集計し、合計金額を返します。手数料を取得するメソッドは、オープンポジションに参加した取引を分析します。手数料の額をどのように計算するかをパラメータを通して選択することができます。エントリ取引だけで取得する場合は、デフォルトのパラメータをそのまま使用します。エントリとクローズの手数料を計算する必要がある場合、パラメーターはtrueと等しくなければなりません。後者のメソッドはいくつかの理由から、大体のものであることに注意してください。まず、選択されたポジションを閉じることができます。すると、DEAL_ENTRY_OUT_BYタイプの取引が出現します。これらに対して手数料は請求されません。第2に、もし口座の通貨が基本通貨と一致しない場合、レートの変動時にエントリとクローズの価格が異なる場合があります。
//+------------------------------------------------------------------+ //| Get the hedge commission | //+------------------------------------------------------------------+ double CHedgePositionInfo::Commission(const bool _full=false) { double hedge_commission=0.; int hedge_pos_num=m_tickets.Total(); //--- if any positions if(hedge_pos_num>0) for(int pos_idx=0;pos_idx<hedge_pos_num;pos_idx++) { ulong curr_pos_ticket=m_tickets.At(pos_idx); if(curr_pos_ticket<LONG_MAX) if(m_pos_info.SelectByTicket(curr_pos_ticket)) { long curr_pos_id=m_pos_info.Identifier(); if(curr_pos_id>0) //--- retrieve the history of deals associated with the selected position if(HistorySelectByPosition(curr_pos_id)) { CDealInfo curr_deal; int deals_num=HistoryDealsTotal(); for(int deal_idx=0;deal_idx<deals_num;deal_idx++) if(curr_deal.SelectByIndex(deal_idx)) { ENUM_DEAL_ENTRY curr_deal_entry=curr_deal.Entry(); if(curr_deal_entry==DEAL_ENTRY_IN) { double curr_deal_commission=NormalizeDouble(curr_deal.Commission(),2); if(curr_deal_commission!=0.) { double fac=1.; if(_full) fac=2.; hedge_commission+=(fac*curr_deal_commission); } } } } } } //--- return hedge_commission; } //+------------------------------------------------------------------+
クラスにはCHedgePositionInfo::Margin()というメソッドがあり、ヘッジポジションのマージンの値を判定することができます。実際、このメソッドはプログラムするのが最も難しいものでした。未決済ポジションと保留中の注文のマージンのサイズを正しく判別するメソッドに関して、1つの記事が書けるほどです。
2.3.1ヘッジポジションに関する権利
開発者が示しているように、多方向のポジションの場合、ブローカーによって決定されるマージンの計算方法が2つあります。最初の方法は基本的な計算に基づいており、2番目の方法は最大の側面で実装されています。
私は第2の計算方法に出会えなかったことを認めます。それにもかかわらず、これをプログラムします。しかし、まず最初にマージンの計算を含むもっと複雑なアルゴリズムを持つ最初の方法を検討することを提案します。
- カバーされていないボリューム
- ヘッジボリューム(ヘッジマージンが示されている場合)
- 保留中の注文
この記事のマージンは、Retail Forex、Futuresをモデルに計算しています。保留中のオーダーのマージンの計算は考慮されていません。
ヘッジポジションのマージンを計算するには、以下のパラメータに関する情報が必要です。
- デポジット通貨。原則として、口座は米ドル(USD)、ユーロ(EUR)、ポンド(GBP)、フラン(CHF)で表示されます。
- マージン通貨。原則として、これはシンボルの基本通貨です。たとえば、EURUSDの場合はユーロ(EUR)、AUDNZDの場合は豪ドル(AUD)です。
- レバレッジのサイズ。
また、端末の[貿易]タブの残高明細では、預金通貨にマージン価格が表示されます。したがって、計算の結果は、預金通貨のマージンの値である必要があります。
マージン通貨が預金通貨と一致しない可能性があるため、計算アルゴリズムにはいくつかのオプションがあります。
- 預金通貨がヘッジポジションシンボルに基本通貨として存在する場合。ドル口座でUSDCHFを取引している場合など。
- ヘッジポジションシンボルに預金通貨が引用通貨の形式で存在する場合。ドル口座でEURUSDを取引している場合など。
- 預金通貨がヘッジポジションのシンボルにないとき。AUDNZDをドル口座で取引している場合など。
最初のオプションは最も簡単に計算でき、最後は最も難しいです。会計作業をして、各オプションの例を考えましょう。
最初のオプション
USDCHFシンボル(図1)に5つのポジションが開かれているドル口座(デポジット)があるとします。
図1 USDCHFペアの市場ポジション
基本パラメータ:
口座通貨 - USD。
マージン通貨 - USD。
レバレッジサイズ - 1:100。
3つの買いポジションがあります。ポジションの総額は5.55ロットであり、価値基準で55万5千ドルです。そして、2つの売りポジションがあります。ポジションの総量は7.5ロットであり、金額は75万ドルです。
A)カバーされていないボリュームの計算
カバーされていないボリュームは1.95ロットまたは19万5千ドルです。これは買い以上に売りが大きいため、売りとなります。しかしながら、この場合は加重平均価格を計算する必要がないため、買いや売りは全く重要ではありません。
この金額からのマージンは、レバレッジを考慮して計算されます。
$195 000 / 100 = $1 950。
B)ヘッジボリュームの計算
ヘッジボリュームは、5.55ロットまたは55万5千ドルです。
この金額からのマージンは、レバレッジを考慮して計算されます。
$555 000 / 100 = $5 550。
グロスマージンは、カバーされていないボリュームのマージンとヘッジボリュームのマージンの合計として計算されます。
$1 950 + $5 550 = $7 500。
『マージン』インジケータの取引端末に表示されるのはこの値です。
2番目のオプション
EURUSDシンボル(図2)に対して5つのポジションが開かれているドル口座(デポジット)があるとします。
図2 EURUSDペアの市場ポジション
基本パラメータ:
- 口座通貨 - USD。
- マージン通貨 - EUR。
- レバレッジサイズ - 1:300。
3つの買いポジションがあります。ポジションの総額は5.55ロットであり、価格では55万5千ユーロまたは64万5617.20ドルである。加重平均購入価格は1.163274ドルです。
2つの売りポジションがあります。ポジションの総量は7.50ロットで、価格では75万ユーロまたは87万2,409ドルです。加重平均販売価格は1.163212ドルです。
すべてのポジションを表2で表示します。
Type | Volume | Price | Value, $ |
---|---|---|---|
buy | 1.75 | 1.16329 | 203 575.75 |
buy | 2.55 | 1.16329 | 296 638.95 |
buy | 1.25 | 1.16322 | 145 402.50 |
sell | 3.00 | 1.16323 | 348 969.00 |
sell | 4.50 | 1.16320 | 523 440.00 |
Total | 13.05 | 1.1632385 | 1 518 026.20 |
表2 EURUSDペアの市場ポジション
全部で5つのポジションがあります。ポジション総額は13.05ロットで、価格面では130万5千ユーロまたは151万8,026.20ドルです。ポジションの加重平均価格は1.16324ドルです。
A)カバーされていないボリュームの計算
カバーされていないボリュームは1.95ロットまたは19万5千ユーロです。これは買い以上に売りが大きいため、売りとなります。したがって、このボリュームの値を決定するには、加重平均販売価格を使用します。
$1.163212 * €195 000 = $226 826.34。
この金額からのマージンは、レバレッジを考慮して計算されます。
$226 826.34 / 300 = $756.09。
B)ヘッジボリュームの計算
ヘッジボリュームは5.55ロットまたは55万5千ユーロです。このボリュームの価値を決定するために、すべてのポジションの加重平均価格を取得します。
$1.1632385 * €555 000 = $645 597.35。
この金額からのマージンは、レバレッジを考慮して計算されます。
$645 597.35 / 300 = $2 151,99。
理論的には、総マージンは次のようになります。
$756.09 + $2 151.99 = $2 908.08。
しかし、端末では$ 1 832.08という値が見えます。
実際には、カバーされていないボリュームの場合、ツールの仕様の『ヘッジドマージン』パラメータの値が考慮されます。これが契約のサイズより小さければ、いくつかの乗数が取得されます。この場合、指定されたパラメータによって、値が5万に設定されます。したがって、
ヘッジボリュームの価格 = $ 1.1632385 *€555 000 /(100 000/50 000)= $ 322 798.67。
ヘッジボリュームのマージン= $ 322,798.67 / 300 = $ 1,076.00。
合計額:$ 756.09 + $ 1 076.00 = $ 1 832.08。この値は端末に対応しています。
3番目のオプション
AUDNZDシンボルのために5つのポジションが開かれているドル口座(デポジット)があるとします(図3)。
図3 AUDNZDクロスの市場ポジション
基本パラメータ:
- 口座通貨 - USD。
- マージン通貨 - AUD。
- レバレッジサイズ - 1:300。
3つの買いポジションがあります。ポジション総額は5.55ロットであり、額面55万5千豪ドルまたは40万442.35ドルです。加重平均購入価格は$ 0.7215178です。
2つの売りポジションがあります。ポジションの総量は7.50ロットに相当し、額面75万豪ドルまたは54万1,035.00ドルです。加重平均販売価格は$ 0.72138です。
すべてのポジションを表3で表示します。
Type | Volume | Price | Value, $ |
---|---|---|---|
buy | 1.75 | 0.72152 | 126 266.00 |
buy | 2.55 | 0.72152 | 183 987.60 |
buy | 1.25 | 0.72151 | 90 188.75 |
sell | 3.00 | 0.72144 | 216 432.00 |
sell | 4.50 | 0.72134 | 324 603.00 |
Total | 13.05 | 0.72144 | 941 477.35 |
図3 AUDNZDクロスの市場ポジション
Price列には、AUDNZDシンボルではなく、AUDUSDシンボルでのポジションの価格が表示されています。これは、アカウントの通貨で取引された金額を即座に評価するためです。この場合、勘定通貨とマージン通貨が表示されるペアのティックと相場の履歴を参照する必要があります。したがって、計算値は実際の値とは多少異なる場合があります。
全部で5つのポジションがあります。ポジションの総量は13.05ロットで、価格面では130万5千豪ドルまたは94万1,477.35ドルです。ポジションの加重平均価格は$ 0.72144です。
A)カバーされていないボリュームの計算
カバーされていないボリュームは、1.95ロットまたは19万5千豪ドルです。これは買い以上に売りが大きいため、売りとなります。したがって、このボリュームの値を決定するには、加重平均販売価格を使用します。
$ 0.72138 * A $ 195,000 = $ 140 669.10。
この金額からのマージンは、レバレッジを考慮して計算されます。
$140 669.10 / 300 = $468.90.
B)ヘッジボリュームの計算
ヘッジボリュームは5.55ロットまたは55万5千豪ドルです。この金額の価値を決定するために、『ヘッジマージン』パラメータの価格を考慮して、すべてのポジションの加重平均価格を採用します。
$ 0.72144 * A $ 555,000 /(100,000 / 50,000)= $ 200 199.21。
この金額からのマージンは、レバレッジを考慮して計算されます。
$200 199.21/ 300 = $667.33.
合計額:$ 468.90 + $ 667.33 = $ 1 136.23。図3に従って、これが端末のものと一致しているかチェックします。
2.4その他のプロパティ
クラスにはまだ、ヘッジの状態を持つStoreState()とCheckState()を扱うメソッドがあります。通常のポジションと同様に、タイプ、数量、開始価格、ストップロス価格、および利益を取得することによって決定されます。
テキストプロパティTypeDescription()の単一メソッドは、ヘッジタイプを文字列として返します。
特に注目すべきは、Select()ヘッジポジション選択メソッドです。メソッドコードを以下に示します。
//+------------------------------------------------------------------+ //| Selects hedge positions | //+------------------------------------------------------------------+ bool CHedgePositionInfo::Select(void) { string hedge_symbol=m_symbol.Name(); //--- clear all positions m_tickets.Shutdown(); //--- collect positions int pos_num=PositionsTotal(); for(int pos_idx=0;pos_idx<pos_num;pos_idx++) if(m_pos_info.SelectByIndex(pos_idx)) { string curr_pos_symbol=m_pos_info.Symbol(); //--- select by symbol if(!StringCompare(hedge_symbol,curr_pos_symbol)) { //--- if to select by magic bool is_the_same_magic=true; if(m_magic>0) { long curr_pos_magic=m_pos_info.Magic(); if(m_magic!=curr_pos_magic) is_the_same_magic=false; } if(is_the_same_magic) { ulong curr_pos_ticket=m_pos_info.Ticket(); if(curr_pos_ticket>0) if(!m_tickets.Add(curr_pos_ticket)) { PrintFormat(__FUNCTION__+": failed to add #%d ticket!",curr_pos_ticket); return false; } } } } //--- return m_tickets.Total()>0; } //+------------------------------------------------------------------+
このメソッドの主な目的は、ヘッジを構成するポジションのチケットを更新することです。これらのシンボルがヘッジシンボルとマッチしている場合、ここに市場ポジションが入ります。また、マジックのような選択フィルタを追加することもできます。
3.例
私達はヘッジポジションのプロパティで動作するクラスを作成しました。このセクションでは、実際的な例を扱うことを提案します。簡単なスクリプトから始めましょう。
3.1テストスクリプト
ヘッジのプロパティに関する『エキスパート』タブの情報がログに記録されるTest_hedge_properties.mq5スクリプトは練習用に作成されました。
デポジットを計算する最初のオプションでは、USDCHFシンボルに5つのポジションがありました(図1)。スクリプトを実行し、ログ内で次の情報を取得します。
2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) ---== Hedge properties==--- 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Symbol: USDCHF 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Positions total = 5 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) 1) #293972991 buy 1.75 USDCHF 0.97160000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) 2) #293974150 buy 2.55 USDCHF 0.97142000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) 3) #293974889 sell 3.00 USDCHF 0.97157000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) 4) #293975329 sell 4.50 USDCHF 0.97164000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) 5) #293976289 buy 1.25 USDCHF 0.97205000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Magic: 0 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Time: 2018.08.29 17:15:44 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Time in msc: 1535562944628 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Update time: 2018.08.29 17:20:35 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Update time in msc: 1535563235034 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Type: HEDGE_NETTING_SELL 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Type description: hedge netting sell 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Volume: -1.95 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Buy volume: 5.55 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Sell volume: 7.50 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Open price: 0.97159 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Sl-price: -1.00000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Tp-price: -1.00000 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Current price: 0.96956 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Commission: 0.00 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Swap: -35.79 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Profit: 409.77 2018.09.03 18:51:37.078 Test_hedge_properties (AUDNZD,H1) Margin: 7500.00
第2のオプションでは、EURUSD上のポジションのプロパティが処理されました(図2)。スクリプトを実行した後、次の情報を取得しました。
2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) ---== Hedge properties==--- 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Symbol: EURUSD 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Positions total = 5 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) 1) #119213986 buy 1.75 EURUSD 1.16329000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) 2) #119214003 buy 2.55 EURUSD 1.16329000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) 3) #119214004 buy 1.25 EURUSD 1.16322000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) 4) #119214011 sell 3.00 EURUSD 1.16323000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) 5) #119214021 sell 4.50 EURUSD 1.16320000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Magic: 0 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Time: 2018.08.31 16:38:10 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Time in msc: 1535733490531 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Update time: 2018.08.31 16:38:49 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Update time in msc: 1535733529678 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Type: HEDGE_NETTING_SELL 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Type description: hedge netting sell 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Volume: -1.95 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Buy volume: 5.55 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Sell volume: 7.50 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Open price: 1.16303 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Sl-price: -1.00000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Tp-price: -1.00000 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Current price: 1.16198 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Commission: 0.00 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Swap: -37.20 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Profit: 206.60 2018.09.03 18:55:09.469 Test_hedge_properties (AUDNZD,H1) Margin: 1832.08
第3のオプションでは、AUDNZDシンボルのポジションを扱いました(図3)。スクリプトは、次の情報をログに出力します。
2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) ---== Hedge properties==--- 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Symbol: AUDNZD 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Positions total = 5 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) 1) #119214062 buy 1.75 AUDNZD 1.08781000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) 2) #119214068 buy 2.55 AUDNZD 1.08783000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) 3) #119214071 buy 1.25 AUDNZD 1.08785000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) 4) #119214083 sell 3.00 AUDNZD 1.08773000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) 5) #119214092 sell 4.50 AUDNZD 1.08757000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Magic: 0 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Time: 2018.08.31 16:39:41 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Time in msc: 1535733581113 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Update time: 2018.08.31 16:40:07 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Update time in msc: 1535733607241 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Type: HEDGE_NETTING_SELL 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Type description: hedge netting sell 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Volume: -1.95 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Buy volume: 5.55 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Sell volume: 7.50 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Open price: 1.08708 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Sl-price: -1.00000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Tp-price: -1.00000 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Current price: 1.09314 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Commission: 0.00 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Swap: -21.06 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Profit: -779.45 2018.09.03 18:47:25.369 Test_hedge_properties (EURUSD,H1) Margin: 1136.23
Test_hedge_properties.mq5のスクリプトコードは、アーカイブからダウンロードできます。
3.1ヘッジプロパティパネル
ここでの作業は複雑になります。標準ライブラリを使用して、私たちはHedgePropertiesEA.mq5アドバイザーを作成し、選択されたヘッジポジションのプロパティを表示するパネルをチャート上に表示します。
これらの目的のために、CAppDialog標準クラスの子孫になるCHedgeDialogクラスを作成します。後者の助けを借りて、パネルウィンドウの最小化と復元、パネル要素の変更処理など、典型的なタスクをプログラムする必要性を取り除きます。
//+------------------------------------------------------------------+ //| Class CHedgeDialog | //| Purpose: Class for displaying a hedge position info. | //| Derives from class CAppDialog. | //+------------------------------------------------------------------+ class CHedgeDialog : private CAppDialog { //--- === Data members === --- private: CArrayString m_symbols_arr; //--- controls CLabel m_labels[FIELDS_NUM+1]; CEdit m_edits[FIELDS_NUM]; CComboBox m_combo; bool m_to_refresh; //--- === Methods === --- public: //--- constructor/destructor void CHedgeDialog(void) {}; void ~CHedgeDialog(void) {}; //--- initialization bool Init(void); void Deinit(const int _reason); //--- processing void OnChartEvent(const int _id, const long &_lparam, const double &_dparam, const string &_sparam); void OnTradeEvent(void); //--- private: int HedgeSymbols(void); void RefreshPanel(void); }; //+------------------------------------------------------------------+
エキスパートコード内のクラスのインスタンスは、初期化、初期化イベント、スケジュールイベント、および取引操作に関連するイベントを呼出しおよび処理します。
ヘッジポジションプロパティパネルを図4に示します。
図4 ヘッジポジションのプロパティパネル
主なメソッドの1つはCHedgeDialog :: RefreshPanel()です。これは、いわば『動力』で必要に応じて、パネル情報フィールドを更新します。コーディングとテストのいくつかの困難さは、ヘッジの数が変更された場合に引き起こされました。この場合、ドロップダウンリストの一意の文字を変更し、OnChartEvent()ハンドラ呼び出しの無限ループに入る必要はありません。この為に長さが1秒のハンドラへの連続コールの制限を使用しました。
//--- check the limit for refreshing if(!m_to_refresh) { uint last_cnt=GetTickCount(); static uint prev_cnt=0; uint msc_elapsed=last_cnt-prev_cnt; prev_cnt=last_cnt; if(msc_elapsed>1000) m_to_refresh=true; else return; }
HedgePropertiesEA.mq5アドバイザーのフルコードはアーカイブファイルで参照できます。
まとめ
MetaTrader 5取引端末は、この段階では、マルチマーケットだけでなく、さまざまなポジション計算システムの使用もできます。このような機能は、取引アイデアの実装と形式化のためのツールを大幅に拡大します。
この記事が、MetaTrader 4からMetaTrader 5へ自分の戦略を移したい人にとって興味深いものになることを願っています。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/4830




- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索