日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
用 Python 實(shí)現(xiàn)隨機(jī)相對(duì)強(qiáng)弱指數(shù) StochRSI

 Python中文社區(qū)(ID:python-china)

創(chuàng)新互聯(lián)建站自2013年創(chuàng)立以來(lái),先為開州等服務(wù)建站,開州等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為開州企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

隨機(jī)相對(duì)強(qiáng)弱指數(shù)簡(jiǎn)稱為StochRSI,是一種技術(shù)分析指標(biāo),用于確定資產(chǎn)是否處于超買或超賣狀態(tài),也用于確定當(dāng)前市場(chǎng)的態(tài)勢(shì)。顧名思義,StochRSI是標(biāo)準(zhǔn)相對(duì)強(qiáng)弱指數(shù)(RSI)的衍生,因此被視為是一種能夠衡量指數(shù)的指數(shù)。它是一種振蕩器,在中心線的上方和下方波動(dòng)。

StochRSI最初是在1994年由Stanley Kroll和Tushar Chande撰寫的題為《The NewTechnical Trader》的書中描述。它經(jīng)常被股票交易者使用。

StochRSI如何運(yùn)作?

通過應(yīng)用隨機(jī)振蕩器生成公式,從標(biāo)準(zhǔn)RSI生成StochRSI。其生成結(jié)果是單個(gè)數(shù)字評(píng)級(jí),圍繞中心線(0.5)在0-1的值域范圍內(nèi)上下擺動(dòng)。但是,StochRSI的修改版本將結(jié)果乘以100,因此該值是介于0和100之間而不是0和1之間。通常還會(huì)參考3天內(nèi)的簡(jiǎn)單移動(dòng)平均線(SMA)以及StochRSI趨勢(shì),作為信號(hào)線,旨在降低虛假信號(hào)交易的風(fēng)險(xiǎn)。

標(biāo)準(zhǔn)隨機(jī)震蕩指數(shù)公式取決于資產(chǎn)的收盤價(jià)以及設(shè)定周期內(nèi)的最高價(jià)和最低價(jià)。但是,當(dāng)使用公式計(jì)算StochRSI時(shí),它直接使用RSI數(shù)據(jù)(不考慮價(jià)格)。

Stoch RSI = (Current RSI - Lowest RSI)/(Highest RSI - Lowest RSI)

與標(biāo)準(zhǔn)RSI一樣,StochRSI使用的最常見時(shí)間周期為14。StochRSI計(jì)算中涉及的14個(gè)周期基于圖表時(shí)間范圍。因此,每日?qǐng)D表會(huì)顯示過去14天(K線圖),每小時(shí)圖表會(huì)顯示過去14小時(shí)生成的StochRSI。

周期可以設(shè)置為幾天、幾小時(shí)甚至幾分鐘,并且它們的使用方式也因交易者而異(根據(jù)他們的情況和策略而定)。還可以向上或向下調(diào)整周期數(shù),以確定長(zhǎng)期或短期趨勢(shì)。將周期值設(shè)置為20,是StochRSI指標(biāo)一個(gè)相當(dāng)受歡迎的選擇。

如上所述,某些StochRSI圖表模式指定的范圍值為0到100而不是0到1。在這些圖表中,中心線為50而不是0.5。因此,通常在0.8處出現(xiàn)的超買信號(hào)將表示為80,而超賣信號(hào)表示為20而不是0.2。具有0-100設(shè)置的圖表可能看起來(lái)略有不同,但實(shí)際原理解釋是基本相同的。

如何使用StochRSI?

StochRSI指數(shù)如果出現(xiàn)在其范圍的上限和下限附近,此時(shí)的意義是最重大的。因此,該指標(biāo)的主要用途是確定潛在的買入和賣出點(diǎn),以及價(jià)格發(fā)生的逆轉(zhuǎn)。因此,0.2或以下的數(shù)值,會(huì)表明資產(chǎn)可能發(fā)生超賣,而0.8或以上的數(shù)值則表明該資產(chǎn)可能會(huì)發(fā)生超買。

