FC2ブログ

# バックテスト Back Testing
# 引数 始値 高値 安値 終値 出来高 (\@Open, \@High, \@Low, \@Close, \@Volume)
# 戻り値 バックテスト (@BackTesting)
sub BACKTESTING{
my ($Open, $High, $Low, $Close, $Volume) = @_;
my @BackTesting = ();
my @EntryFlag = ();
my @ExitFlag = ();
my @ProfitBuy = ();
my @ProfitSell = ();
my @LossBuy = ();
my @LossSell = ();
my $EntryPrice = 0;
my $Equity = 0;
my $MaximumEquity = 0;
my $Drawdown = 0;
my $MaximumDrawdown = 0;
my $CountWin = 0;
my $CountLoss = 0;
my $ConsecutiveCountWin = 0;
my $ConsecutiveCountLoss = 0;
my $Postion = 0;
my $Count = @$Close - 1;

# 配列数の確認
if(($Count < 0) || (@$Close != @$High) || (@$Close != @$Low) || (@$Close != @$Volume)){
return 0;
}

# 個別の設定
# 売買手数料
my $Commission = 0;

# フラグの取得
@EntryFlag = &ENTRYRYLE($Open, $High, $Low, $Close, $Volume);
@ExitFlag = &EXITRYLE($Open, $High, $Low, $Close, $Volume);

# 配列数を取得
$Count = (@EntryFlag > @ExitFlag ? (@ExitFlag - 1) : (@EntryFlag - 1));

# 計算
for(my $i = $Count; $i >= 0; $i--){
if($Postion == 0){
# 買い = 1 売り = -1
if($EntryFlag[$i] == 1){
# エントリー価格
$EntryPrice = $$Open[$i] + $Commission;
# ポジション
$Postion = 1;
}
elsif($EntryFlag[$i] == -1){
# エントリー価格
$EntryPrice = $$Open[$i] - $Commission;
# ポジション
$Postion = -1;
}
}else {
# 買い = 1 売り = -1
if($ExitFlag[$i] == 1){
# ポジション
$Postion = 0;

# 利益 損失
my $Diff = ($$Open[$i] - $EntryPrice) - $Commission;
if($Diff > 0){
# 利益
$ProfitBuy[@ProfitBuy] = $Diff;
# 資産
$Equity += $Diff;
# 勝ち
$CountWin++;
# 連続した勝ち
$ConsecutiveCountWin = $CountWin if($CountWin > $ConsecutiveCountWin);
# 資産の最大
if($Equity > $MaximumEquity){
$MaximumEquity = $Equity;
$Drawdown = 0;
}

# 初期化
$CountLoss = 0;
}elsif($Diff < 0) {
# 損失
$LossBuy[@LossBuy] = $Diff;
# 資産
$Equity += $Diff;
# 負け
$CountLoss++;
# 連続した負け
$ConsecutiveCountLoss = $CountLoss if($CountLoss > $ConsecutiveCountLoss);
# ドローダウン
$Drawdown = $MaximumEquity - $Equity;
# 最大ドローダウン
$MaximumDrawdown = $Drawdown if($Drawdown > $MaximumDrawdown);

# 初期化
$CountWin = 0;
}
}
elsif($ExitFlag[$i] == -1){
# ポジション
$Postion = 0;

# 利益 損失
my $Diff = ($EntryPrice - $$Open[$i]) - $Commission;
if($Diff > 0){
# 利益
$ProfitSell[@ProfitSell] = $Diff;
# 資産
$Equity += $Diff;
# 勝ち
$CountWin++;
# 連続した勝ち
$ConsecutiveCountWin = $CountWin if($CountWin > $ConsecutiveCountWin);
# 資産の最大
if($Equity > $MaximumEquity){
$MaximumEquity = $Equity;
$Drawdown = 0;
}

# 初期化
$CountLoss = 0;
}elsif($Diff < 0) {
# 損失
$LossSell[@LossSell] = $Diff;
# 資産
$Equity += $Diff;
# 負け
$CountLoss++;
# 連続した負け
$ConsecutiveCountLoss = $CountLoss if($CountLoss > $ConsecutiveCountLoss);
# ドローダウン
$Drawdown = $MaximumEquity - $Equity;
# 最大ドローダウン
$MaximumDrawdown = $Drawdown if($Drawdown > $MaximumDrawdown);

# 初期化
$CountWin = 0;
}
}
}
}

# 合計 平均 取引回数 [0] 合計 [1] 平均 [2] 取引回数
@ProfitBuy = &SUMAVERAGE(\@ProfitBuy);
@ProfitSell = &SUMAVERAGE(\@ProfitSell);
@LossBuy = &SUMAVERAGE(\@LossBuy);
@LossSell = &SUMAVERAGE(\@LossSell);

# 結果
# [0] 取引回数
$BackTesting[0] = ($ProfitBuy[2] + $ProfitSell[2]) + ($LossBuy[2] + $LossSell[2]);
# [1] 勝率
$BackTesting[1] = ($ProfitBuy[2] + $ProfitSell[2]) / $BackTesting[0];
# [2] 総利益
$BackTesting[2] = $ProfitBuy[0] + $ProfitSell[0];
# [3] 平均利益
$BackTesting[3] = $ProfitBuy[1] + $ProfitSell[1];
# [4] 総損失
$BackTesting[4] = $LossBuy[0] + $LossSell[0];
# [5] 平均損失
$BackTesting[5] = $LossBuy[1] + $LossSell[1];
# [6] プロフィットファクター
$BackTesting[6] = $BackTesting[2] / abs($BackTesting[4]);
# [7] ペイオフレシオ
$BackTesting[7] = $BackTesting[3] / abs($BackTesting[5]);
# [8] 最大ドローダウン
$BackTesting[8] = $MaximumDrawdown;
# [9] 連続した勝ち
$BackTesting[9] = $ConsecutiveCountWin;
# [10] 連続した負け
$BackTesting[10] = $ConsecutiveCountLoss;

return @BackTesting;
}

