
エキスパートアドバイザーの資金管理のためのファンクション
はじめに
MQL5言語はmql5-プログラムのターミナル内の状況、また金融商品 とトレーディングアカウントについての膨大な量の情報を得る機会を提供する。資本管理機能を整えるために、 リストの最後の2つの節から、その性質を学習し、次のような関数に慣れておく必要がある
- SymbolInfoInteger()
- SymbolInfoDouble()
- SymbolInfoString()
- AccountInfoInteger()
- AccountInfoDouble()
- AccountInfoString()
この論説では主な焦点をエキスパートアドバイザーにある機能の使用に絞るが、これらの説明の全てはインジケーターとスクリプトにも適用できる。
アカウントバランスについての情報を得る
トレーディングアカウントの最初の2つの重要な特性は - 残高と純資産。 これらの値を得るためには、 AccountInfoDouble() ファンクションを用いる:
double balance=AccountInfoDouble(ACCOUNT_BALANCE); double equity=AccountInfoDouble(ACCOUNT_EQUITY);
次に重要な点は、全てのオープンポジションにおけるデポジット資金の量であり、さらに全てのオープンポジションに対する流動損益の合計である。
double margin=AccountInfoDouble(ACCOUNT_MARGIN); double float_profit=AccountInfoDouble(ACCOUNT_PROFIT);
新規のポジションを開くあるいは既存のものを強化するためには、デポジットに入っていない自由な資源を必要とする。
double free_margin=AccountInfoDouble(ACCOUNT_FREEMARGIN);
ここで、上記の値は月毎の期間で表現されていることに注意するべきである。
AccountInfoDouble() ファンクション で戻る金銭の値は、 デポジット通貨で表現される。. デポジット通貨を求めるにはAccountInfoString() ファンクションを用いる。
string account_currency=AccountInfoString(ACCOUNT_CURRENCY);
個人資金のレベル
アカウントにはもう一つの重要な特性がある - ストップアウト(オープンポジションを維持するのに必要な個人資金の不足によるポジションの強制閉鎖)が起こるレベル。この値を得るには再びAccountInfoDouble() ファンクションを用いる。
double stopout_level=AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
このファンクションは値そのものを戻すだけであり、どのような単位のタイプでその値が表現されているかを説明するものではない。 ストップアウトのレベルの明細には2つのモードがあり、それは:パーセントによるものと金額によるものである。これを求めるには AccountInfoInteger() ファンクションを用いる
//--- Get account currency string account_currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Stop Out level double stopout_level=AccountInfoDouble(ACCOUNT_MARGIN_SO_SO); //--- Stop Out mode ENUM_ACCOUNT_STOPOUT_MODE so_mode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); if(so_mode==ACCOUNT_STOPOUT_MODE_PERCENT) PrintFormat("Stop Out level in percents %.2f%%",stopout_level); else PrintFormat("Stop Out level in currency %.2f %s",stopout_level,account_currency);
アカウントに関する追加の情報
しばしば計算においてトレーディングアカウントのレバレッジに提供されている量を知ることが要求される。この情報はAccountInfoInteger() ファンクションを用いて得ることができる:
int leverage=(int)AccountInfoInteger(ACCOUNT_LEVERAGE);調整されていないエキスパートアドバイザーを間違えて現実のアカウントで実行することを避けるために、アカウントのタイプを知る必要がある。
ENUM_ACCOUNT_TRADE_MODE mode=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE); switch(mode) { case ACCOUNT_TRADE_MODE_DEMO: Comment("Account demo"); break; case ACCOUNT_TRADE_MODE_CONTEST: Comment(com,"Account Contest"); break; case ACCOUNT_TRADE_MODE_REAL: Comment(com,"Account Real"); break; default: Comment(com,"Account unknown type"); }トレーディングはどのアカウントでも可能なわけではなく、たとえば、競争的なアカウントでは、トレーディング操作は競争開始後にのみ行える。この情報はAccountInfoInteger() ファンクションによっても得ることができる。
bool trade_allowed=(bool)AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); if(trade_allowed) Print("Trade is allowed"); else Print(com,"Trade is not allowed");
このアカウントでのトレーディングが許可されても、それはエキスパートアドバイザーがトレードする権利があることを意味しているわけではない。エキスパートアドバイザーにトレードすることが許可されているかどうかをチェックするには、次のコードを書く:
if(trade_allowed) { bool trade_expert=(bool)AccountInfoInteger(ACCOUNT_TRADE_EXPERT); if(trade_expert) Print("Experts are allowed to trade"); else Print("Experts are not allowed to trade");
これらの例は添付したエキスパートアドバイザーAccount_Info.mq5にある。. それらはMQL5プログラム内全てにおいて使用できる。
ツールについての情報
各金融商品はその説明がパスに付いていて、そのツールの特徴を示している。もし端末にてEURUSD のプロパティに関するウインドウを開けると以下のようなものが表示されている:
この場合には、EURUSDについての説明は - "EURUSD, Euro vs US Dollar"となっている。この情報を得るには、SymbolInfoString() ファンクションを使う:
string symbol=SymbolInfoString(_Symbol,SYMBOL_DESCRIPTION); Print("Symbol: "+symbol); string symbol_path=SymbolInfoString(_Symbol,SYMBOL_PATH); Print("Path: "+symbol_path);
標準契約の大きさを見るにはSymbolInfoDouble()を使う:
double lot_size=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE); Print("Standard contract: "+DoubleToString(lot_size,2));
FOREXツール の特徴はある通貨を売りもう一つの通貨を買うことである。この契約は購入を実行するのに必要な通貨で示される。これはベース通貨であり、SymbolInfoString() ファンクションを使って得られる:
string base_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_BASE); Print("Base currency: "+base_currency);
そのツールにおける価格の変化は購入した資産の価格の変化となり、したがって、利得はオープンポジション(もしポジションが損であると、利得は負となりえる)によって変化する。このように、価格の変化は収入の変化につながり、特定の通貨で表現される。この通貨は見積もり通貨と呼ばれる。通貨のペアEURUSDではベース通貨は通常 Euroで、見積通貨 はU.S. ドルである。見積通貨を得るためにSymbolInfoString() ファンクションを使うことができる:
string profit_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_PROFIT); Print("Currency quotes: "+profit_currency);
ツール上でポジションを開けるには、資金を必要とし、この資金は特定の通貨で表現される。この通貨は通貨マージンあるいはデポジットと呼ばれる。FOREXツールでは、マージンとベース通貨は通常同じである。デポジット通貨での値を見るにはSymbolInfoString() ファンクションを使用する:
string margin_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_MARGIN); Print("Currency deposit: "+margin_currency);
説明するファンクションはエキスパートアドバイザー のSymbol_Info.mq5 のコードで与えられる。. 次の図は Comment() ファンクションを用いたシンボルEURUSDの情報出力を示している。
デポジット額を計算する
トレーダーに最も必要とされる金融商品についての情報は、ポジションを開くのに必要な資金の大きさである。特定の数量のロットを売買するするのに必要な金額を知らないのでは、資本管理のためのエキスパートアドバイザーシステムを実行することはできない。さらに、アカウントの口座残高を制御することも難しくなる。
これからの議論の理解が困難であるときには記事 Forex Trading ABCを読むことを勧める。そこに書かれている説明はこの記事にも適用される。
通貨デポジットでのマージンの大きさを計算する必用がある、すなわち、得られた値を与えたアカウントのレバレッジの額で割って、貸付金通貨からデポジット通貨へデポジットを再計算するのである。これを行うのためにGetMarginForOpening() ファンクションを次に書く://+------------------------------------------------------------------+ //| Return amount of equity needed to open position | //+------------------------------------------------------------------+ double GetMarginForOpening(double lot,string symbol,ENUM_POSITION_TYPE direction) { double answer=0; //--- ... //--- Return result - amount of equity in account currency, required to open position in specified volume return(answer); }
ここで:
- ロットはオープンポジションの量である;
- シンボルは、金融商品の名前である;
- 想定ポジションの方向.
- デポジットの通貨
- 貸付金の通貨
- 通貨の見積(通貨交換のために必要)
- 契約額
これをMQL5 言語で書く:
//--- Get contract size double lot_size=SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE); //--- Get account currency string account_currency=AccountInfoString(ACCOUNT_CURRENCY); //--- Margin currency string margin_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_MARGIN); //--- Profit currency string profit_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_PROFIT); //--- Calculation currency string calc_currency=""; //--- Reverse quote - true, Direct quote - false bool mode;
モード変数はデポジット通貨での契約額を計算するのに影響する。例に基づいてこれを考える。今後のケースではデポジット通貨はUSドルと仮定する。
通貨のペアは通常3つのカテゴリーに分割される:
- 直接通貨ペア - U.S. 特定通貨へのドル換算レート例: USDCHF, USDCAD, USDJPY, USDSEK;
- 逆通貨ペア - 特定の通貨から U.S. ドルへの交換レートとである。例: EURUSD, GBPUSD, AUDUSD, NZDUSD;
- 交互通貨ペア -U.S. ドルが絡まないペアである。例: AUDCAD, EURJPY, EURCAD.
1. EURUSD - 逆通貨ペア
見積通貨がアカウント通貨である通貨ペアを逆通貨ペアと呼ぶ。ここでの例においては、アカウント通貨はU.S. ドルであり、通貨ペアの分類は一般に受け入れられている分類と一致する。しかしトレーディングアカウントが別の通貨(USD以外)であると、それは一致しない。 この場合には、以下の説明を理解するために、アカウント通貨を考慮に入れる。
契約額EURUSD - 100 000 ユーロ。100 000 ユーロ をデポジットの通貨 - U.S. ドルで表現する。. このためにユーロがドルで計算されるための交換レートを知る必要がある。. ここで計算通貨の概念を導入する、すなわち、貸付金通貨をデポジット通貨に変換するのに必要な通貨である。
//--- Calculation currency string calc_currency="";
幸い EURUSD 通貨ペアはユーロのドルに対する交換レートを表わしていて、したがってこの場合には、貸付金額を計算するのに必用なEURUSDのシンボルは正確に交換レートとなる:
//--- If profit currency and account currency are equal if(profit_currency==account_currency) { calc_currency=symbol; mode=true; }
我々は mode の値を真として確立してきた、これはユーロをドルに交換することを意味し(貸付金通貨はデポジット通貨に交換可)、通貨交換レートEURUSDを契約額に掛けている。もしmode = 偽となると、契約額を計算通貨の交換レートで割ることになる。商品上での通貨の価格を得るには SymbolInfoTick()ファンクションを使用する。.
//--- We know calculation currency, let's get its last prices MqlTick tick; SymbolInfoTick(calc_currency,tick);
このファンクションは現在の価格と最新の価格の更新の時を MqlTick タイプの変数に入れる -この 構造 は この目的のために特別に設計された。
したがってこのシンボルで最新の価格を得るには、それに契約額、そしてロット数を掛ければ十分である。この商品には買い価格と売り価格とがあることを考えると、どの計算価格を採ればよいのか?それは論理的に:もし買うのであれば計算のための価格はAsk 価格となり、もし売るのであればBid価格を用いる必要がある。
//--- Now we have everything for calculation double calc_price; //--- Calculate for Buy if(direction==POSITION_TYPE_BUY) { //--- Reverse quote if(mode) { //--- Calculate using Buy price for reverse quote calc_price=tick.ask; answer=lot*lot_size*calc_price; } } //--- calculate for Sell if(direction==POSITION_TYPE_SELL) { //--- Reverse quote if(mode) { //--- Calculate using Sell price for reverse quote calc_price=tick.bid; answer=lot*lot_size*calc_price; } }
したがって、例では、EURUSDシンボルに対してデポジット通貨がユーロ、契約額が100 000、そして最新のAsk価格 = 1.2500。アカウント通貨 - U.S. ドル、計算通貨が同じEURUSD 通貨ペア。100 000 に1.2500 をかけて 125 000 U.S. ドルを得る -これが もし Ask 価格 =1.2500であれば1 EURUSDロットを購入する標準契約の費用である。.
もし見積通貨がアカウント通貨と同じであれば、アカウント通貨での1ロットの価値を得るには、単純に契約額にポジションの意図する方向によって適切なBid あるいは Askの価格をかければよいと結論づけることができる。
margin=lots*lot_size*rate/leverage;
2. USDCHF - direct currency pair
USDCHF のための貸付金通貨とアカウント通貨が - U.S. ドルと合致する。貸付金通貨とアカウント通貨が同じ場合の通貨ペアは直接通貨ペアと呼ぶ。契約額 - 100 000. これは最も単純な状況で、単に積を戻せばよい。
//--- if the base currency symbol and the deposit currency are the same if(margin_currency==account_currency) { calc_currency=symbol; //--- Just return the contract value, multiplied by the number of lots return(lot*lot_size); }
もしデポジット通貨がアカウント通貨と一致すれば、アカウント通貨でのデポジットの価値は標準契約にロットの数(契約)を掛け、レバレッジの額で割ればよい。
margin=lots*lot_size/leverage;
3. CADCHF - 交差- 通貨ペア
CADCHF 通貨ペアは説明の目的で取り、デポジット通貨と見積通貨がアカウント通貨と一致する他のどのペアでも使用できる。 この通貨ペアはクロス(交差)と呼ばれる、と言うのはその上でマージン利得を計算するために、他の通貨ペアの交換レートを知る必要があり、それが通貨の1つで交差するからである。
通常、交差-通貨ペアは、見積り通貨がU.S. ドルを使わないペアである。しかし、見積りにアカウント通貨を含まない全てのペアを交差通貨ペアと呼ぶことにする。もし、アカウント通貨がユーロであると、ペアGBPUSD はデポジット通貨が英国ポンドで見積り通貨がU.S. ドルであるために交差通貨ペアとなる。このケースでは、マージンを計算するために、ポンド (GBP) をユーロ(EUR)で表現しなければならない。
しかし、引き続きシンボルが通貨ペアCADCHFである例について考える。デポジット通貨はカナダドル (CAD) でU.S. ドル(USD)と一致しない。見積り通貨はスイスフランでこれも米ドルとは一致しない。
ポジション1ロットを開くためのデポジットは100,000 カナダドルであるとのみ言える。ここでの作業はデポジットを U.S. ドルのアカウント通貨に再計算することである。. これを行うため、U.S. ドルとデポジット通貨がカナダドルを含む交換レートの通貨ペアを求めなくてはならない。 全部で2通りの可能な選択肢がある:
- CADUSD
- USDCAD
CADCHFのための出力データを持っている:
マージン通貨=CAD (カナダドル) 利得通貨=CHF (スイスフラン)
事前にどちらの通貨ペアがその端末でMQL5言語に関して存在するか知らないので、どちらのオプションも望ましいとはいえない。そこで、GetSymbolByCurrencies() ファンクションを書く、それは 与えられた通貨の集合に対して計算のために 最初に一致する 通貨ペアを教えるものである。
//+------------------------------------------------------------------+ //| Return symbol with specified margin currency and profit currency | //+------------------------------------------------------------------+ string GetSymbolByCurrencies(string margin_currency,string profit_currency) { //--- In loop process all symbols, that are shown in Market Watch window for(int s=0;s<SymbolsTotal(true);s++) { //--- Get symbol name by number in Market Watch window string symbolname=SymbolName(s,true); //--- Get margin currency string m_cur=SymbolInfoString(symbolname,SYMBOL_CURRENCY_MARGIN); //--- Get profit currency (profit on price change) string p_cur=SymbolInfoString(symbolname,SYMBOL_CURRENCY_PROFIT); //--- if If symbol matches both currencies, return symbol name if(m_cur==margin_currency && p_cur==profit_currency) return(symbolname); } return(NULL); }
このコードから分かるように、"Market Watch" ウインドウ ( "true"がパラメータの SymbolsTotal() ファンクションがその数を与える)で使用できる全てのシンボルの計数から始める。各シンボルの名前を得るには "Market Watch"のリストの数によって、 trueパラメーターで SymbolName() ファンクションを用いる。 もしそのパラメーターを"false"にするとそのトレーディングサーバー上に送られている全てのシンボルを計数する、これは通常端末で選択されているものよりはるかに多い。
次に、通貨デポジットと見積りを得るためのシンボルの名前を使い、そしてそれらをGetSymbolByCurrencies() ファンクションで通過したものと比較する。成功した場合には、そのシンボルの名前を戻しファンクション の働きは成功して完了し先の作業に進む。繰り返しが完了して、ファンクションの最後のラインに到達し、そして何も合致せずそのシンボルが見つからなかった場合には、NULLを戻す。
これでGetSymbolByCurrencies() ファンクションを用いて、交差通貨ペアのための計算通貨 を得ることができたとして、2つの試みをする: 最初の試みではシンボルを検索することを試みる、そのデポジット通貨はマージン通貨であり(デポジット通貨 CADCHF - CAD)、そして見積り通貨はアカウントの通貨(USD)である。言い換えれば、CADUSDのペアに似たものを探すということである。
//--- If calculation currency is still not determined //--- then we have cross currency if(calc_currency="") { calc_currency=GetSymbolByCurrencies(margin_currency,account_currency); mode=true; //--- If obtained value is equal to NULL, then this symbol is not found if(calc_currency==NULL) { //--- Lets try to do it reverse calc_currency=GetSymbolByCurrencies(account_currency,margin_currency); mode=false; } }
この試みが失敗すれば、もう一つの可能性を試みる:デポジット通貨がアカウント通貨(USD)であり、見積り通貨がマージン通貨(CADCHFのデポジット通貨 - CAD)であるシンボルを探す。すなわちUSDCADに似た何かを探すのである。
これで計算通貨のペアを見つけたとして、それは2つの可能性の1つである - 直接あるいは逆。逆通貨ペアに対してモード変数は"true"と仮定している。直接の通貨ペアを得た場合には、値は"false"である。値が"true"の場合、通貨ペアの交換レートで掛け算をし、 "false"の値ではアカウント通貨の標準契約の額で割り算をする。
ここで見つかった計算通貨に対するアカウント通貨でのデポジット額の最終の計算をする。それはどちらの可能性の場合 - 直接あるいは逆の通貨ペア - でも適合する。.
//--- We know calculation currency, let's get its last prices MqlTick tick; SymbolInfoTick(calc_currency,tick); //--- Now we have everything for calculation double calc_price; //--- Calculate for Buy if(direction==POSITION_TYPE_BUY) { //--- Reverse quote if(mode) { //--- Calculate using Buy price for reverse quote calc_price=tick.ask; answer=lot*lot_size*calc_price; } //--- Direct quote else { //--- Calculate using Sell price for direct quote calc_price=tick.bid; answer=lot*lot_size/calc_price; } } //--- Calculate for Sell if(direction==POSITION_TYPE_SELL) { //--- Reverse quote if(mode) { //--- Calculate using Sell price for reverse quote calc_price=tick.bid; answer=lot*lot_size*calc_price; } //--- Direct quote else { //--- Calculate using Buy price for direct quote calc_price=tick.ask; answer=lot*lot_size/calc_price; } }
得られた結果を戻す。
//--- Return result - amount of equity in account currency, required to open position in specified volume return (Answer);
GetMarginForOpening() ファンクションはこの時点でその働きを完了する。最後にしなければならないことは、得られた値を与えられたレバレッジの額で割ることであり - そうすると仮定した方向での特定の大きさのポジションを開くのに対してのマージンの値を得る。逆あるいは交差の通貨ペアを表わすシンボルに対しては、マージンの値は各チックで変化することを忘れてはいけない。
ここに SymbolInfo_Advanced.mq5 エキスパートアドバイザーのコードの部分を載せる。完全なコードはファイルとして添付されている。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- String variable for comment string com="\r\n"; StringAdd(com,Symbol()); StringAdd(com,"\r\n"); //--- Size of standard contract double lot_size=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE); //--- Margin currency string margin_currency=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_MARGIN); StringAdd(com,StringFormat("Standard contract: %.2f %s",lot_size,margin_currency)); StringAdd(com,"\r\n"); //--- Leverage int leverage=(int)AccountInfoInteger(ACCOUNT_LEVERAGE); StringAdd(com,StringFormat("Leverage: 1/%d",leverage)); StringAdd(com,"\r\n"); //--- Calculate value of contract in account currency StringAdd(com,"Deposit for opening positions in 1 lot consists "); //--- Calculate margin using leverage double margin=GetMarginForOpening(1,Symbol(),POSITION_TYPE_BUY)/leverage; StringAdd(com,DoubleToString(margin,2)); StringAdd(com," "+AccountInfoString(ACCOUNT_CURRENCY)); Comment(com); }
そしてこの仕事の結果がチャートにある。
結論
ここに与えられた例はトレーディングアカウントの最も重要な特性について、そして金融商品の特性についての情報を得ることがいかに容易で簡単に行うことができるかを紹介した。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/113





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