Hedgeモードの概要
Hedgeモード(両建てモード)は、同一通貨ペアで買いポジションと売りポジションを同時に保有できる取引モードです。これは、Nettingモード(ネッティングモード)と対比される取引方式です。
HedgeとNettingモードの比較
項目 | Hedgeモードの特徴 | Nettingモードの特徴 |
---|---|---|
ポジション管理 | 同一通貨ペアで複数のポジションを同時に保有可能 | 同一通貨ペアのポジションは自動的に相殺され、1つの純ポジションとして管理される |
ストップロス・テイクプロフィット | 各ポジションに異なるストップロスやテイクプロフィットを設定可能 | 1つのポジションとして管理されるため、個別設定は不可 |
リスク分散 | リスク分散が可能で、不利な状況でも損失を軽減できる | リスク分散は難しいが、ポジションが単純化される |
ボラティリティ活用 | 市場のボラティリティを活用し、両方向の動きから利益を得る機会がある | ボラティリティ活用は難しいが、取引がシンプル |
取引プロセス | 複数ポジションを管理する必要があり、取引が複雑になる場合がある | 取引の簡素化と決済プロセスの効率化が図れる |
コスト削減 | 両建てによる取引コスト(手数料やスプレッド)が増加する可能性あり | 送金手数料、事務コスト、決済資金、為替リスクの削減効果がある |
Hedgeモードは、MT4での取引と似た方式で馴染みやすく多くのFX会社で採用されており、MT5などの取引プラットフォームでも利用可能です。トレーダーは市場の状況や戦略のニーズに応じて、柔軟な取引を実行することができます。
ただし、Hedgeモードを効果的に活用するには、適切なリスク管理と高度な取引スキルが必要です。初心者トレーダーは、Hedgeモードの複雑性を十分に理解してから使用することが重要です。
なお、HedgeモードとNettingモードは口座ごとに設定されており、トレーダーが自由に切り替えることはできません。取引を始める前に、使用する口座のモードを確認することが重要です。
Point
多くの口座を見てきたわけではありませんが、MT5口座でHedgeモード以外を見たことがないので、基本的にはMT4と同じポジション管理と考えてよいと思います。
Order(オーダー)とは何か?
Order(オーダー)とは、未約定の注文のことを指します。これは市場に出された指示であり、特定の条件が満たされたときに実行されます。主なオーダータイプは以下の通りです:
- 成行注文(Market Order)
現在の市場価格で即時に約定する注文。 - 指値注文(Limit Order)
指定した価格またはそれより有利な価格で約定する注文。 - 逆指値注文(Stop Order)
指定した価格に達したときに成行注文として執行される注文。
MQL5では、OrderSend()
関数を使用してオーダーを発注します。この関数では、注文の種類や数量、価格などを指定できます。
Position(ポジション)とは何か?
Position(ポジション)とは、すでに約定済みの取引を指します。つまり、市場で実際に保有している状態です。ポジションには以下の2種類があります:
- 買いポジション(ロング)
価格上昇を期待して保有するポジション。 - 売りポジション(ショート)
価格下落を期待して保有するポジション。
MQL5では、PositionSelect()
関数を使って特定のポジションを選択し、PositionGetDouble()
やPositionGetInteger()
などを使って詳細情報を取得します。
OrderとPositionの違い
OrderとPositionには明確な違いがあります。それぞれ以下のように区別されます:
項目 | Order(オーダー) | Position(ポジション) |
---|---|---|
状態 | 未約定の注文 | 約定済みの取引 |
管理方法 | OrderSend() で発注 | PositionSelect() で選択後に操作 |
リスク | 約定するまでリスクなし | 市場変動による損益が発生 |
Hedgeモードでは、この違いを正確に理解し、それぞれを適切に管理することが重要です。
Hedgeモードにおけるポジション管理の重要性
Hedgeモードでは、同一通貨ペアで複数のポジションを持つことができるため、適切なポジション管理が非常に重要です。以下がその理由です:
- リスク管理
複数のポジションを持つことで全体のリスクが増大する可能性があります。各ポジションごとのリスク評価が必要です。 - 収益最適化
異なる戦略によるポジション間の相互作用を考慮しながら、収益最大化を目指します。 - 複雑性への対応
多数のポジションを同時に管理することは単一ポジションよりも難しいため、自動化や整理された管理手法が求められます。
具体的なポジション管理手法
Hedgeモードで効果的なポジション管理を行うためには、以下の手法が役立ちます:
- 識別と追跡
各ポジションにユニークな識別子(チケット番号など)を割り当てて追跡します。 - リスク分散
異なる戦略や時間軸で取引し、リスク集中を避けます。 - 自動化
MQL5スクリプトやEAによる自動化で効率的な管理を実現します。
MQL5での実装例
以下は、Hedgeモードでポジションを管理する簡単なコード例です。
1つめは、単純にポジションが無ければ買い(BUY)エントリーして、ポジションがある場合は反対側のエントリーをします。
エントリーしたら手動で決済してみて動きを確認してみて動作を理解してみてください。
#property copyright "Your Name"
#property link "https://www.example.com"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
CTrade g_trade;
input double Lots = 0.01; // 取引量
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(0 == PositionsTotal())
{
// ポジションがない場合、新規ポジションをオープン
g_trade.Buy(Lots, Symbol(), 0, 0, 0, "Hedge Buy");
Print("新規ポジションをオープン(買い)");
}
else if(1 == PositionsTotal())
{
// 1つのポジションがある場合、反対方向でヘッジ
ulong ticket = PositionGetTicket(0);
if(PositionSelectByTicket(ticket))
{
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(POSITION_TYPE_BUY == positionType)
{
g_trade.Sell(Lots, Symbol(), 0, 0, 0, "Hedge Sell");
Print("ヘッジポジションをオープン(売り)");
}
else if(POSITION_TYPE_SELL == positionType)
{
g_trade.Buy(Lots, Symbol(), 0, 0, 0, "Hedge Buy");
Print("ヘッジポジションをオープン(買い)");
}
}
}
}
ソースコードの解説
行番号 | ソースコード | 解説 |
---|---|---|
1 | #property copyright “Your Name” | プログラムの著作権情報を定義します。 “Your Name” はユーザーの名前に変更することができます。 |
2 | #property link “https://www.example.com” | プログラムに関連するウェブリンクを定義します。リンク先のURLを設定します。 |
3 | #property version “1.00” | プログラムのバージョン情報を定義します。この場合はバージョン「1.00」です。 |
4 | #property strict | 厳格モードを有効にします。これにより、型チェックやエラーチェックが強化されます。 |
6 | #include | Trade.mqh ライブラリをインクルードします。このライブラリは、取引に関する関数を提供します。 |
8 | CTrade g_trade; | CTrade クラスのインスタンス g_trade を宣言します。このインスタンスを使って、取引操作を実行します。 |
10 | input double Lots = 0.01; | ユーザーが入力する変数 Lots を定義します。取引量を決定するための変数で、デフォルト値は 0.01 ロットです。 |
15 | int OnInit() | OnInit 関数の開始です。Expert Advisor(EA)の初期化処理を行うための関数です。 |
16 | { | OnInit 関数の開始。 |
17 | return(INIT_SUCCEEDED); | 初期化が成功したことを示す定数 INIT_SUCCEEDED を返します。 |
18 | } | OnInit 関数の終了。 |
23 | void OnDeinit(const int reason) | OnDeinit 関数の開始です。EAが終了する際に呼び出され、終了処理を行うための関数です。 |
24 | { | OnDeinit 関数の開始。 |
25 | } | OnDeinit 関数の終了。 |
30 | void OnTick() | OnTick 関数の開始です。ティックごとに呼ばれる関数で、ここで売買判断を行います。 |
31 | { | OnTick 関数の開始。 |
32 | if(0 == PositionsTotal()) | ポジションがない場合の条件文です。PositionsTotal() は現在開いているポジションの数を返します。 |
33 | { | if 条件文の開始。 |
35 | g_trade.Buy(Lots, Symbol(), 0, 0, 0, “Hedge Buy”); | g_trade を使用して買いポジションをオープンします。取引量は Lots で、シンボルは現在の通貨ペアです。 |
36 | Print(“新規ポジションをオープン(買い)”); | ポジションが開かれたことをコンソールに出力します。 |
37 | } | if 条件文の終了。 |
38 | else if(1 == PositionsTotal()) | 既に1つポジションがある場合の条件文です。 |
39 | { | else if 条件文の開始。 |
41 | ulong ticket = PositionGetTicket(0); | 最初のポジションのチケット番号を取得します。チケット番号はポジションを一意に識別するために使われます。 |
42 | if(PositionSelectByTicket(ticket)) | チケット番号でポジションを選択します。選択したポジションの情報を取得するための条件文です。 |
43 | { | if 条件文の開始。 |
44 | ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); | 現在のポジションのタイプ(買い・売り)を取得し、positionType に格納します。 |
45 | } | if 条件文の終了。 |
46 | if(POSITION_TYPE_BUY == positionType) | 現在のポジションが買いの場合の条件文です。 |
47 | { | if 条件文の開始。 |
48 | g_trade.Sell(Lots, Symbol(), 0, 0, 0, “Hedge Sell”); | 反対方向(売り)のポジションを開きます。取引量は Lots で、シンボルは現在の通貨ペアです。 |
49 | Print(“ヘッジポジションをオープン(売り)”); | ヘッジポジションをオープンしたことをコンソールに出力します。 |
50 | } | if 条件文の終了。 |
51 | else if(POSITION_TYPE_SELL == positionType) | 現在のポジションが売りの場合の条件文です。 |
52 | { | else if 条件文の開始。 |
53 | g_trade.Buy(Lots, Symbol(), 0, 0, 0, “Hedge Buy”); | 反対方向(買い)のポジションを開きます。取引量は Lots で、シンボルは現在の通貨ペアです。 |
54 | Print(“ヘッジポジションをオープン(買い)”); | ヘッジポジションをオープンしたことをコンソールに出力します。 |
55 | } | else if 条件文の終了。 |
56 | } | if 条件文の終了。 |
57 | } | else if 条件文の終了。 |
58 | } | OnTick 関数の終了。 |
次の例は決済です。
このコードでは、すべてのオープン中のポジションについてループ処理し、それぞれに応じたロジックを適用しています。また、一部利益確定として部分決済も行っています。
エントリーは勝手にしないので、1.0ロットなど数回半分に割り切れるポジションをエントリーしてみてください。一定の利益で半分ずつ決済していきますが割り切れない(端数がでる)と決済出来ない問題がおきますので、なぜ決済できなくなるかを含めて理解できるようになると良いです。
#property copyright "Your Name"
#property link "https://www.example.com"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
CTrade g_trade;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 初期化処理をここに記述
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 終了処理をここに記述
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 全てのオープンポジションをループ処理
for(int nPositionIndex = PositionsTotal() - 1; nPositionIndex >= 0; nPositionIndex--)
{
ulong ulTicket = PositionGetTicket(nPositionIndex);
if(PositionSelectByTicket(ulTicket))
{
double dPositionProfit = PositionGetDouble(POSITION_PROFIT);
ENUM_POSITION_TYPE ePositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double dPositionVolume = PositionGetDouble(POSITION_VOLUME);
// ポジションタイプごとの処理
if(ePositionType == POSITION_TYPE_BUY)
{
// 買いポジションの場合
Print("買いポジション: 利益 = ", dPositionProfit);
}
else if(ePositionType == POSITION_TYPE_SELL)
{
// 売りポジションの場合
Print("売りポジション: 利益 = ", dPositionProfit);
}
// 利益が一定額以上なら部分決済
if(dPositionProfit > 100)
{
g_trade.PositionClosePartial(ulTicket, dPositionVolume / 2);
Print("ポジションの一部を決済しました: チケット = ", ulTicket);
}
}
}
}
ソースコードの解説
行番号 | コード | 説明 |
---|---|---|
1 | #property copyright "Your Name" | EAの著作権情報を指定。 |
2 | #property link "https://www.example.com" | EAに関連するウェブサイトのリンクを指定。 |
3 | #property version "1.00" | EAのバージョン情報を設定。 |
4 | #property strict | 厳密な型チェックを適用し、コードの安全性を向上。 |
6 | #include <Trade\Trade.mqh> | CTrade クラスを使用するためのヘッダーファイルをインクルード。 |
8 | CTrade g_trade; | CTrade クラスのインスタンス g_trade を作成(トレード処理用)。 |
13 | int OnInit() | 初期化関数 OnInit の定義。 |
14 | { | OnInit 関数の開始。 |
16 | return(INIT_SUCCEEDED); | 初期化が成功したことを示すリターン値。 |
17 | } | OnInit 関数の終了。 |
22 | void OnDeinit(const int reason) | EA終了時の処理を記述する関数 OnDeinit の定義。 |
23 | { | OnDeinit 関数の開始。 |
25 | } | OnDeinit 関数の終了。 |
30 | void OnTick() | ティックごと(価格更新ごと)に実行される OnTick 関数の定義。 |
31 | { | OnTick 関数の開始。 |
33 | for(int nPositionIndex = PositionsTotal() - 1; nPositionIndex >= 0; nPositionIndex--) | すべてのオープンポジションをループ処理。 |
34 | { | for ループの開始。 |
35 | ulong ulTicket = PositionGetTicket(nPositionIndex); | ポジションのチケット番号を取得。 |
36 | if(PositionSelectByTicket(ulTicket)) | ポジション選択が成功した場合の処理開始。 |
37 | { | ポジション選択成功時の処理ブロック開始。 |
38 | double dPositionProfit = PositionGetDouble(POSITION_PROFIT); | ポジションの現在の利益を取得。 |
39 | ENUM_POSITION_TYPE ePositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); | ポジションの種類(買い or 売り)を取得。 |
40 | double dPositionVolume = PositionGetDouble(POSITION_VOLUME); | ポジションの取引量(ロット数)を取得。 |
43 | if(ePositionType == POSITION_TYPE_BUY) | 買いポジションの場合の処理開始。 |
44 | { | 買いポジションの処理ブロック開始。 |
46 | Print("買いポジション: 利益 = ", dPositionProfit); | 買いポジションの利益を表示。 |
47 | } | 買いポジションの処理終了。 |
48 | else if(ePositionType == POSITION_TYPE_SELL) | 売りポジションの場合の処理開始。 |
49 | { | 売りポジションの処理ブロック開始。 |
51 | Print("売りポジション: 利益 = ", dPositionProfit); | 売りポジションの利益を表示。 |
52 | } | 売りポジションの処理終了。 |
55 | if(dPositionProfit > 100) | 利益が100を超えた場合の部分決済処理開始。 |
56 | { | 部分決済の処理ブロック開始。 |
57 | g_trade.PositionClosePartial(ulTicket, dPositionVolume / 2); | ポジションの半分を決済。 |
58 | Print("ポジションの一部を決済しました: チケット = ", ulTicket); | 部分決済の実行をログに出力。 |
59 | } | 部分決済の処理終了。 |
60 | } | ポジション選択成功時の処理終了。 |
61 | } | forループの処理終了。 |
62 | } | OnTick 関数の終了。 |
まとめと今後の展望
Hedgeモードでは、OrderとPositionという異なる概念を正しく理解し、それぞれを適切に扱うことが重要です。特に複数のポジション管理が求められる場面では、自動化や整理された手法によって効率的かつ安全な運用が可能になります。
今後はさらに高度な戦略やリスク管理技術について学びながら、自分自身のEA開発スキルを磨いていきましょう!
用語集
用語 | 説明 |
---|---|
Hedgeモード | 同一通貨ペアで買いと売り両方のポジションを同時保有できる取引モード |
Order | 未約定状態の注文 |
Position | 約定済みで保有中の取引 |
PositionSelect() | 特定のポジション選択関数 |
PositionGetDouble() | ポジション情報取得関数(小数値データ用) |
PositionsTotal() | 現在保有中の全オープンポジション数取得 |
PositionClosePartial() | 部分決済用関数 |
コメント