# エントリールール Entry Rule
# 引数 始値 高値 安値 終値 出来高 (\@Open, \@High, \@Low, \@Close, \@Volume)
# 戻り値 エントリーフラグ (@EntryFlag)
sub ENTRYRYLE{
my ($Open, $High, $Low, $Close, $Volume) = @_;
my @EntryFlag = ();

# フラグは固定 買い = 1 売り = -1 なし = 0
# エントリールール

return @EntryFlag;
}

# イグジットルール Exit Rule
# 引数 始値 高値 安値 終値 出来高 (\@Open, \@High, \@Low, \@Close, \@Volume)
# 戻り値 イグジットフラグ (@ExitFlag)
sub EXITRYLE{
my ($Open, $High, $Low, $Close, $Volume) = @_;
my @ExitFlag = ();

# フラグは固定 買い = 1 売り = -1 なし = 0
# イグジットルール

return @ExitFlag
}

# 合計 平均 Sum Average
# 引数 値 (\@Value)
# 戻り値 合計 平均 取引回数 (@SumAverage)
sub SUMAVERAGE{
my ($Value) = @_;
my @SumAverage = ();
my $Sum = 0;
my $Count = @$Value - 1;

for(my $i = $Count; $i >= 0; $i--){
$Sum += $$Value[$i];
}

# [0] 合計
$SumAverage[0] = $Sum;
# [1] 平均
$SumAverage[1] = ($Count >= 0 ? ($Sum / ($Count + 1)) : 0);
# [2] 取引回数
$SumAverage[2] = ($Count >= 0 ? ($Count + 1) : 0);

return @SumAverage;
}


例 SMA(5) と SMA(25) のゴールデンクロスとデッドクロス
http://blog-imgs-36.fc2.com/a/m/a/amamiyaprog/BackTesting1.txt

一言
指値・逆指値・トレール注文等の機能をつけたい
動作の確認が出来たら他の言語でつくり直す
オンライン コンパイラ/インタプリタ
テクニカル分析
プロフィール

Author:雨宮
Firefoxを使用しているので気づかなかったけど、IE6でソースコードを上手くコピーできない

5/3
携帯用ならIE6でもソースコードをコピーできる
携帯用

検索フォーム


あわせて読みたいブログパーツ
一寸先は闇 RSS

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。