此外,更接近中心線的數(shù)值也可以為交易者提供有關(guān)市場(chǎng)趨勢(shì)的信息。例如,當(dāng)中心線作為支撐線并且StochRSI線穩(wěn)定移動(dòng)到0.5以上時(shí),尤其是數(shù)值趨近于0.8,則可能表明其繼續(xù)看漲或呈上升趨勢(shì)。同樣,當(dāng)數(shù)值始終低于0.5,趨近于0.2時(shí),則表明下跌或呈下降趨勢(shì)趨勢(shì)。

我們將通過 Python 中的回測(cè)來(lái)介紹 RSI 和 StochRSI 這兩種方法。

基于均值回歸的StochRSI 策略

最常見的 StochRSI 策略基于均值回歸。與 RSI 一樣,StochRSI 通常使用 80 來(lái)表示做空的超買水平,使用 20 來(lái)表示要買入的超賣水平。此外,14 天的回顧和平滑期很常見。出于我們的目的,我們將堅(jiān)持使用這些標(biāo)準(zhǔn)值。

現(xiàn)在編寫代碼,讓我們?cè)?Python 中導(dǎo)入一些標(biāo)準(zhǔn)包。

 
 
 
 
  1. import numpy as np  
  2. import pandas as pd  
  3. import matplotlib.pyplot as plt  
  4. import yfinance as yf 

接下來(lái),我們將構(gòu)建一個(gè)函數(shù)來(lái)計(jì)算我們的指標(biāo)。我們將其稱為 calcStochRSI(),它將依靠一些函數(shù)來(lái)計(jì)算 RSI 和隨機(jī)振蕩器,以獲得我們選擇的指標(biāo)。

 
 
 
 
  1. def calcRSI(data, P=14):  
  2.   # Calculate gains and losses  
  3.   data['diff_close'] = data['Close'] - data['Close'].shift(1)  
  4.   data['gain'] = np.where(data['diff_close']>0,  
  5.     data['diff_close'], 0)  
  6.   data['loss'] = np.where(data['diff_close']<0,   
  7.     np.abs(data['diff_close']), 0)  
  8.   # Get initial values  
  9.   data[['init_avg_gain', 'init_avg_loss']] = data[  
  10.     ['gain', 'loss']].rolling(P)   
  11.   # Calculate smoothed avg gains and losses for all t > P  
  12.   avg_gain = np.zeros(len(data))  
  13.   avg_loss = np.zeros(len(data)) 
  14.   for i, _row in enumerate(data.iterrows()):  
  15.     row = _row[1]  
  16.     if i < P - 1:  
  17.       last_row = row.copy()  
  18.       continue  
  19.     elif i == P-1:  
  20.       avg_gain[i] += row['init_avg_gain']  
  21.       avg_loss[i] += row['init_avg_loss']  
  22.     else:  
  23.       avg_gain[i] += ((P - 1) * avg_gain[i] +  
  24.             row['gain']) / P  
  25.       avg_loss[i] += ((P - 1) * avg_loss[i] +  
  26.             row['loss']) / P          
  27.     last_row = row.copy()  
  28.   data['avg_gain'] = avg_gain  
  29.   data['avg_loss'] = avg_loss  
  30.   # Calculate RS and RSI  
  31.   data['RS'] = data['avg_gain'] / data['avg_loss']  
  32.   data['RSI'] = 100 - 100 / (1 + data['RS'])  
  33.   return data  
  34. def calcStochOscillator(data):  
  35.   data['low_N'] = data['RSI'].rolling(N).min()  
  36.   data['high_N'] = data['RSI'].rolling(N).max()  
  37.   data['StochRSI'] = 100 * (data['RSI'] - data['low_N']) / \  
  38.     (data['high_N'] - data['low_N'])  
  39.   return data  
  40. def calcStochRSI(data, P=14, N=14):  
  41.   data = calcRSI(data)  
  42.   data = calcStochOscillator(data)  
  43.   return data  
  44. def calcReturns(df):  
  45.   # Helper function to avoid repeating too much code  
  46.   df['returns'] = df['Close'] / df['Close'].shift(1)  
  47.   df['log_returns'] = np.log(df['returns'])  
  48.   df['strat_returns'] = df['position'].shift(1) * df['returns']  
  49.   df['strat_log_returns'] = df['position'].shift(1) * df['log_returns']  
  50.   df['cum_returns'] = np.exp(df['log_returns'].cumsum()) - 1  
  51.   df['strat_cum_returns'] = np.exp(df['strat_log_returns'].cumsum()) - 1  
  52.   df['peak'] = df['cum_returns'].cummax()  
  53.   df['strat_peak'] = df['strat_cum_returns'].cummax()  
  54.   return df 

