考え方とコード
先日ブログにメモとして残したロジック(OS_OF_ver4)に対して,下記変更を加えた.
- 売買判定条件にRSIを加え,高値掴みを避ける.
- トレンド判定やナンピン判定,損切判定のスレッシュを,直近の最大レートに対する割合で設定
- ナンピン条件を見直し(一定レート差で注文するように)
# 長期トレンドに従いつつ,8時間足には逆らうヤーツ.一応,USD,EUR,GBP,AUD,NZD,CADすべてで,2002~2020年トータルで黒字.
# 統一ラベル化
# 210101 改修中. 注文時の通貨量を,口座残高に応じて決める.具体的には,残高×1/(10×5回×Nペア分)とする.
# 210106 改修中. ナンピンロジックを変更(終値とポジション平均レートの差がdV→終値と端っこのポジションレートの差がdV).
def OS_OF_ver6(InputData_DF, jNow,Posi_pre,Vp_pre, Balance,Npair,Amount): #jNowは,売買判断に使う最新足の位置を決定.何もなきゃ0.ひとつ前の足なら1
N_RSI=6 #RSIのスレッシュ判定に用いる足の本数
Settle = 0
Order = 0
#パラメータ初期化
N_Data = len(InputData_DF) - jNow
Vc_Y = np.zeros((N_Data, 1))
delta_LS2_L_Y = np.zeros((N_Data, 1))
LS2_L_Y = np.zeros((N_Data, 1))
RSI_Y= np.zeros((N_Data, 1))
#パラメータ代入
for jj in range(N_Data-1):
Vc_Y[jj] = InputData_DF.at[jNow+jj, "Vc"]
delta_LS2_L_Y[jj] = InputData_DF.at[jNow+jj, "LS2_120"] - InputData_DF.at[jNow+jj+1, "LS2_120"]
LS2_L_Y[jj] = InputData_DF.at[jNow+jj, "LS2_120"]
RSI_Y[jj] = InputData_DF.at[jNow + jj, "RSI"]
#スレッシュ定義
Thre_LS2_L = max(Vc_Y[0:N_Data-1])*0.00037 #0.0003~5
MaxNamPin=5 #各通貨ペアの,新規注文上限.例えば,買い注文は,初回+MaxNamPin-1回分,ナンピン買い出来る
Loss = max(Vc_Y[0:N_Data-1])*0.025 # 損切ラインをどう設定するかね.直近の終値最高値×0.02~0.03あたり.
dV_GRD = max(Vc_Y[0:N_Data - 1]) * 0.01 # USDで1円設定がロバストだった
dV_NamPin = max(Vc_Y[0:N_Data - 1]) * 0.0015 # For ver6. 0.001~0.003?
Trend0_L = 0
if delta_LS2_L_Y[0] > Thre_LS2_L:
Trend0_L = 1
if delta_LS2_L_Y[0] < -Thre_LS2_L:
Trend0_L = -1
# 実際は回数ではなくて,ポジション量で上限を切る.
MaxAmount = (MaxNamPin - 1) * Amount
# 買い注文ロジック
if Posi_pre <=0 :
if Trend0_L==1 and Vc_Y[0]-Vc_Y[1]<0 and Vc_Y[0]-LS2_L_Y[0]<dV_GRD and min(RSI_Y[0:N_RSI])<55:
Order = Amount
elif Posi_pre <=MaxAmount:
#if Vc_Y[0]<Vp_pre-dV_NamPin:
if Vc_Y[0] < Vp_pre - dV_NamPin/2*(Amount+abs(Posi_pre))/Amount:
Order = Amount
# 売り注文ロジック
if Posi_pre >= 0:
if Trend0_L==-1 and Vc_Y[0]-Vc_Y[1]>0 and Vc_Y[0]-LS2_L_Y[0]>-dV_GRD and max(RSI_Y[0:N_RSI])>45:
Order = -Amount
elif Posi_pre >= -MaxAmount:
#if Vc_Y[0] > Vp_pre+dV_NamPin:
if Vc_Y[0] > Vp_pre + dV_NamPin/2*(Amount+abs(Posi_pre))/Amount:
Order = -Amount
# 買い玉を売り決済するロジック
if Posi_pre > 0:
if Trend0_L==-1:
Settle=-1
if Vc_Y[0]-Vp_pre<-Loss:#損切り
Settle=-1
# 売り玉を買い決済するロジック
if Posi_pre < 0:
if Trend0_L==1:
Settle = 1
if Vc_Y[0]-Vp_pre>Loss:#損切り
Settle=1
PosiMax = CalPosiMax_ver1(Balance)
Amount_new = round(PosiMax / (Npair * MaxNamPin))
# 決済する際,それが損となるとき
if (Settle == -1 and Vc_Y[0] < Vp_pre - 0.3) or (Settle == 1 and Vc_Y[0] > Vp_pre + 0.3):
#ここで,Amountを更新
Amount = max(Amount_new, Amount)
Amount=1000 #ここで固定すれば,一応注文量は常に固定となる
return (Amount,Settle, Order) # 決済は±1か0で出力,新規注文は±通貨量かoで出力
バックテスト
2005~2020年のデータを使い,バックテストをしてみた.初回口座残高は50,000円,取引通貨量は1,000,スプレッドは0.03円(3銭)としてみた.通貨ペアはクロス円でUSD,CAD,EUR,GBP,AUD,NZDの6通りとし,すべて同じ定数設定で計算した.…損失が膨らむ年もあるけど,おおむね右肩上がりで収益を積み上げている.少なくとも大損はしないかな…思ったより悪くない…のか??
…正直このロジックが良いのかダメなのかわからない.とりあえず,同じ定数設定で長期的に損しないなら,まあいいかくらい.欲を言えば,損する年がないように改良したい.
…パフォーマンスが良いかの問題だが,例えば,ウォーレン・バフェット氏が率いるバークシャー社で,確か1年あたり20%のリターンを継続しているのが”驚異的”とのこと.福利がなければ,5年で2倍,15年で4倍か…上記バックテストに当てはめると,5万円を15年で20万円にできればバークシャー相当ということ…と考えると,バックテストの成績としては意外と悪くないのかもしれない.
…まあ,しょせんバックテストだから,こんなパフォーマンスを出せるとは思っちゃいけないのよ.きっと.
<USD_JPY>

<CAD_JPY>

<EUR_JPY>

<GBP_JPY>

<AUD_JPY>

<NZD_JPY>




コメント