Forex トレーディングのイロハ

MetaQuotes | 17 2月, 2016

はじめに


金融市場を扱うということはまずトレード処理を意味します。ごく幼いころから、われわれは皆、何を売り、買うべきかということについて直観的考えを持っています。ですが Forex トレーディングは何か特別なものです。本稿ではいくつか用語の説明が必要な考えを取り上げます。われわれはまたこういった語に対応する MQL4 の関数についても考察します。

歴史を少し


われわれは、歴史の教科書から古代にはお金は使われていなかったことを知っています。そのころには自然経済で、直接の物々交換でした。お金の起源(発明)自体は人類の歴史にとって大きな前進の一歩となりました。万能の商品-お金、を使うことで人は実質的にすべてのものを交換することができるようになったのです。国により時代によりその遍在する交換物の形が変化する中、たとえば金や銀のように、お金は常にパーツに分けることがなく、蓄え、簡単に持ち運べるかなり貴重なものでありました。そしてもちろん、今や各国で独自の歴史、消費者、通貨-財源の形、を有しています。すでに大昔に国々の間では交易関係があり、商人がある国から別の国で売るために商品を運びました。商品はその土地の物品か万国共通の価値のもの、たとえば金貨、と交換されました。

現代


現在では貴金属は支払いの媒体として使用されることは実質的にはありません。そのため国々は支払いに交換レートを用いるのです。交換レートはある国の通貨単位価格を別の国の通貨単位に設定するものです。たとえば、EUR/USD のレート 1.25 は1ユーロで1.25 米ドルを手にすることができることを意味します。そのため、自由に換算できる 2 通貨にとっては交換レートを計算することが可能です。大きな外国為替は通常輸出入で銀行によって行われます。それゆえ、標準通貨ペアと交換の標準額を提示する必要ができました。MetaTrader 4 クライアントターミナルにおける通貨ペア(金融商品、シンボル)の名前は通貨名略称の組み合わせで記載されます。たとえば、EURUSD はユーロの米ドルでのレートで、GBPJPY は英ポンドの日本円でのレート、すなわち始めの通貨は常に後の通貨単位とされるのです。

預金通貨


多様な通貨ペアを使って取引を行うことは可能ですが、トレード結果はつねに1通貨-預金通貨、でのみ記載されます。預金通貨が米ドルであれば、利益と損失は米ドルで示され、それがユーロであれば、利益と損失はもちろんユーロで示されます。ご自身の預金通貨に関する情報はAccountCurrency() 関数で入手可能です。それは取引結果を預金通貨に換算するのに使えます。

標準的契約サイズ-標準ロット


1通貨を別通貨に交換する際、『ロット』という概念を使います、ロットは売買される物品量です。ロットは異なる通貨ペアに対して異なる値を持ちます。現在では、ほとんどの通貨ペアは100,000(百)に等しいロット値を持ちます。ですが、何の 100,000 でしょうか?われわれが買う場合、物品にたいしてお金を出します。売るとき、物品に対してお金を受け取ります。ただ通貨の場合、ある通貨を別の通貨に対して得るため売買を同時に行います。これが、買うとき最初の通貨を得、それに応じて2番目の通貨を渡す、ということを考える一般的な方法である理由です。EURUSD に対する標準ロットは 100,000 ユーロです。EURUSD の標準1ロットを買う場合、それは 100,000 ユーロを得、ある数量の米ドルを渡すことを意味します。受け取り額と支払い額はつねに一致するため、100,000 ユーロ = X 米ドルとなります。それでは米ドルの額はどのように計算できるのでしょうか?この式でユーロと米ドルを入れ替えます。

EURO= k*USD
ここで k は EURUS の為替レートです。
100 000 (k*USD) = X USD => X= k*100 000;
現在の EURUSD の為替レートが 1.25 であれば、X=125,000 となります。


したがって、EURUSD の1ロットを買うと、100,000 ユーロを受け取り、125,000 米ドルを渡すのです。ユーロが買われ、米ドルが売られることについて 、EURUSD が買われた、と言われることがあります。契約仕様からの通貨ペアに対する標準ロットの価格に関する情報もMarketInfo() 関数によって入手できます。たとえば以下です。


MarketInfo(Symbol(), MODE_LOTSIZE);

また、通貨ペアのテキスト名を提示すると、関数


MarketInfo("EURUSD",  MODE_LOTSIZE);

は100,000 を返します。それはヘルプファイルに書かれてあります。MODE_LOTSIZE はシンボルベースの通貨での契約サイズです。EURUSD に対するべース通貨は EUR (*) です。CHFJPY に対するべース通貨はスイスフランで、それに応じ、1ロットの価格はそれぞれスイスフランで表現されます。