有了這些功能,我們只需要為我們的策略構(gòu)建邏輯就可以了。還要注意,我們有一個(gè)名為 calcReturns 的輔助函數(shù),我們可以快速將其應(yīng)用于回測(cè)的結(jié)果以從中獲取所有返回值。

這意味著回歸模型將在 StochRSI 高于 80 時(shí)做空或賣出,并在低于 20 時(shí)買入。

 
 
 
 
  1. def StochRSIReversionStrategy(data, P=14, N=14, short_level=80,   
  2.   buy_level=20, shorts=True):  
  3.   '''Buys when the StochRSI is oversold and sells when it's overbought'''  
  4.   df = calcStochRSI(data, P, N)  
  5.   df['position'] = np  
  6.   df['position'] = np.where(df['StochRSI']
  7.   if shorts:  
  8.     df['position'] = np.where(df['StochRSI']>short_level, -1, df['position'])  
  9.   else:  
  10.     df['position'] = np.where(df['StochRSI']>short_level, 0, df['position'])  
  11.   df['position'] = df['position'].ffill()  
  12.   return calcReturns(df)  
  13. table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')  
  14. df = table[0]  
  15. syms = df['Symbol']  
  16. # Sample symbols  
  17. # ticker = np.random.choice(syms.values)  
  18. ticker = "BSX"  
  19. print(f"Ticker Symbol: {ticker}")  
  20. start = '2000-01-01'  
  21. end = '2020-12-31'  
  22. # Get Data  
  23. yfyfObj = yf.Ticker(ticker)  
  24. data = yfObj.history(startstart=start, endend=end)  
  25. data.drop(['Open', 'High', 'Low', 'Volume', 'Dividends',   
  26.     'Stock Splits'], inplace=True, axis=1)  
  27. # Run test  
  28. df_rev = StochRSIReversionStrategy(data.copy())  
  29. # Plot results  
  30. colors = plt.rcParams['axes.prop_cycle'].by_key()['color']  
  31. fig, ax = plt.subplots(2, figsize=(12, 8))  
  32. ax[0].plot(df_rev['strat_cum_returns']*100, label='Mean Reversion')  
  33. ax[0].plot(df_rev['cum_returns']*100, label='Buy and Hold')  
  34. ax[0].set_ylabel('Returns (%)')  
  35. ax[0].set_title('Cumulative Returns for Mean Reversion and' +  
  36.                 f' Buy and Hold Strategies for {ticker}')  
  37. ax[0].legend(bbox_to_anchor=[1, 0.6])  
  38. ax[1].plot(df_rev['StochRSI'], label='StochRSI', linewidth=0.5)  
  39. ax[1].plot(df_rev['RSI'], label='RSI', linewidth=1)  
  40. ax[1].axhline(80, label='Over Bought', color=colors[1], linestyle=':')  
  41. ax[1].axhline(20, label='Over Sold', color=colors[2], linestyle=':')  
  42. ax[1].axhline(50, label='Centerline', color='k', linestyle=':')  
  43. ax[1].set_ylabel('Stochastic RSI')  
  44. ax[1].set_xlabel('Date')  
  45. ax[1].set_title(f'Stochastic RSI for {ticker}')  
  46. ax[1].legend(bbox_to_anchor=[1, 0.75])  
  47. plt.tight_layout()  
  48. plt.show() 

在我們研究的 21 年期間,均值回歸策略擊敗了Boston Scientific(BSX)的買入和持有策略,回報(bào)率為 28 倍,而后者為 2 倍。

在第二個(gè)圖中顯示了 StochRSI 和一些關(guān)鍵指標(biāo)。我還添加了 RSI 以與更不穩(wěn)定的 StochRSI 進(jìn)行比較。這導(dǎo)致交易頻繁,如果您的賬戶較小且交易成本相對(duì)較高,這可能會(huì)嚴(yán)重影響您的實(shí)際回報(bào)。我們只是在一個(gè)工具上運(yùn)行它,所以最終進(jìn)行了 443 筆交易,或者每 12 天交易一次,這看起來(lái)并不多。但是,如果我們要使用該指標(biāo)管理適當(dāng)?shù)墓ぞ呓M合并頻繁進(jìn)行交易,我們每天可能會(huì)進(jìn)出多筆交易,交易成本會(huì)變得很高。

 
 
 
 
  1. # Get trades  
  2. diff = df_rev['position'].diff().dropna()  
  3. trade_idx = diff.index[np.where(diff!=0)]  
  4. fig, ax = plt.subplots(figsize=(12, 8))  
  5. ax.plot(df_rev['Close'], linewidth=1, label=f'{ticker}')  
  6. ax.scatter(trade_idx, df_rev[trade_idx]['Close'], c=colors[1],   
  7.            marker='^', label='Trade')  
  8. ax.set_ylabel('Price')  
  9. ax.set_title(f'{ticker} Price Chart and Trades for' +  
  10.              'StochRSI Mean Reversion Strategy')  
  11. ax.legend()  
  12. plt.show() 

