gryps2/UI-code/T-056_バックテスト時csv出力.txt
super.admin ae3f0ebf03 convert
2025-05-30 14:58:21 +02:00

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;
}
//+------------------------------------------------------------------+