トレード結果



別の例を考察します。EURUSD を1.2500 で1ロット購入しました。現行価格は 1.2600 です。よってトレードを終了することにしました。すなわち EURUSD を1ロット売却するのです。

バランスの記録

EURUSD を1.2500(取引開始) で1ロット購入するということは、 + 100,000 ユーロ - 125,000 米ドル、ということです。
EURUSD を1.2600(取引終了) で1ロット売却するということは、 - 100,000 ユーロ + 125 ,000 米ドル、ということです。取引の結果としての利益: 0 ユーロ + $ 1000

結論:EURUSD についての取引結果としての利益は米ドルで表されます。すなわち通貨ペアの2番目の通貨で表されるのです。ご自身で別の取引結果を計算してみてください。GBPCHF 1ロットは 2.30 で買い、2.40 でクローズでした。結果どのような利益がどの通貨で得ることになるのでしょうか?


レバレッジとマージン


金融市場でのトレーディングはレバレッジから利益が得られるためトレーダーにとっては魅力的です。われわれの例では、EURUSD を1ロット買うと、100,000 以上の米ドル(レート 1.25 では125,000 ドル)を得るかもしれないのです。ほとんどのブローカーがトレーダーがいわゆる「レバレッジ」を利用することを許可しています。レバレッジ値はポジションをオープンするために、より少ない資本が何度利用できるかを示すものです。ポジションをオープンするために必要な資金額はマージンと呼ばれます。レバレッジなしでは、EURUSD 1ロットは 100,000 ユーロかかります、またはレート 1.2500 で 125,000 米ドルかかります。みなさんのブローカーがレバレッジを100提供する場合、ポジションをオープンするのに必要な資金額は100倍減って 1,250 米ドルとなります。すでに計算した利益は変わりません。関数 AccountLeverage() を使って提供されている取引アカウントのレバレッジ値を見ることができます。よって、1ロットをオープンするためのマージンは次のように定義されます。

マージン(シンボルベース通貨で) = ロット価格(シンボルベース通貨で)÷ レバレッジサイズ

預金通貨に関してシンボルベース通貨の価格は、シンボルベース通貨と預金通貨間の比率です。


マージン決定


例:

MarketInfo("GBPJPY", MODE_LOTSIZE) は値 70 000 (LS) を出します。
AccountCurrency() は "EUR" (AC) を返します。
AccountLeverage() は 50 (AL) を返します。
現時点 (M)での GBPJPY 契約価格はどのように計算できるのでしょうか?

ベース通貨は GBP です。よって
M = 70000 GBP / AL = 70 000*GBPEUR / AL = 70000 / EURGBP / AL.

EURGBP レートが現時点で 0.6786 であれば、
M = 70000 / 0.6786 / 50 = 2063.07 ユーロ

レバレッジが 100 であば、マージンは 2 倍少なくなり、1031.54 ユーロです。レバレッジ 10 に対してマージンは以下となります。

M = 70000 / 0.6786 / 10 = 10315.36.


レバレッジサイズはポジションをオープンするのに必要なマージンサイズにのみ影響を与えますが、ある契約によって取引する際取得する利益サイズには影響はありません。シンボルベース通貨が英ポンドであるため、ユーロ(預金通貨)でのマージンサイズは、EURGBPレートに従って変動することを忘れてはいけません。われわれの例ではGBPEURを 1/EURGBP と置き換えました。というのも利用可能なものはシンボル EURGBP だけだからです。



ポイント-最小価格変動


Forex における通貨ペアは、その特別な変動だけでなく、レートにある小数点以下の数によってもお互い異なります。たとえば、2006年12月29日時点の GBPJPY のレートは 233.18 で、一方 GBPUSD の同日終値は 1.9587 でした。小数点以下の数(精度)は以下の関数によって設定されます。

MarketInfo(Symbol(), MODE_DIGITS);

例えば、関数

MarketInfo("GBPJPY", MODE_DIGITS);

は2を返します。

それに対応して、異なる通貨に対する安値の変化も異なります。この値は円を含む通常ペアには 0.01 で、EURUSD に対しては 0.0001 です。クオート通貨における安値の値変化は ポイント と呼ばれ、以下の関数によって取得されます。

MarketInfo(Symbol(), MODE_POINT);

通貨ペアに対しては関数値

MarketInfo(Symbol(), MODE_POINT); and MarketInfo(Symbol(), MODE_TICKSIZE);

は同じです。


預金通貨におけるポイント価格