要查看整體策略的一些關(guān)鍵指標(biāo),讓我們看看使用以下 getStratStats 函數(shù)。

 
 
 
 
  1. def getStratStats(log_returns: pd.Series, risk_free_rate: float = 0.02):  
  2.   stats = {}  
  3.   # Total Returns  
  4.   stats['tot_returns'] = np.exp(log_returns.sum()) - 1  
  5.   # Mean Annual Returns  
  6.   stats['annual_returns'] = np.exp(log_returns.mean() * 252) - 1  
  7.   # Annual Volatility  
  8.   stats['annual_volatility'] = log_returns * np.sqrt(252)  
  9.   # Sortino Ratio  
  10.   annualized_downside = log_returns.loc[log_returns<0].std() * np.sqrt(252)  
  11.   stats['sortino_ratio'] = (stats['annual_returns'] - risk_free_rate) \  
  12.     / annualized_downside  
  13.   # Sharpe Ratio  
  14.   stats['sharpe_ratio'] = (stats['annual_returns'] - risk_free_rate) \  
  15.     / stats['annual_volatility']  
  16.   # Max Drawdown  
  17.   cum_returns = log_returns.cumsum() - 1  
  18.   peak = cum_returns.cummax()  
  19.   drawdown = peak - cum_returns  
  20.   stats['max_drawdown'] = drawdown.max()  
  21.   # Max Drawdown Duration  
  22.   strat_dd = drawdown[drawdown==0]  
  23.   strat_ddstrat_dd_diff = strat_dd.index[1:] - strat_dd.index[:-1]  
  24.   strat_dd_days = strat_dd_diff.map(lambda x: x.days)  
  25.   strat_dd_days = np.hstack([strat_dd_days,   
  26.       (drawdown.index[-1] - strat_dd.index[-1]).days])  
  27.   stats['max_drawdown_duration'] = strat_dd_days.max()  
  28.   return stats  
  29. rev_stats = getStratStats(df_rev['strat_log_returns'])  
  30. bh_stats = getStratStats(df_rev['log_returns'])  
  31. pd.concat([pd.DataFrame(rev_stats, index=['Mean Reversion']),  
  32.            pd.DataFrame(bh_stats, index=['Buy and Hold'])]) 

在這里,我們看到該策略的回報(bào)率為 28 倍,而基礎(chǔ)資產(chǎn)的年度波動(dòng)率大致相同。此外,根據(jù) Sortino 和 Sharpe Ratios 衡量,我們有更好的風(fēng)險(xiǎn)調(diào)整回報(bào)。

