長期トレンドに従い短期足に逆らう by 8時間足・改

考え方とコード

先日ブログにメモとして残したロジック(OS_OF_ver4)に対して,下記変更を加えた.

  1. 売買判定条件にRSIを加え,高値掴みを避ける.
  2. トレンド判定やナンピン判定,損切判定のスレッシュを,直近の最大レートに対する割合で設定
  3. ナンピン条件を見直し(一定レート差で注文するように)
# 長期トレンドに従いつつ,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>

コメント

タイトルとURLをコピーしました