118 lines
No EOL
9 KiB
Text
118 lines
No EOL
9 KiB
Text
// シャープレシオ取得
|
|
double InitialBalance;
|
|
|
|
|
|
int OnInit()
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
// 初期証拠金取得
|
|
if(IsTesting() || IsOptimization())
|
|
{
|
|
InitialBalance = AccountBalance();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
double OnTester()
|
|
{
|
|
// 開発モード Development = true で、BT時のファイル出力と、return内項目をOnTester欄表示
|
|
if (Development && IsOptimization())
|
|
{
|
|
string filename = "BacktestResults.csv";
|
|
int filehandle = FileOpen(filename, FILE_CSV|FILE_WRITE|FILE_READ, ",");
|
|
// CSVヘッダーを書き込む
|
|
if (FileTell(filehandle) == 0)
|
|
{
|
|
FileWrite(filehandle, "損益", "総取引数", "PF", "期待利得", "DD$", "DD%",
|
|
"RF", "シャープレシオ", "勝率", "RRR", "パラメータ1", "パラメータ2");
|
|
}
|
|
|
|
// バックテストの結果からデータを取得
|
|
double totalProfit = NormalizeDouble(TesterStatistics(STAT_PROFIT), 2);
|
|
int totalTrades = (int)TesterStatistics(STAT_TRADES);
|
|
double PF = NormalizeDouble(TesterStatistics(STAT_PROFIT_FACTOR), 2);
|
|
double ExPayoff = NormalizeDouble(TesterStatistics(STAT_EXPECTED_PAYOFF), 2);
|
|
double DDAmount = NormalizeDouble(TesterStatistics(STAT_EQUITY_DD), 2);
|
|
double DDPer = NormalizeDouble(TesterStatistics(STAT_EQUITYDD_PERCENT), 2);
|
|
double RF = NormalizeDouble(TesterStatistics(STAT_PROFIT) / TesterStatistics(STAT_EQUITY_DD), 2);
|
|
double Sharpre = NormalizeDouble(SharpeRatio(InitialBalance), 2);
|
|
double WinPercent = NormalizeDouble(100*TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES), 2);
|
|
double RRRatio = NormalizeDouble((TesterStatistics(STAT_GROSS_PROFIT) / TesterStatistics(STAT_PROFIT_TRADES))/
|
|
(-TesterStatistics(STAT_GROSS_LOSS) / TesterStatistics(STAT_LOSS_TRADES)), 2);
|
|
|
|
// 入力パラメータの取得
|
|
int parameters1 = MA_TF;
|
|
int parameters2 = MA_Period;
|
|
|
|
// 結果をファイルに書き込む
|
|
for(int i = 0; i < 5000; i++)
|
|
{
|
|
FileClose(filehandle); // ファイルが開きっぱなしで開けないエラーを防ぐ
|
|
filehandle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1
|
|
|
|
if (filehandle != INVALID_HANDLE)
|
|
{
|
|
FileSeek(filehandle, 0, SEEK_END); // ファイルの末尾に移動
|
|
FileWrite(filehandle, totalProfit, totalTrades, PF, ExPayoff, DDAmount, DDPer,
|
|
RF, Sharpre, WinPercent, RRRatio, parameters1, parameters2);
|
|
FileClose(filehandle);
|
|
break;
|
|
}
|
|
if (filehandle == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました");
|
|
}
|
|
|
|
// シャープレシオ
|
|
return(NormalizeDouble(SharpeRatio(InitialBalance), 2));
|
|
// リカバリーファクター
|
|
//return(NormalizeDouble(TesterStatistics(STAT_PROFIT) / TesterStatistics(STAT_EQUITY_DD), 2));
|
|
// 勝率
|
|
// return(NormalizeDouble(100*TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES), 2));
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| シャープレシオ計算 |
|
|
//+------------------------------------------------------------------+
|
|
double SharpeRatio(double Balance)
|
|
{
|
|
int i;
|
|
int CalcMonth = 0;
|
|
int TradeMonths = 0;
|
|
double MonthlyProfit[];
|
|
|
|
for(i = 0; i < OrdersHistoryTotal(); i++){
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == false) break;
|
|
|
|
int CloseMonth = TimeMonth(OrderCloseTime());
|
|
if(CalcMonth != CloseMonth){
|
|
CalcMonth = CloseMonth;
|
|
TradeMonths++;
|
|
ArrayResize(MonthlyProfit, TradeMonths);
|
|
}
|
|
MonthlyProfit[TradeMonths - 1] += OrderProfit();
|
|
}
|
|
|
|
double MonthlyEarningRate[];
|
|
ArrayResize(MonthlyEarningRate, ArraySize(MonthlyProfit));
|
|
double SumMER = 0;
|
|
|
|
for(i = 0; i < ArraySize(MonthlyProfit); i++){
|
|
MonthlyEarningRate[i] = MonthlyProfit[i] / Balance;
|
|
SumMER += MonthlyEarningRate[i];
|
|
Balance += MonthlyProfit[i];
|
|
}
|
|
|
|
double MER_Average = SumMER / TradeMonths;
|
|
double MER_SD = iStdDevOnArray(MonthlyEarningRate, 0, TradeMonths, 0, 0, 0);
|
|
double SR = 1;
|
|
if(MER_SD != 0) SR = MER_Average / MER_SD; // ゼロ割を回避
|
|
|
|
return SR;
|
|
}
|
|
//+------------------------------------------------------------------+ |