做空恐慌指數Python回測

1.VIX歷史走勢

import pandas as pd
import numpy as np

vixy_df = pd.read_csv('stock/VIXY.csv')
vix_df = pd.read_csv('stock/VIX.csv')

vix_df = vix_df.set_index('Date',False)
vix_df= vix_df[1:]
vix_df

import matplotlib.pyplot as plt
plt.figure(figsize=(15,8)) #創建繪圖對象
plt.plot(pd.to_datetime(vix_df['Date']),vix_df['Adj Close'],"b",linewidth=1)   #在當前繪圖對象繪圖(X軸,Y軸,藍色,線寬度)
# plt.plot(x,hs_profit_list,"r",linewidth=1)
plt.xlabel("Date") #X軸標籤
plt.ylabel("Price")  #Y軸標籤
plt.title("VIX") #圖標題
plt.axhline(22, color="red", linestyle="--")
plt.axhline(35, color="red", linestyle="--")
plt.axhline(13, color="green", linestyle="--")
plt.show()  #顯示圖

在這裏插入圖片描述
去雅虎financial 上下載VIX和VIXY的歷史數據到stock目錄下。
可以看到2011年後,VIX最高有漲到45多,35以上的也有4次,中等高度也有漲到超過22。低點的話13左右。

2. 簡單條件當VIX 高於X的時候進行做空VIXY,低於Y的時候,平倉VIXY

VIX本身只有期貨,所以我們來回測基於VIX的ETF,VIXY

import datetime
def MaxDrawdown(return_list):
    '''最大回撤率'''
    i = np.argmax((np.maximum.accumulate(return_list) - return_list) / np.maximum.accumulate(return_list))  # 結束位置
    if i == 0:
        return 0
    j = np.argmax(return_list[:i])  # 開始位置
    return (return_list[j] - return_list[i]) / (return_list[j])

all_date = list(vix_df.index.values)[1:]
def get_profit(short_vix_price=22.42, cover_vix_price=13.58, log=False):

    
#     percent_day_count = 12
#     is_high_average_day_count = 15
    is_short = False
#     start_hb_date = datetime.datetime.strptime(start_date, "%Y-%m-%d")
    profit = 1
    log_profit = 1
    win_profit = []
    loss_profit = []
    profit_list = []
    profit_date = []
    for date in all_date:
        date_index = list(vix_df.index.values).index(date)
        current_vix_price = vix_df['Adj Close'][date_index]
        is_high = current_vix_price >= short_vix_price
        if is_high and is_short is False:
            current_date_time = datetime.datetime.strptime(str(date)[0:10], "%Y-%m-%d")
#             day_count = (current_date_time - start_hb_date).days
            #算上空倉的貨幣基金收益
#             profit *= 1 + ((day_count / 365) * hb_percent)
            is_short = True
            short_price = vixy_df['Adj Close'][date_index]
            if log:
                print("short " + " date:" + str(date) + " price:" + str(short_price) + " vix:" + str(short_vix_price))
                
        if is_short and log:
            log_profit = log_profit * (( vixy_df['Adj Close'][date_index - 1] - vixy_df['Adj Close'][date_index]) / vixy_df['Adj Close'][date_index - 1] + 1)
        
        if is_short is True and current_vix_price <= cover_vix_price:
            is_short = False
#             start_hb_date = datetime.datetime.strptime(str(date)[0:10], "%Y-%m-%d")
            buy_price = vixy_df['Adj Close'][date_index]
            current_profit = (short_price - buy_price) /  short_price + 1
            profit *= current_profit
            #算上買賣成本
            profit *= 0.9985
            log_profit = profit
            if current_profit >=1:
                win_profit.append(current_profit - 1)
            else:
                loss_profit.append(current_profit - 1)
            if log:
                print("cover:VIXY "  + " date:" + str(date) + " price:" + str(buy_price) + " profit:" + str(profit))
        profit_list.append(log_profit)
        profit_date.append(date)


    if log:
        print('淨值:' + str(profit))
        print('盈利次數:' + str(len(win_profit)))
        print('虧損次數:' + str(len(loss_profit)))
        winPercent = len(win_profit) /  float(len(win_profit) + len(loss_profit))
        print('勝率:' + str( winPercent) ) 
        averangeWinPercent = np.sum(win_profit) /  float(len(win_profit))
        print('平均每次盈利:' + str(averangeWinPercent ) ) 
        averageLossPerent = np.sum(loss_profit) /  float(len(loss_profit))
        print('平均每次虧損:' + str(averageLossPerent ) ) 
        kali = winPercent - (1 - winPercent) / (averangeWinPercent / abs(averageLossPerent));
        print('盈虧比:' + str(abs(averangeWinPercent / averageLossPerent)))
        print('凱利最佳倉位:' + str(kali))
        max_down = MaxDrawdown(profit_list)
        print('最大回撤:' + str(max_down))
    return profit, profit_list, profit_date

3.當VIX35做空VIXY,13平倉淨值走勢

x = profit_date
y = profit_list
plt.figure(figsize=(15,8)) #創建繪圖對象
plt.plot(pd.to_datetime(x),y,"b",linewidth=1)   #在當前繪圖對象繪圖(X軸,Y軸,藍色,線寬度)
# plt.plot(x,hs_profit_list,"r",linewidth=1)
plt.xlabel("Date") #X軸標籤
plt.ylabel("Profit")  #Y軸標籤
plt.title("Short VIXY") #圖標題
plt.show()  #顯示圖

在這裏插入圖片描述
淨值:4.6848805430308555
盈利次數:4
虧損次數:0
勝率:1.0
平均每次盈利:0.49078186646488375
平均每次虧損:nan
盈虧比:nan
凱利最佳倉位:nan
最大回撤:0.6017801172984159

效果並不明顯。

4.當VIX22做空VIXY,13平倉淨值走勢

在這裏插入圖片描述
淨值:7.786198365812795
盈利次數:7
虧損次數:0
勝率:1.0
平均每次盈利:0.3573116363119387
平均每次虧損:nan
盈虧比:nan
凱利最佳倉位:nan
最大回撤:0.717993653963472

5.暴利窮舉2011年來歷史較大值 13.8, 12.8

在這裏插入圖片描述
淨值:67.17964069219849
盈利次數:47
虧損次數:1
勝率:0.9791666666666666
平均每次盈利:0.10550110265455798
平均每次虧損:-0.20406508130081302
盈虧比:0.5169973323316323
凱利最佳倉位:0.9388698758894762
最大回撤:0.7179936539634723

6. 總結做空VIXY的策略

1.雖然理論上可以取得100%勝率,但是最大回撤驚人,所以不算是好策略。100%勝率的策略越要小心
2.做空的風險太高:1.證券商可以提早平倉不通知。2.做空還有利息沒有算進去,最高20%也不是沒有可能。3.證券商會提高保證金 4. 做空倉位上漲比做多股票會快速吞噬可用資金,可用計算下 5.做空的最大虧損有可能會超過100%
3.金融危機VIX最高有上漲到80,預計VIXY這種可能會上漲超過8倍

以上僅供學習,不要作爲投資依據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章