在 2020 年的新冠疫情中,我們確實(shí)看到了均值回歸策略的潛在問題之一。該策略的總回報(bào)大幅下降,因?yàn)樵摬呗缘亩ㄎ皇窍蛏匣貧w,但市場(chǎng)繼續(xù)低迷,該模型只是保持不變 . 它恢復(fù)了其中的一部分,但在這次測(cè)試中從未達(dá)到過疫情之前的高點(diǎn)。正確使用止損有助于限制這些巨大的損失,并有可能增加整體回報(bào)。

StochRSI 和動(dòng)量策略

我們之前提到的另一個(gè)基本策略是使用 StochRSI 作為動(dòng)量指標(biāo)。當(dāng)指標(biāo)穿過中心線時(shí),我們會(huì)根據(jù)其方向買入或做空股票。

 
 
 
 
  1. def StochRSIMomentumStrategy(data, P=14, N=14,  
  2.   centerline=50, shorts=True):  
  3.   '''  
  4.   Buys when the StochRSI moves above the centerline,   
  5.   sells when it moves below  
  6.   '''  
  7.   df = calcStochRSI(data, P) 
  8.   df['position'] = np.nan  
  9.   df['position'] = np.where(df['StochRSI']>50, 1, df['position'])  
  10.   if shorts: 
  11.      df['position'] = np.where(df['StochRSI']<50, -1, df['position'])  
  12.   else:  
  13.     df['position'] = np.where(df['StochRSI']<50, 0, df['position'])  
  14.   df['position'] = df['position'].ffill()  
  15.   return calcReturns(df) 

運(yùn)行我們的回測(cè):

 
 
 
 
  1. # Run test  
  2. df_mom = StochRSIMomentumStrategy(data.copy())  
  3. # Plot results  
  4. colors = plt.rcParams['axes.prop_cycle'].by_key()['color']  
  5. fig, ax = plt.subplots(2, figsize=(12, 8))  
  6. ax[0].plot(df_mom['strat_cum_returns']*100, label='Momentum')  
  7. ax[0].plot(df_mom['cum_returns']*100, label='Buy and Hold')  
  8. ax[0].set_ylabel('Returns (%)')  
  9. ax[0].set_title('Cumulative Returns for Momentum and' +  
  10.                 f' Buy and Hold Strategies for {ticker}')  
  11. ax[0].legend(bbox_to_anchor=[1, 0.6])  
  12. ax[1].plot(df_mom['StochRSI'], label='StochRSI', linewidth=0.5)  
  13. ax[1].plot(df_mom['RSI'], label='RSI', linewidth=1)  
  14. ax[1].axhline(50, label='Centerline', color='k', linestyle=':')  
  15. ax[1].set_ylabel('Stochastic RSI')  
  16. ax[1].set_xlabel('Date')  
  17. ax[1].set_title(f'Stochastic RSI for {ticker}')  
  18. ax[1].legend(bbox_to_anchor=[1, 0.75])  
  19. plt.tight_layout()  
  20. plt.show() 

在這種情況下,我們的動(dòng)量策略表現(xiàn)非常糟糕,在我們假設(shè)的時(shí)間段內(nèi)幾乎損失了我們所有的初始投資。

查看我們策略的統(tǒng)計(jì)數(shù)據(jù),該模型的唯一優(yōu)勢(shì)是比買入并持有方法的回撤時(shí)間略短。

 
 
 
 
  1. mom_stats = getStratStats(df_mom['strat_log_returns'])  
  2. bh_stats = getStratStats(df_mom['log_returns'])  
  3. pd.concat([pd.DataFrame(mom_stats, index=['Momentum']),  
  4.            pd.DataFrame(rev_stats, index=['Mean Reversion']),  
  5.            pd.DataFrame(bh_stats, index=['Buy and Hold'])]) 

這并不意味著StochRSI 不適合此類應(yīng)用。一次糟糕的回測(cè)并不意味著該策略毫無(wú)價(jià)值。相反,一個(gè)很好的回測(cè)并不意味著你有一些你應(yīng)該立即開始交易的東西。我們需要與其他指標(biāo)結(jié)合使用以改善結(jié)果。


文章標(biāo)題:用 Python 實(shí)現(xiàn)隨機(jī)相對(duì)強(qiáng)弱指數(shù) StochRSI
URL地址:http://www.5511xx.com/article/cdsechi.html