TesterWithdrawal関数の働き・役割
TesterWithdrawal関数は、バックテスト環境での出金動作をシミュレートするために使用されます。特に資産管理システムを構築する際に役立つ機能であり、テスト条件で設定した利益や残高条件に基づいて、資金の引き出し処理を再現できます。この関数は、指定された金額の出金を行い、システム内での資産減少を仮想的に実行します。
TesterWithdrawal関数の引数について
TesterWithdrawal関数は、出金処理に必要な金額を指定する1つの引数を取ります。
bool TesterWithdrawal(
double money // 出金の合計額
);
money
この引数は、出金の合計額を指定します。金額は、テストで使用される取引口座の預金通貨単位で入力します。例えば、口座通貨がUSDの場合、ここで指定する金額もUSDで扱われます。
TesterWithdrawal関数の戻り値について
TesterWithdrawal関数の戻り値は、出金処理が成功したかどうかを示すブール値です。具体的には、出金が正常に行われた場合はtrueを返し、何らかの理由で出金ができなかった場合にはfalseを返します。
TesterWithdrawal関数を使ったサンプルコード
//--- 必要なライブラリをインクルードする
#include <Trade\Trade.mqh> // 取引機能のライブラリ、CTradeクラスを使用
#include <Trade\SymbolInfo.mqh> // シンボル情報のライブラリ、CSymbolInfoクラスを使用
#include <Trade\AccountInfo.mqh> // アカウント情報のライブラリ、CAccountInfoクラスを使用
//--- 定数を定義する
#define BALANCE_PROFIT_WITHDRAWAL 5 // テスターの口座から資金が引き出される基準となる残高利益の値(5単位)
//--- 入力パラメータ
input double InpLots = 0.1; // ロットサイズ(取引数量)
input uint InpStopLoss = 50; // ストップロスの値(ポイント単位)
input uint InpTakeProfit = 150; // テイクプロフィットの値(ポイント単位)
input ulong InpMagic = 123; // マジックナンバー(ポジション識別用)
input ulong InpDeviation = 5; // 許容される価格偏差(スリッページの許容範囲)
//--- グローバル変数の宣言
CTrade trade; // 取引操作用のクラスインスタンス
CSymbolInfo symb; // シンボル(銘柄)情報を管理するクラスインスタンス
CAccountInfo account; // 取引口座情報を管理するクラスインスタンス
double balance_prev; // 前回の口座残高を保持する変数
double balance_op_sum; // 出金操作の合計金額を保持する変数
uint balance_op_total; // 出金操作の回数をカウントする変数
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 初期口座残高を取得し変数に保存する
balance_prev = account.Balance();
//--- 出金操作の合計金額と回数を初期化する
balance_op_sum = 0;
balance_op_total = 0;
//--- 初期化が正常に完了したことを示す値を返す
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| エキスパートティック関数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 現在の相場情報を更新する
if(!symb.RefreshRates()) // 情報の更新が失敗した場合は処理を中断
return;
//--- 残高が変化している場合のみ処理を続行する
if(balance_prev != account.Balance())
{
//--- 現在の残高が前回の残高に定義した基準値(BALANCE_PROFIT_WITHDRAWAL)を加えた額を超えている場合
if(account.Balance() > balance_prev + BALANCE_PROFIT_WITHDRAWAL)
{
//--- 残高の増加分(利益)を計算
double profit = account.Balance() - balance_prev;
PrintFormat("口座残高が %.2f %s 増加しました。この利益分を出金します。", profit, account.Currency());
//--- 出金を試みる
if(TesterWithdrawal(profit))
{
//--- 出金成功時、出金回数を1増やし、合計出金金額に利益額を加算
balance_op_total++;
balance_op_sum += profit;
//--- 現在の残高を更新し、次回比較用に保存
balance_prev = account.Balance();
PrintFormat("出金が成功しました。現在の口座残高: %.2f %s", account.Balance(), account.Currency());
PrintFormat("総出金回数: %lu, 出金総額: %.2f %s", balance_op_total, balance_op_sum, account.Currency());
}
/*
結果例:
口座残高が 21.00 USD 増加しました。この利益分を出金します。
deal #13 balance -21.00 [withdrawal] done
出金が成功しました。現在の口座残高: 10000.00 USD
総出金回数: 1, 出金総額: 21.00 USD
*/
}
}
}
//+------------------------------------------------------------------+
//| テスタ関数 |
//+------------------------------------------------------------------+
double OnTester()
{
//--- 残高ドローダウンの金額換算値を取得
double ret = TesterStatistics(STAT_BALANCE_DD);
//--- 最大ドローダウン、出金回数、およびその合計額をエキスパートログに出力
PrintFormat("最大残高ドローダウン(資金換算): %.2f %s, 出金回数: %lu, 出金総額: %.2f %s",
ret, account.Currency(), balance_op_total, balance_op_sum, account.Currency());
//--- 結果を返す(最大ドローダウン金額)
return(ret);
/*
結果例:
最大残高ドローダウン(資金換算): 5188.50 USD, 出金回数: 2, 出金総額: 36.00 USD
最終残高 4867.50 USD
OnTester の結果 5188.5
*/
}
このコードでは、TesterWithdrawal関数を使って、指定された基準以上の利益が発生した場合に出金動作をエミュレート(模擬的に模倣)しています。豊富な日本語コメントを含め、各処理の意味がわかりやすくなるように解説を追加しています。
サンプルコード解説1:グローバル領域部分
//--- 必要なライブラリをインクルードする
#include <Trade\Trade.mqh> // 取引機能のライブラリ、CTradeクラスを使用
#include <Trade\SymbolInfo.mqh> // シンボル情報のライブラリ、CSymbolInfoクラスを使用
#include <Trade\AccountInfo.mqh> // アカウント情報のライブラリ、CAccountInfoクラスを使用
//--- 定数を定義する
#define BALANCE_PROFIT_WITHDRAWAL 5 // テスターの口座から資金が引き出される基準となる残高利益の値(5単位)
//--- 入力パラメータ
input double InpLots = 0.1; // ロットサイズ(取引数量)
input uint InpStopLoss = 50; // ストップロスの値(ポイント単位)
input uint InpTakeProfit = 150; // テイクプロフィットの値(ポイント単位)
input ulong InpMagic = 123; // マジックナンバー(ポジション識別用)
input ulong InpDeviation = 5; // 許容される価格偏差(スリッページの許容範囲)
//--- グローバル変数の宣言
CTrade trade; // 取引操作用のクラスインスタンス
CSymbolInfo symb; // シンボル(銘柄)情報を管理するクラスインスタンス
CAccountInfo account; // 取引口座情報を管理するクラスインスタンス
double balance_prev; // 前回の口座残高を保持する変数
double balance_op_sum; // 出金操作の合計金額を保持する変数
uint balance_op_total; // 出金操作の回数をカウントする変数
このコードのグローバル領域では、出金処理や取引関連の操作を行うためのライブラリをインクルードし、必要な入力パラメータやグローバル変数を定義しています。
ライブラリのインクルード
コードの最初に、取引や口座情報、シンボル情報などのクラスを使用するために必要なライブラリがインクルードされています。
- Trade\Trade.mqh
取引に関する機能を提供するライブラリで、CTradeクラスを使用するためにインクルードされています。このクラスを使って取引を行う操作を簡単に実装できます。 - Trade\SymbolInfo.mqh
シンボル(銘柄)に関する情報を管理するためのライブラリで、CSymbolInfoクラスを利用しています。銘柄の価格やティックデータの更新ができ、取引に関連した最新の相場情報を取得するために使用されます。 - Trade\AccountInfo.mqh
取引口座に関する情報を取得するためのライブラリで、CAccountInfoクラスを利用します。このクラスを使用して口座の残高や利益、通貨情報を取得でき、出金処理や資産管理を行う際に役立ちます。
定数の定義
次に、定数としてBALANCE_PROFIT_WITHDRAWALを定義しています。この定数は、テスト環境において利益がどの程度増加した場合に出金を行うかを基準として設定されています。ここでは「5単位」という値が設定されており、口座残高がこの基準を超えた場合に出金処理が実行されます。
入力パラメータの宣言
入力パラメータはエキスパートアドバイザー(EA)の実行時に設定することができ、取引のルールを変更するために使用されます。
- InpLots
取引する数量(ロットサイズ)を設定します。ロットサイズは、1回の取引でどれだけの資金を投じるかを指定するもので、ここでは0.1ロットに設定されています。 - InpStopLoss
ストップロスの値をポイント単位で指定します。ここでは「50ポイント」に設定されており、損失を50ポイントで抑えるために使われます。 - InpTakeProfit
テイクプロフィットの値をポイント単位で指定します。ここでは「150ポイント」に設定されており、利益が150ポイントに達した場合に自動的に利益を確定します。 - InpMagic
取引を識別するためのマジックナンバーです。これにより、他の取引と識別することが可能で、管理や操作を行う際に役立ちます。 - InpDeviation
スリッページの許容範囲をポイント単位で指定します。スリッページとは、希望価格から実際の約定価格がずれることを指し、ここでは5ポイント以内であれば許容するように設定されています。
グローバル変数の宣言
最後に、コードのグローバル領域で必要なグローバル変数を宣言しています。
- trade
CTradeクラスのインスタンスで、取引操作を行うために使用されます。例えば、売買注文の送信やポジション管理などを実行できます。 - symb
CSymbolInfoクラスのインスタンスで、銘柄情報を管理します。この変数を使って、取引を行う銘柄の価格情報などを取得します。 - account
CAccountInfoクラスのインスタンスで、口座情報を管理します。取引口座の残高や利益、通貨などの情報を取得するために使用されます。 - balance_prev
前回の残高を保持する変数で、出金処理の基準として使用されます。この変数の値を現在の残高と比較し、利益が設定基準を超えた場合に出金処理を行います。 - balance_op_sum
出金操作の合計金額を保持する変数です。出金が発生するたびに出金額が加算され、総出金額を管理するために利用します。 - balance_op_total
出金操作の回数をカウントする変数で、出金が発生するたびにカウントが1つ増加します。この変数を使って総出金回数を記録します。
プルコード解説2:OnInit関数部分
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 口座残高を初期化
balance_prev = account.Balance(); // 初期の残高をbalance_prevに設定
balance_dep_sum = 0; // 入金総額の初期化
balance_dep_total = 0; // 入金回数の初期化
//--- 正常な初期化が完了した場合にINIT_SUCCEEDEDを返す
return(INIT_SUCCEEDED);
}
このセクションのOnInit関数は、エキスパートアドバイザーの初期化を行うための関数です。主に初期設定として、口座の初期残高や入金に関する変数を初期化し、正常に初期化が完了したことを示すための戻り値を返します。
- balance_prevは、account.Balanceメソッドを使用して、口座の現在の残高を取得し、この値を変数balance_prevに保存しています。これにより、エキスパートアドバイザー実行時の初期残高が記録され、後続の処理で使用されます。
- balance_dep_sumは、入金された総額を記録する変数で、初期化時には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:OnInit関数部分その3
//--- 現在の残高が前回の残高に定義した基準値(BALANCE_PROFIT_WITHDRAWAL)を加えた額を超えている場合
if(account.Balance() > balance_prev + BALANCE_PROFIT_WITHDRAWAL)
{
//--- 残高の増加分(利益)を計算
double profit = account.Balance() - balance_prev;
PrintFormat("口座残高が %.2f %s 増加しました。この利益分を出金します。", profit, account.Currency());
ここでは、前回の残高を基に出金処理が必要かを判断するロジックが含まれています。このコードは、利益が一定の基準額を超えた場合に出金を行うための処理を行います。
残高チェックと基準額の設定
まず、現在の口座残高であるaccount.Balanceメソッドが前回記録された残高balance_prev変数に加え、あらかじめ定義した基準値BALANCE_PROFIT_WITHDRAWAL変数を超えているかを確認しています。この基準値は利益が発生してもすぐに引き出しを行わず、ある程度の増加があった場合にのみ出金を行う目的で設定され、ここでは5としています。
この条件により、口座残高account.Balanceメソッドが基準値BALANCE_PROFIT_WITHDRAWAL変数を超える場合のみ、以下の出金プロセスが実行されます。
利益の計算
残高が基準を超えた場合、現在の残高account.Balanceメソッドと前回の残高balance_prev変数の差分が「利益」として計算されます。この利益額は変数profitに保存され、出金する金額としてTesterWithdrawal関数に渡されます。
利益の算出方法としては、account.Balanceメソッド(現在の残高)からbalance_prev変数(前回の残高)を引くことで求めています。この差額profit変数は、テスト内での資産管理に利用されます。
ログ出力
次に、出金対象となる利益額profit変数と口座の通貨単位account.Currencyメソッドをエキスパートログに出力します。PrintFormat関数を用いることで、profit変数やaccount.Currencyメソッドの情報をわかりやすく表示しています。
このログメッセージにより、利益が発生して出金プロセスが開始されることを示し、利益額が口座通貨単位で表示されるため、テスト中の資産管理状況を把握しやすくしています。
サンプルコード解説6:OnTick関数部分その4
//--- 出金を試みる
if(TesterWithdrawal(profit))
{
//--- 出金成功時、出金回数を1増やし、合計出金金額に利益額を加算
balance_op_total++;
balance_op_sum += profit;
//--- 現在の残高を更新し、次回比較用に保存
balance_prev = account.Balance();
PrintFormat("出金が成功しました。現在の口座残高: %.2f %s", account.Balance(), account.Currency());
PrintFormat("総出金回数: %lu, 出金総額: %.2f %s", balance_op_total, balance_op_sum, account.Currency());
}
/*
結果例:
口座残高が 21.00 USD 増加しました。この利益分を出金します。
deal #13 balance -21.00 [withdrawal] done
出金が成功しました。現在の口座残高: 10000.00 USD
総出金回数: 1, 出金総額: 21.00 USD
*/
}
}
}
ここでは、利益が一定基準を超えた場合にTesterWithdrawal関数を使って出金を試みる処理と、出金結果をログに出力する部分について解説します。
出金処理の試行
まず、利益額profit変数をTesterWithdrawal関数に渡して出金を試みます。TesterWithdrawal関数は出金が成功したかどうかを示すブール値を返し、出金が成功した場合にのみ以下の処理が実行されます。
出金成功時の処理
出金が成功すると、出金回数と合計出金金額が更新されます。
- balance_op_total変数は、出金回数を管理するための変数であり、出金が成功するたびに1ずつ増加させています。
- balance_op_sum変数には、これまでに出金した全ての金額の合計が保持されており、今回の利益額profit変数を加算しています。
この更新により、出金が何回行われたか、またその合計額が記録されます。
前回の残高の更新
次に、balance_prev変数に現在の口座残高account.Balanceメソッドの値を保存します。これにより、次回の残高変動チェック時に新しい基準となる値が設定されます。この更新により、残高が再び基準値を超えたときにのみ出金が行われるようになります。
ログ出力とフォーマット指定子の使用
PrintFormat関数を使用して、出金成功時のメッセージをエキスパートログに出力しています。このメッセージには以下のフォーマット指定子が含まれており、特定の変数の値をわかりやすく表示します。
- %.2f: 小数点以下2桁までの浮動小数点数として値を表示します。ここではaccount.Balanceメソッドで取得した現在の残高や出金総額balance_op_sum変数、利益額profit変数が使用されています。
- %s:文字列として値を表示します。ここではaccount.Currencyメソッドにより、口座の通貨単位(USDなど)が出力されます。
- %lu: 符号なし整数(長整数)として値を表示します。ここでは出金回数balance_op_total変数が使用されています。
例えば、PrintFormat関数による出力内容の例として、以下のようなメッセージが表示されます。
- 「出金が成功しました。現在の口座残高: 10000.00 USD」
- 「総出金回数: 1, 出金総額: 21.00 USD」
これにより、出金処理の結果が詳細に記録され、口座残高の確認や出金回数・合計額の把握が簡単になります。
サンプルコード解説7:OnTester関数部分
//+------------------------------------------------------------------+
//| テスタ関数 |
//+------------------------------------------------------------------+
double OnTester()
{
//--- 残高ドローダウンの金額換算値を取得
double ret = TesterStatistics(STAT_BALANCE_DD);
//--- 最大ドローダウン、出金回数、およびその合計額をエキスパートログに出力
PrintFormat("最大残高ドローダウン(資金換算): %.2f %s, 出金回数: %lu, 出金総額: %.2f %s",
ret, account.Currency(), balance_op_total, balance_op_sum, account.Currency());
//--- 結果を返す(最大ドローダウン金額)
return(ret);
/*
結果例:
最大残高ドローダウン(資金換算): 5188.50 USD, 出金回数: 2, 出金総額: 36.00 USD
最終残高 4867.50 USD
OnTester の結果 5188.5
*/
}
このOnTester関数では、テスト結果の評価指標として最大残高ドローダウンを取得し、出金の詳細情報とともにエキスパートログに出力しています。バックテストにおけるドローダウンの確認と出金処理の履歴を把握するための重要な機能です。
残高ドローダウンの取得
まず、TesterStatistics関数を使って、STAT_BALANCE_DD定数に基づく最大残高ドローダウン金額換算値を取得し、その値を変数retに格納します。STAT_BALANCE_DD定数は、テストにおいて最大の資金減少を示すための定数であり、テストのリスク評価に役立ちます。このドローダウンの金額は、特にバックテスト中の最大リスクを把握するために重要です。
出金履歴のログ出力
次に、PrintFormat関数を使用して、最大ドローダウン額(ret変数)と、これまでの出金に関する情報(出金回数balance_op_total変数と合計出金額balance_op_sum変数)をエキスパートログに出力します。
PrintFormat関数では、以下のフォーマット指定子を使用してデータを表示しています:
%.
2f
: 小数点以下2桁までの浮動小数点数を表示するフォーマット指定子です。ret変数(最大ドローダウン額)とbalance_op_sum変数(合計出金額)の数値を表示する際に使用されます。- %s:文字列を表示するフォーマット指定子です。account.Currencyメソッドで取得した通貨単位がここに挿入されます。
- %lu: 符号なし長整数を表示するフォーマット指定子で、ここでは出金回数を表すbalance_op_total変数が挿入されます。
これにより、エキスパートログに最大ドローダウン額、出金回数、およびその合計額がわかりやすく表示され、以下のようなメッセージがエキスパートログに出力されます。
- 「最大残高ドローダウン(資金換算): 5188.50 USD, 出金回数: 2, 出金総額: 36.00 USD」
関数の戻り値
最後に、ret変数の値(最大ドローダウン額)を戻り値として返しています。この戻り値はテストの最終評価結果として利用され、OnTester関数が持つ評価指標としての役割を果たします。
このように、OnTester関数を使用することで、バックテストの結果に基づくリスク指標や資産管理の詳細が確認でき、テスト結果の分析に役立ちます。
TesterWithdrawal関数を使ってEAを作る際のアイディア
TesterWithdrawal関数を活用したエキスパートアドバイザー(EA)では、利益が発生する度に適切な資金管理を行うことで、テスト環境下でのリスク管理を強化できます。この関数は出金処理をシミュレートするため、資産の保護や複利効果の最適化に役立ちます。以下に、いくつかのEA開発アイディアを紹介します。
利益確保とリスク分散を意識したトレーリング出金EA
TesterWithdrawal関数をトレーリングストップのように活用し、一定の利益が発生する度に出金を行うEAを作成します。利益が発生する度にその一部を出金し、口座残高を守ることで、相場の急変動に対応しやすくする戦略です。このEAでは、各トレードの利益から特定の割合を引き出すため、口座の安全を確保しつつリスク分散ができます。
一定期間ごとの定期出金システム
TesterWithdrawal関数を使い、週単位や月単位といった一定の期間ごとに出金処理を行うEAを設計します。トレード期間中に安定した利益が得られた場合にその利益を引き出し、再投資資金と利益を分けて管理するため、長期的な安定運用が目指せます。また、利益が出金基準に満たない場合は再投資に回し、効率的な運用も可能です。
利益とドローダウンを考慮したリバランスEA
TesterWithdrawal関数とOnTester関数で取得できる最大ドローダウンの情報を組み合わせて、リスク調整を行うリバランスEAを作成します。利益が一定基準に達した際には出金を行い、さらにドローダウンが大きくなった場合に取引ロットを減らしてリスクを抑えるといった運用が可能です。このアプローチにより、利益確保とリスク管理のバランスを保ちながら、資産運用が行えます。
利益基準の自動調整機能付き出金EA
一定額の利益が発生した際に出金基準額(BALANCE_PROFIT_WITHDRAWAL変数)を自動的に調整するEAを作成します。利益が増加するにつれて、出金基準も増加させることで、複利的に資産を増やす工夫が可能です。例えば、利益基準を段階的に引き上げていき、リスク管理と利益確保のバランスを保ちながら資金を運用します。