TesterDeposit関数の働き・役割
TesterDeposit関数は、ストラテジーテスターでのシミュレーション中に資金を入金することをエミュレート(模擬的に再現)するための特殊な関数です。この関数を利用することで、テスト中の資金管理システムにおける資金の追加シナリオを再現でき、口座残高のドローダウンが発生した場合の資金補充を含む資金管理シミュレーションを実行できます。
TesterDeposit関数の引数について
TesterDeposit関数の引数構成は以下の通りです。
bool TesterDeposit(
double money // 入金額
);
引数の詳細
moneyは、預金通貨での口座への入金額を指定します。テスト中の口座残高が減少した際に、この引数で指定した金額が口座に追加されます。たとえば、引数に100.0を指定した場合、テスト中の口座に100.0の入金が行われます。
TesterDeposit関数の戻り値について
TesterDeposit関数は、資金の入金処理が成功したかどうかを示す真偽値(ブール型)を返します。具体的には、資金が正常に入金された場合にはtrueを返し、何らかの理由で入金が行われなかった場合にはfalseを返します。
戻り値を利用することで、資金の追加が正常に完了したかを確認でき、適切なロジックを構築することが可能です。
TesterDeposit関数を使ったサンプルコード
//--- 必要なライブラリをインクルードする
#include <Trade\Trade.mqh> // 取引機能のライブラリ、CTradeクラスを使用
#include <Trade\SymbolInfo.mqh> // シンボル情報のライブラリ、CSymbolInfoクラスを使用
#include <Trade\AccountInfo.mqh> // アカウント情報のライブラリ、CAccountInfoクラスを使用
//--- define
#define BALANCE_LOSS_DEPOSIT 100.0 // テスターの口座に資金が入金される残高ドローダウンの値
//--- 入力パラメータ
input double InpLots = 0.1; // ロット数
input uint InpStopLoss = 50; // ポイント単位のストップロス値
input uint InpTakeProfit = 150; // ポイント単位のテイクプロフィット値
input ulong InpMagic = 123; // マジックナンバー
input ulong InpDeviation = 5; // 偏差(注文価格と実際の約定価格の許容範囲)
//--- グローバル変数
CTrade trade; // CTradeクラスのインスタンス(取引機能の操作を管理する)
CSymbolInfo symb; // CSymbolInfoクラスのインスタンス(シンボル情報を管理する)
CAccountInfo account; // CAccountInfoクラスのインスタンス(取引口座情報を管理する)
double balance_dep_summ; // 入金された総額を保持する変数
uint balance_dep_total; // 入金回数を保持する変数
double balance_prev; // 前回の口座残高を保持する変数
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 口座残高を初期化
balance_prev = account.Balance(); // 初期の残高をbalance_prevに設定
balance_dep_summ = 0; // 入金総額の初期化
balance_dep_total = 0; // 入金回数の初期化
//--- 正常な初期化が完了した場合にINIT_SUCCEEDEDを返す
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| エキスパートティック関数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 現在のシンボルの価格情報を更新
if(!symb.RefreshRates()) // シンボルの価格が更新できなかった場合は終了
return;
//--- 口座残高が前回値よりも大きく減少している場合の処理
if(balance_prev != account.Balance()) // 前回の残高と現在の残高が異なる場合
{
//--- 残高が設定した値BALANCE_LOSS_DEPOSITよりも減少しているか確認
if(account.Balance() < balance_prev - BALANCE_LOSS_DEPOSIT)
{
// 損失額を計算
double loss = balance_prev - account.Balance();
PrintFormat("初期残高 %.2f %s は %.2f %s 減少しました。入金が必要です。", balance_prev, account.Currency(), loss, account.Currency());
//--- TesterDeposit関数を使って損失額分を入金
if(TesterDeposit(loss)) // 入金が成功した場合
{
balance_dep_total++; // 入金回数を1増加
balance_dep_summ += loss; // 入金総額に今回の入金額を追加
balance_prev = account.Balance(); // 現在の残高を更新してbalance_prevに保存
//--- 入金が成功したことをエキスパートログに出力
PrintFormat("口座に資金が入金されました。現在の残高: %.2f %s", account.Balance(), account.Currency());
PrintFormat("総入金回数: %lu, 総入金額: %.2f %s", balance_dep_total, balance_dep_summ, account.Currency());
}
}
}
}
//+------------------------------------------------------------------+
//| テスタ関数 |
//+------------------------------------------------------------------+
double OnTester()
{
//--- 最大残高ドローダウンを金額換算で取得し、出力ハンドラー値として設定する
double ret = TesterStatistics(STAT_BALANCE_DD); // 最大残高ドローダウンを取得
//--- ドローダウン、入金回数、入金総額をエキスパートログに表示
PrintFormat("%s: 最大残高ドローダウン: %.2f %s. 総入金回数: %lu, 総入金額: %.2f %s.", __FUNCTION__, ret, account.Currency(), balance_dep_total, balance_dep_summ, account.Currency());
//--- 結果を返す
return(ret);
}
サンプルコード解説1:グローバル領域部分
//--- 必要なライブラリをインクルードする
#include <Trade\Trade.mqh> // 取引機能のライブラリ、CTradeクラスを使用
#include <Trade\SymbolInfo.mqh> // シンボル情報のライブラリ、CSymbolInfoクラスを使用
#include <Trade\AccountInfo.mqh> // アカウント情報のライブラリ、CAccountInfoクラスを使用
//--- define
#define BALANCE_LOSS_DEPOSIT 100.0 // テスターの口座に資金が入金される残高ドローダウンの値
//--- 入力パラメータ
input double InpLots = 0.1; // ロット数
input uint InpStopLoss = 50; // ポイント単位のストップロス値
input uint InpTakeProfit = 150; // ポイント単位のテイクプロフィット値
input ulong InpMagic = 123; // マジックナンバー
input ulong InpDeviation = 5; // 偏差(注文価格と実際の約定価格の許容範囲)
//--- グローバル変数
CTrade trade; // CTradeクラスのインスタンス(取引機能の操作を管理する)
CSymbolInfo symb; // CSymbolInfoクラスのインスタンス(シンボル情報を管理する)
CAccountInfo account; // CAccountInfoクラスのインスタンス(取引口座情報を管理する)
double balance_dep_summ; // 入金された総額を保持する変数
uint balance_dep_total; // 入金回数を保持する変数
double balance_prev; // 前回の口座残高を保持する変数
上記のコードは、MQL5のエキスパートアドバイザーにおいて、取引、シンボル情報、口座情報を管理するための初期設定を含んでいます。各要素の解説は以下の通りです。
必要なライブラリのインクルード
Trade.mqh、SymbolInfo.mqh、AccountInfo.mqhは、それぞれ取引、シンボル情報、口座情報を管理するためのライブラリです。
- Trade.mqhは取引に関連する機能を提供し、CTradeクラスが含まれています。
- SymbolInfo.mqhはシンボル(銘柄)に関連する情報を取得するための機能を提供し、CSymbolInfoクラスが含まれています。
- AccountInfo.mqhは口座情報を取得し、CAccountInfoクラスが含まれています。
定数の定義
BALANCE_LOSS_DEPOSITは、口座残高の損失がこの値を超えた場合に資金を追加するための基準となる定数です。ここでは、口座残高が100.0(任意の通貨)以上の損失が発生すると入金処理が行われます。
入力パラメータ
エキスパートアドバイザーで使用する取引に関する設定項目です。これらの値はユーザーが変更できる入力パラメータとして設定されています。
- InpLotsは、取引で使用するロット数(取引量)を指定します。
- InpStopLossは、ストップロスのポイント数(損失を限定するための価格差)です。
- InpTakeProfitは、テイクプロフィットのポイント数(利益確定のための価格差)です。
- InpMagicは、エキスパートアドバイザーによって発行された注文を識別するためのマジックナンバーです。
- InpDeviationは、注文価格と実際の約定価格との間の許容される偏差(スプレッド)を設定します。
グローバル変数
エキスパートアドバイザー全体で使用されるグローバル変数に宣言されています。
- tradeは、CTradeクラスのインスタンスで、取引機能の操作を管理します。
- symbは、CSymbolInfoクラスインスタンスで、シンボル情報を管理します。
- accountは、CAccountInfoクラスのインスタンスで、取引口座の情報を管理します。
- balance_dep_summは、入金された総額を記録する変数です。
- balance_dep_totalは、入金回数を記録する変数です。
- balance_prevは、最後に記録された口座残高を保持する変数で、前回の残高と現在の残高を比較するために使用されます。
サンプルコード解説2:OnInit関数部分
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 口座残高を初期化
balance_prev = account.Balance(); // 初期の残高をbalance_prevに設定
balance_dep_summ = 0; // 入金総額の初期化
balance_dep_total = 0; // 入金回数の初期化
//--- 正常な初期化が完了した場合にINIT_SUCCEEDEDを返す
return(INIT_SUCCEEDED);
}
このセクションのOnInit関数は、エキスパートアドバイザーの初期化を行うための関数です。主に初期設定として、口座の初期残高や入金に関する変数を初期化し、正常に初期化が完了したことを示すための戻り値を返します。
- balance_prevは、account.Balanceメソッドを使用して、口座の現在の残高を取得し、この値を変数balance_prevに保存しています。これにより、エキスパートアドバイザー実行時の初期残高が記録され、後続の処理で使用されます。
- balance_dep_summは、入金された総額を記録する変数で、初期化時には0に設定されます。これにより、シミュレーションが開始した段階では入金額がゼロであることが明確になります。
- balance_dep_totalは、入金が行われた回数を記録する変数で、初期値として0が設定されています。
最後に、正常な初期化が完了したことを示すため、INIT_SUCCEEDEDを返しています。これにより、エキスパートアドバイザーが正常に動作できる状態にあるかが判断され、初期化に失敗した場合にはエラーが発生することになります。
サンプルコード解説3:OnTick関数部分その1
//+------------------------------------------------------------------+
//| エキスパートティック関数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 現在のシンボルの価格情報を更新
if(!symb.RefreshRates()) // シンボルの価格が更新できなかった場合は終了
return;
OnTick関数は、エキスパートアドバイザーがティックごとに実行する動作を定義しています。ティックとは、シンボルの価格が更新されたときに発生するイベントのことで、この関数は毎ティックで呼び出され、リアルタイムで取引の処理を行います。
- symb.RefreshRatesメソッドは、シンボルの価格情報を更新する役割を持ちます。この関数により、最新の価格情報を取得し、エキスパートアドバイザー内で取引の判断を行うためのデータが更新されます。
- symb.RefreshRatesメソッドがfalseを返す場合、価格情報の更新に失敗したことを意味します。OnTick関数ではこの場合にreturn文で処理を終了させ、以降の処理が行われないようにしています。これにより、価格情報が正確でない状態で取引判断が実行されることを防止しています。
サンプルコード解説4:OnTick関数部分その2
//--- 口座残高が前回値よりも大きく減少している場合の処理
if(balance_prev != account.Balance()) // 前回の残高と現在の残高が異なる場合
OnTick関数内でのこのセクションは、口座残高の変動を監視し、前回の残高と比較して減少しているかどうかを確認する処理です。この処理により、指定された条件に基づいて資金を追加するための準備が行われます。
- account.Balanceメソッドは、現在の口座残高を取得します。前回記録した残高と比較するために、このメソッドを使用して最新の残高を取得しています。
- balance_prevとaccount.Balanceメソッドの戻り値が異なる場合、つまり残高が変動している場合のみ、次の処理が実行されます。こうすることで、残高の変化がない場合には余分な処理を行わないようになり、効率的な実行が可能となります。
このように、残高の変動が検知されたときにのみ追加の処理が行われ、残高が大きく減少した場合に特定のアクションを実行する準備が整います。
サンプルコード解説5:OnTick関数部分その3
if(account.Balance() < balance_prev - BALANCE_LOSS_DEPOSIT)
{
// 損失額を計算
double loss = balance_prev - account.Balance();
PrintFormat("初期残高 %.2f %s は %.2f %s 減少しました。入金が必要です。",
balance_prev, account.Currency(), loss, account.Currency());
このセクションでは、口座残高が前回の残高から一定の金額(BALANCE_LOSS_DEPOSIT)以上減少したかを確認し、減少した場合にその損失額を計算してログに出力する処理を行っています。
- account.Balanceメソッドは、現在の口座残高を取得します。この残高が前回の残高であるbalance_prevからBALANCE_LOSS_DEPOSITで指定した値(この例では100.0)以上減少しているかを確認します。
- balance_prevとaccount.Balanceメソッドの差がBALANCE_LOSS_DEPOSITを超えた場合、残高の減少が基準値を超えているため、次の処理が実行されます。
損失額の計算
balance_prevからaccount.Balanceメソッドの戻り値を引くことで、損失額を計算しています。これにより、初期の残高からどれだけ減少したかが分かり、その値が変数lossに格納されます。
PrintFormat関数の詳細
PrintFormat関数は、指定された文字列に変数の値を埋め込んでフォーマットされたログメッセージを出力するメソッドです。以下のフォーマット指定子と対応する値について説明します。
- %.2fは、浮動小数点数(小数点以下2桁まで)のフォーマット指定子です。この場合、balance_prevとlossに対して使用されており、口座の残高や損失額を小数点以下2桁まで表示します。
- %sは、文字列のフォーマット指定子であり、通貨の単位を表示するために使用されています。account.Currencyメソッドが返す値(口座の通貨単位)がここで埋め込まれます。
このPrintFormat関数の出力例は、「初期残高 10000.00 USD は 116.00 USD 減少しました。入金が必要です。」のようになります。
サンプルコード解説6:OnTick関数部分その4
//--- TesterDeposit関数を使って損失額分を入金
if(TesterDeposit(loss)) // 入金が成功した場合
{
balance_dep_total++; // 入金回数を1増加
balance_dep_summ += loss; // 入金総額に今回の入金額を追加
balance_prev = account.Balance(); // 現在の残高を更新してbalance_prevに保存
//--- 入金が成功したことをエキスパートログに出力
PrintFormat("口座に資金が入金されました。現在の残高: %.2f %s", account.Balance(), account.Currency());
PrintFormat("総入金回数: %lu, 総入金額: %.2f %s", balance_dep_total, balance_dep_summ, account.Currency());
}
}
}
}
このセクションでは、TesterDeposit関数を使用して損失額に相当する金額を口座に入金し、入金が成功した場合に関する処理を行っています。以下の詳細は、各ステップの具体的な解説です。
- TesterDeposit関数は、指定された金額(ここでは損失額であるloss)を口座に入金します。入金が成功するとtrueを返し、失敗した場合にはfalseを返します。この返り値を利用して、入金成功時の処理が実行されます。
- balance_dep_totalは入金回数をカウントする変数で、入金が成功するたびに1増加します。これにより、エキスパートアドバイザーが実行中に行われた総入金回数が追跡されます。
- balance_dep_summは、入金総額を記録する変数で、今回入金された金額lossが追加されます。これにより、すべての入金額が合計され、どれだけの資金が追加されたかが把握できます。
- balance_prevは、最新の口座残高であるaccount.Balanceメソッドの戻り値を使用して更新され、次回以降の残高比較に使用されます。
PrintFormat関数の詳細
PrintFormat関数は、フォーマットされたメッセージをエキスパートログに出力するために使用され、以下のフォーマット指定子と対応する値を用いて残高情報や入金に関するデータを表示します。
- %.2fは、口座残高や入金総額などの浮動小数点数(小数点以下2桁まで)を表示するフォーマット指定子です。この例では、account.Balanceメソッドとbalance_dep_summに対して使用されています。
- %sは、口座の通貨単位を示す文字列を表示するフォーマット指定子です。account.Currencyメソッドの戻り値(口座の通貨単位)がここで表示されます。
- %luは、符号なし整数を表示するためのフォーマット指定子で、入金回数を表すbalance_dep_totalに使用されています。
このPrintFormat関数の出力例は以下のようになります。
- 「口座に資金が入金されました。現在の残高: 10000.00 USD」
- 「総入金回数: 1, 総入金額: 116.00 USD」
このようにして、エキスパートログに入金の詳細が記録され、テスト結果の確認に役立ちます。
サンプルコード解説7:OnTester関数部分
//+------------------------------------------------------------------+
//| テスタ関数 |
//+------------------------------------------------------------------+
double OnTester()
{
//--- 最大残高ドローダウンを金額換算で取得し、出力ハンドラー値として設定する
double ret = TesterStatistics(STAT_BALANCE_DD); // 最大残高ドローダウンを取得
//--- ドローダウン、入金回数、入金総額をエキスパートログに表示
PrintFormat("%s: 最大残高ドローダウン: %.2f %s. 総入金回数: %lu, 総入金額: %.2f %s.", __FUNCTION__, ret, account.Currency(), balance_dep_total, balance_dep_summ, account.Currency());
//--- 結果を返す
return(ret);
}
OnTester関数は、ストラテジーテスターでエキスパートアドバイザーをテストする際に実行され、テスト結果に関する統計データを取得してエキスパートログに出力します。この関数では、最大残高ドローダウンなどの重要な資金管理指標を取得して表示し、テストの結果として返します。
- TesterStatistics関数は、指定された統計項目を取得するための関数です。ここではSTAT_BALANCE_DDを指定することで、最大残ドローダウン(残高の最大減少額)を取得し、変数retに格納しています。このデータは資金管理やリスク評価において重要な指標です。
- PrintFormat関数は、ドローダウンや入金に関する情報をフォーマットしてエキスパートログに表示するために使用されます。
PrintFormat関数の詳細
PrintFormat関数内の各フォーマット指定子と対応する値について説明します。
- %sは、関数名や通貨の単位などの文字列を表示するためのフォーマット指定子です。ここでは__FUNCTION__とaccount.Currencyメソッドから取得した値を表示しています。
- %.2fは、小数点以下2桁までの浮動小数点数を表示するフォーマット指定子です。ここでは最大残高ドローダウンのretと入金総額のbalance_dep_summに対して使用されており、金額をわかりやすく表示します。
- %luは、符号なし整数を表示するフォーマット指定子で、入金回数を表すbalance_dep_totalに使用されています。
このPrintFormat関数の出力例は次のようになります。
- 「OnTester: 最大残高ドローダウン: 5188.50 USD. 総入金回数: 46, 総入金額: 5128.50 USD.」
戻り値
最後に、最大残高ドローダウンの値をretとして返します。この戻り値を用いることで、テスト結果を評価し、EAの資金管理やリスク設定の調整に役立てることができます。
TesterDeposit関数を使ってEAを作る際のアイディア
TesterDeposit関数を活用することで、資金管理の効率を高め、さまざまなトレード戦略に適応できるエキスパートアドバイザー(EA)を構築することが可能です。以下に、TesterDeposit関数を利用したEAの開発アイディアをいくつか紹介します。
リスク管理の強化
残高のドローダウンが一定値を超えた際に自動的に資金を追加することで、EAが運用中にドローダウンを補う仕組みが構築できます。たとえば、設定した資金増加ポイントでTesterDeposit関数を使い、損失に対応する入金をシミュレートすることで、リスク管理の強化が図れます。
戦略ごとの資金補充ロジック
複数の戦略を一つのEA内で運用する際、戦略ごとに異なる資金補充ルールを設定することで、戦略に応じた資金管理が可能になります。たとえば、ボラティリティが高いシンボルの場合はドローダウンの基準値を緩やかに設定し、低ボラティリティのシンボルでは厳格に管理することで、資金管理の柔軟性を高められます。
バックテストの資金管理シミュレーション
ストラテジーテスターでのバックテスト時に、定期的に資金を補充するシナリオをシミュレーションすることで、長期運用におけるリスクとリターンをより正確に評価することができます。テスト中の複数パターンの入金スケジュールを設定して、その結果を比較し、資金管理の有効性を検証することも可能です。
リスク低減システムの開発
TesterDeposit関数を使って、損失時の入金を検知したタイミングでポジションサイズを自動的に調整するシステムを作成することが考えられます。ドローダウンが発生した場合にポジションサイズを小さくすることで、リスクを低減しながら運用するEAの開発が可能です。
パフォーマンスのトラッキング
TesterDeposit関数を利用して、損失補填による資金増加がトレードのパフォーマンスにどう影響するかを分析する機能を搭載することも有効です。ドローダウンや利益率に対する資金補充の効果を評価し、資金管理の改善につなげることができます。
これらのアイディアを活用することで、損失補填やリスク管理を効果的に行えるEAを構築でき、資金管理の強化やバックテスト結果の精度向上に役立ちます。
ANCE_PROFIT_WITHDRAWAL変数)を自動的に調整するEAを作成します。利益が増加するにつれて、出金基準も増加させることで、複利的に資産を増やす工夫が可能です。例えば、利益基準を段階的に引き上げていき、リスク管理と利益確保のバランスを保ちながら資金を運用します。