リスク判定をするには、トレーダーは価格が特定のポイント数に変動するとき、オープンしているポジションに対する損失サイズを知る必要があります。または逆に、資金の観点で損失サイズにおいて許容できる損失サイズをポイントで計算します。このためには以下の関数を利用します。

MarketInfo(Symbol(), MODE_TICKVALUE);
これは預金通貨における1ポイント値を返します。
1ポイント価格は通貨ペアに対して変化し、通貨ペアの2番目の値は預金通貨ではないことを忘れてはいけません。

ロットごとのマージン


最後に考察する関数

MarketInfo(Symbol(), MODE_MARGINREQUIRED);

は売りポジションを1ロットオープンするために必要な自由資産額を返します。すなわち Ask 価格での標準ロット価格です。

上記を考慮した関数の使用例


以下は、12 通貨ペアに関して前述を考慮した関数に対するデータ表示を行うスクリプトです。このスクリプトのカスタム関数 MarginCalculate() は入札価格(売却価格)における標準ロットの価格を返します。以下のスクリプトで、MQL4 の関数を Expert Advis での資金管理およびリスク管理のアルゴリズムに使用する関数に応用する方法を学ぶことができます。


//+------------------------------------------------------------------+
//|                                          SimplySpecification.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                       https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
string SymbolsArray[13] = {"","USDCHF","GBPUSD","EURUSD","USDJPY",
"AUDUSD","USDCAD","EURGBP","EURAUD","EURCHF","EURJPY","GBPJPY","GBPCHF"};
//+------------------------------------------------------------------+
//| string SymbolByNumber                                            |
//+------------------------------------------------------------------+
string GetSymbolString(int Number)
  {
//----
   string res = "";
   res = SymbolsArray[Number];   
//----
   return(res);
  }
//+------------------------------------------------------------------+
//| A very simple function to calculate margin for Forex symbols.    |
//| It automatically calculates in the account's base currency and   |
//| does not work for complicated rates that do not have direct      |
//| recalculation into the trade account's base currency.            |
//+------------------------------------------------------------------+
double MarginCalculate(string symbol, double volume)
  {
   string first    = StringSubstr(symbol,0,3); // the first symbol, for example,  EUR
   string second   = StringSubstr(symbol,3,3); // the second symbol, for example, USD
   string currency = AccountCurrency();        // deposit currency, for example,  USD
   double leverage = AccountLeverage();        // leverage, for example,          100
// contract size, for example, 100000
   double contract = MarketInfo(symbol, MODE_LOTSIZE);
   double bid      = MarketInfo(symbol, MODE_BID);      // Bid price
//---- allow only standard forex symbols like XXXYYY
   if(StringLen(symbol) != 6)
     {
      Print("MarginCalculate: '",symbol,"' must be standard forex symbol XXXYYY");
      return(0.0);
     }
//---- check for data availability
   if(bid <= 0 || contract <= 0) 
     {
      Print("MarginCalculate: no market information for '",symbol,"'");
      return(0.0);
     }
//---- check the simplest variations - without cross currencies
   if(first == currency)   
       return(contract*volume / leverage);           // USDxxx
   if(second == currency)  
       return(contract*bid*volume / leverage);       // xxxUSD
//---- check normal cross currencies, search for direct conversion through deposit currency
   string base = currency + first;                   // USDxxx
   if(MarketInfo(base, MODE_BID) > 0) 
       return(contract / MarketInfo(base, MODE_BID)*volume / leverage);
//---- try vice versa
   base = first + currency;                          // xxxUSD
   if(MarketInfo(base, MODE_BID) > 0) 
       return(contract*MarketInfo(base, MODE_BID)*volume / leverage);
//---- direct conversion is impossible
   Print("MarginCalculate: can not convert '",symbol,"'");
   return(0.0);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   for(int i = 1; i < 13; i++)
     {
      Print("Symbol=",GetSymbolString(i),"  spread=",MarketInfo(GetSymbolString(i),
      MODE_SPREAD),"  margin at 1 lot=",MarginCalculate(GetSymbolString(i),1),
      "  MODE_TICKVALUE=",MarketInfo(GetSymbolString(i),MODE_TICKVALUE),
      ", MODE_TICKSIZE=",MarketInfo(GetSymbolString(i),MODE_TICKSIZE),
      " MODE_MARGINREQUIRED=",MarketInfo(GetSymbolString(i),MODE_MARGINREQUIRED));
     } 
//----
   return(0);
  }
//+------------------------------------------------------------------+

注)ほとんどの場合、シンボルのベース通貨は通貨ペアの最初のものですが、もちろんサーバー設定によりこの限りではありません。