關(guān)于本站
人大經(jīng)濟(jì)論壇-經(jīng)管之家:分享大學(xué)、考研、論文、會(huì)計(jì)、留學(xué)、數(shù)據(jù)、經(jīng)濟(jì)學(xué)、金融學(xué)、管理學(xué)、統(tǒng)計(jì)學(xué)、博弈論、統(tǒng)計(jì)年鑒、行業(yè)分析包括等相關(guān)資源。
經(jīng)管之家是國內(nèi)活躍的在線教育咨詢平臺(tái)!
經(jīng)管之家新媒體交易平臺(tái)
提供"微信號(hào)、微博、抖音、快手、頭條、小紅書、百家號(hào)、企鵝號(hào)、UC號(hào)、一點(diǎn)資訊"等虛擬賬號(hào)交易,真正實(shí)現(xiàn)買賣雙方的共贏!菊(qǐng)點(diǎn)擊這里訪問】
TOP熱門關(guān)鍵詞
專題頁面精選
- 經(jīng)濟(jì)學(xué) 管理學(xué) 金融學(xué) 統(tǒng)計(jì)學(xué)
- 會(huì)計(jì)學(xué) 財(cái)政學(xué) 國際貿(mào)易 財(cái)務(wù)管理
- 工商管理學(xué) 人力資源管理 風(fēng)險(xiǎn)管理
- 成本會(huì)計(jì)學(xué) 財(cái)務(wù)會(huì)計(jì) 酒店管理
- 市場(chǎng)營(yíng)銷學(xué) 審計(jì)學(xué) 保險(xiǎn)學(xué)
- 國際金融學(xué) 企業(yè)管理學(xué) 保險(xiǎn)精算
- 精算學(xué) 心理學(xué) 哲學(xué)
掃碼加入金融交流群 |
股票市場(chǎng)周期是股票市場(chǎng)長(zhǎng)期的價(jià)格模式,通常與商業(yè)周期有關(guān)。 它是技術(shù)分析的關(guān)鍵,其中投資方法基于周期或重復(fù)的價(jià)格模式。 如果我們對(duì)股市周期有了更好的理解,我們總能以相對(duì)低的價(jià)格買入并在每個(gè)周期以相對(duì)較高的價(jià)格賣出,將始終獲得正的回報(bào)。當(dāng)然,股票市場(chǎng)沒有什么策略可以永遠(yuǎn)賺錢,但我們基于Python,可以幫助我們更深入、快速地了解隱藏在股市中的周期。
fbprophet簡(jiǎn)介
Fbprophet是Facebook發(fā)布的一個(gè)開源軟件,旨在為大規(guī)模預(yù)測(cè)提供一些有用的指導(dǎo)。 默認(rèn)情況下,它會(huì)將時(shí)間序列劃分為趨勢(shì)和季節(jié)性,可能包含年度,周度和每日。 但是,分析師可以定義自己的季節(jié)性。 為了更好地理解該庫,先導(dǎo)文件是非常有用的。
該庫的一個(gè)特點(diǎn)是簡(jiǎn)單性、靈活性。 由于我們想要計(jì)算的股票市場(chǎng)周期不限于每年,每周或每日,我們應(yīng)該定義自己的周期,找出哪些更適合數(shù)據(jù)。 此外,由于周末沒有交易,我們不應(yīng)該使用每周季節(jié)性。 我們還可以通過addseasonality函數(shù)定義'selfdefine_cycle'。 所有設(shè)置只需兩行代碼即可完成。
- m = Prophet(weekly_seasonality=False,yearly_seasonality=False)
- m.add_seasonality('self_define_cycle',period=8,fourier_order=8,mode='additive')
以Costco為例
我們可以使用Costco標(biāo)的從2015/10/1到2018/10/1, 使用pandas_datareader,我們可以快速讀取股票價(jià)格。如下圖:
https://user-gold-cdn.xitu.io/2018/10/16/1667ac87a221358b?w=1080&h=723&f=jpeg&s=68075 地址:https://pandas-datareader.readth ... st/remote_data.html
在下圖中,我們可以看到從2015年開始有一個(gè)強(qiáng)勁的價(jià)格增長(zhǎng)趨勢(shì)。然而,在中途仍然存在很多上下周期波動(dòng),這些周期都是我們的賺錢點(diǎn)。
- ticker = "COST"
- start_date = '2015-10-01'
- end_date = '2018-10-01'
- stock_data = data.DataReader(ticker, 'iex', start_date, end_date)
- stock_data['close'].plot(figsize=(16,8),color='#002699',alpha=0.8)
- plt.xlabel("Date",fontsize=12,fontweight='bold',color='gray')
- plt.ylabel('Price',fontsize=12,fontweight='bold',color='gray')
- plt.title("Stock price for Costco",fontsize=18)
- plt.show()
https://user-gold-cdn.xitu.io/2018/10/16/1667ac9114907a29?w=956&h=503&f=jpeg&s=35509
對(duì)于預(yù)測(cè)模型,評(píng)估它們的一種方法是樣本均方誤差。 我們可以使用2015/10/1至2018/3/31進(jìn)行訓(xùn)練,并保留最后6個(gè)月的數(shù)據(jù)進(jìn)行測(cè)試和計(jì)算樣本均方誤差。 在每個(gè)周期內(nèi),我們可以通過以最低價(jià)格買入并以最高價(jià)格賣出的方式來優(yōu)化我們的回報(bào)。 為了簡(jiǎn)化過程,我們使用自定義函數(shù)cycle_analysis。 輸出是一個(gè)列表,其中包含每個(gè)周期的預(yù)計(jì)回報(bào)和樣本均方誤差。
- data:帶有時(shí)間索引的Pandas數(shù)據(jù)
- split_date:分割訓(xùn)練和測(cè)試數(shù)據(jù)的日期cycle:每個(gè)周期的間隔(天)
- cycle:每個(gè)周期的間隔(天)
- mode:季節(jié)性的加法或乘法(可選)
- forecast_plot:是否打印預(yù)測(cè)圖(可選,默認(rèn)為False)
- print_ind:是否打印每個(gè)周期的預(yù)計(jì)回報(bào)和是否采樣均方誤差(可選,默認(rèn)為False)
- def cycle_analysis(data,split_date,cycle,mode='additive',forecast_plot = False,print_ind=False):
- training = data[:split_date].iloc[:-1,]
- testing = data[split_date:]
- predict_period = len(pd.date_range(split_date,max(data.index)))
- df = training.reset_index()
- df.columns = ['ds','y']
- m = Prophet(weekly_seasonality=False,yearly_seasonality=False,daily_seasonality=False)
- m.add_seasonality('self_define_cycle',period=cycle,fourier_order=8,mode=mode)
- m.fit(df)
- future = m.make_future_dataframe(periods=predict_period)
- forecast = m.predict(future)
- if forecast_plot:
- m.plot(forecast)
- plt.plot(testing.index,testing.values,'.',color='#ff3333',alpha=0.6)
- plt.xlabel('Date',fontsize=12,fontweight='bold',color='gray')
- plt.ylabel('Price',fontsize=12,fontweight='bold',color='gray')
- plt.show()
- ret = max(forecast.self_define_cycle)-min(forecast.self_define_cycle)
- model_tb = forecast['yhat']
- model_tb.index = forecast['ds'].map(lambda x:x.strftime("%Y-%m-%d"))
- out_tb = pd.concat([testing,model_tb],axis=1)
- out_tb = out_tb[~out_tb.iloc[:,0].isnull()]
- out_tb = out_tb[~out_tb.iloc[:,1].isnull()]
- mse = mean_squared_error(out_tb.iloc[:,0],out_tb.iloc[:,1])
- rep = [ret,mse]
- if print_ind:
- print "Projected return per cycle: {}".format(round(rep[0],2))
- print "MSE: {}".format(round(rep[1],4))
- return rep
在下面兩個(gè)圖中,我們將兩種不同cycle(30和300)分別應(yīng)用于Costco股票價(jià)格,并將2018/4/1作為訓(xùn)練和測(cè)試的分割日期。 正如我們所看到的,如果我們選擇一個(gè)較短的長(zhǎng)度(例如30天),則一個(gè)周期內(nèi)的回報(bào)是很小的,我們需要經(jīng)常進(jìn)行交易,如果我們選擇較長(zhǎng)的長(zhǎng)度,它會(huì)延長(zhǎng)我們的預(yù)測(cè)(例如300天)。
https://user-gold-cdn.xitu.io/2018/10/16/1667aca3890dff1f?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
https://user-gold-cdn.xitu.io/2018/10/16/1667aca6827153af?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
我們可以在cycle_analysis函數(shù)上應(yīng)用一個(gè)循環(huán)來計(jì)算不同循環(huán)長(zhǎng)度的預(yù)計(jì)回報(bào)和樣本均方誤差,并且我們?cè)谙聢D中顯示了結(jié)果。正如我們所看到的,長(zhǎng)度越長(zhǎng),每個(gè)周期的預(yù)計(jì)回報(bào)和樣本均方誤差會(huì)增加。 考慮到交易成本,每個(gè)周期內(nèi)的預(yù)計(jì)回報(bào)應(yīng)該大于10元。 在這種約束下,我們可以選擇最小樣本均方誤差的周期,并且它是252天。 每個(gè)周期的預(yù)計(jì)回報(bào)為17.12元,樣本均方誤差為15.936。 兩者都很不錯(cuò)!
- testing_box = range(10,301)
- return_box = []
- mse_box = []
- for c in testing_box:
- f = cycle_analysis(stock_data['close'],'2018-04-01',c)
- return_box.append(f[0])
- mse_box.append(f[1])
https://user-gold-cdn.xitu.io/2018/10/16/1667acad3c109bc0?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
- report = pd.DataFrame({'cycle':testing_box,'return':return_box,'mse':mse_box})
- possible_choice = report[report['return'] >10]
- possible_choice[possible_choice['mse']==min(possible_choice['mse'])]
https://user-gold-cdn.xitu.io/2018/10/16/1667acb3cd6c5d20?w=460&h=136&f=jpeg&s=12376
- c = possible_choice[possible_choice['mse']==min(possible_choice['mse'])]['cycle'].values[0]
- ycle_analysis(stock_data['close'],'2018-04-01',c,forecast_plot=True,print_ind=True)
https://user-gold-cdn.xitu.io/2018/10/16/1667acb885c01e65?w=716&h=427&f=jpeg&s=36139
Projected return per cycle: 17.12 MSE: 15.9358 [17.120216439034987, 15.93576020351612]
為了進(jìn)一步說明投資策略,我們可以看到2015/10/1和2018/10/1之間的買入和賣出日期。 Return_Dates函數(shù)可以將所有買入和賣出日期作為輸出返回,輸入:
- forecast:fbprophet預(yù)測(cè)對(duì)象
- stock_data:帶有時(shí)間索引的Pandas數(shù)據(jù)
- cycle:周期長(zhǎng)度
- cycle_name:預(yù)測(cè)對(duì)象中循環(huán)列的名稱
- time_name:預(yù)測(cè)對(duì)象中時(shí)間列的名稱
- def Return_Dates(forecast,stock_data,cycle,cycle_name = 'self_define_cycle',time_name = 'ds'):
- # find out the highest and lowest dates in the first cycle
- # We cannot simply search for all highest and lowest point since there is slightly difference for high and low values in different cycles
- high = forecast.iloc[:cycle,]
- high = high[high[cycle_name]==max(high[cycle_name])][time_name]
- high = datetime.strptime(str(high.values[0])[:10],"%Y-%m-%d")
- low = forecast.iloc[:cycle,]
- low = low[low[cycle_name]==min(low[cycle_name])][time_name]
- low = datetime.strptime(str(low.values[0])[:10],"%Y-%m-%d")
- end_dt = datetime.strptime(stock_data.index[-1],"%Y-%m-%d")
- find_list = stock_data.index.map(lambda x:datetime.strptime(x,"%Y-%m-%d"))
- # Finding selling and buying dates with loop
- sell_dt = []
- sell_dt.append(high)
- # Looking for new cycle until it goes beyond the last date in stock_data
- while high<end_dt:
- high = high+timedelta(days=cycle)
- dif = (find_list-high).days
- high = find_list[abs(dif)==min(abs(dif))][0] # In order to avoid the non-trading dates
- sell_dt.append(high)
- buy_dt = []
- buy_dt.append(low)
- # Looking for new cycle until it goes beyond the last date in stock_data
- while low<end_dt:
- low = low+timedelta(days=cycle)
- dif = (find_list-low).days
- low = find_list[abs(dif)==min(abs(dif))][0] # In order to avoid the non-trading dates
- buy_dt.append(low)
- if buy_dt[0] > sell_dt[0]:
- sell_dt = sell_dt[1:]
- buy_dt = buy_dt[:-1]
- sell_dt = sell_dt[:-1]
- return [buy_dt,sell_dt]
在2015/10/1和2018/10/1期間,我們買賣Costco四次。3年內(nèi)的回報(bào)率為23.2%。 可能不是很吸引人,但至少它是比較樂觀的回報(bào)。
https://user-gold-cdn.xitu.io/2018/10/16/1667accbca7fb022?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
更多股票的應(yīng)用,當(dāng)然,這種方法可以應(yīng)用于盡可能多的股票。 我們列出了Costco,Apple,Microsoft,Home Depot和Nike的平均購買價(jià)格,平均銷售價(jià)格,周期長(zhǎng)度,樣本均方誤差,購買數(shù)量,銷售數(shù)量和每個(gè)周期內(nèi)的預(yù)計(jì)回報(bào)。
- Analysis_ticks = ['COST','AAPL','MSFT','HD','NKE']
- start_date = '2015-10-01'
- end_date = '2018-10-01'
- opt_cycle = []
- prot_return = []
- MSE = []
- buy_times = []
- sell_times = []
- avg_buy_price = []
- avg_sell_price = []
- # Loop over each stock
- for ticker in Analysis_ticks:
- stock_data = data.DataReader(ticker, 'iex', start_date, end_date)
- testing_box = range(50,301)
- return_box = []
- mse_box = []
- for cc in testing_box:
- f = cycle_analysis(stock_data['close'],'2018-04-01',cc)
- return_box.append(f[0])
- mse_box.append(f[1])
- report = pd.DataFrame({'cycle':testing_box,'return':return_box,'mse':mse_box})
- possible_choice = report[report['return'] >10]
- # If we cannot find a cycle with return greater than 10, give 0
- if possible_choice.shape[0]>0:
- c = possible_choice[possible_choice['mse']==min(possible_choice['mse'])]['cycle'].values[0]
- rp = possible_choice[possible_choice['mse']==min(possible_choice['mse'])]['return'].values[0]
- mse = possible_choice[possible_choice['mse']==min(possible_choice['mse'])]['mse'].values[0]
- df = stock_data[:'2018-04-01'].iloc[:-1,]['close'].reset_index()
- df.columns = ['ds','y']
- predict_period = len(pd.date_range('2018-04-01','2018-10-01'))
- m = Prophet(weekly_seasonality=False,yearly_seasonality=False,daily_seasonality=False)
- m.add_seasonality('self_define_cycle',period=c,fourier_order=8,mode='additive')
- m.fit(df)
- future = m.make_future_dataframe(periods=predict_period)
- forecast = m.predict(future)
- dt_list = Return_Dates(forecast,stock_data,c)
- buy_price = stock_data.loc[map(lambda x: x.strftime("%Y-%m-%d"),dt_list[0])]['close']
- sell_price = stock_data.loc[map(lambda x: x.strftime("%Y-%m-%d"),dt_list[1])]['close']
- bt = buy_price.shape[0]
- st = sell_price.shape[0]
- bp = np.mean(buy_price)
- sp = np.mean(sell_price)
- else:
- c = 0
- rp = 0
- mse = 0
- bt = 0
- st = 0
- bp = 0
- sp = 0
- opt_cycle.append(c)
- prot_return.append(rp)
- MSE.append(mse)
- buy_times.append(bt)
- sell_times.append(st)
- avg_buy_price.append(bp)
- avg_sell_price.append(sp)
- print "{} Finished".format(ticker)
對(duì)于微軟和耐克,我們找不到符合我們要求每個(gè)周期超過10元回報(bào)的周期。 對(duì)于Costco,Apple和Home Depot,我們可以找到大約250天的周期,并做出良好的預(yù)測(cè)和良好的回報(bào)。
- stock_report = pd.DataFrame({'Stock':Analysis_ticks,'Cycle':opt_cycle,'Projected_Return_per_Cycle':prot_return,
- 'MSE':MSE,'Num_of_Buy':buy_times,'Num_of_Sell':sell_times,
- 'Average_Buy_Price':avg_buy_price,'Average_Sell_Price':avg_sell_price})
- stock_report
https://user-gold-cdn.xitu.io/2018/10/16/1667acd6b0cad10f?w=1080&h=155&f=jpeg&s=35581
總結(jié)借助Python和fbprophet包,我們可以更好地了解股市。 根據(jù)我們發(fā)現(xiàn)的周期,我們可以在3年內(nèi)獲得大約23%的回報(bào)。 也許這種投資策略無法滿足所有人的需求,但你始終可以根據(jù)自己的知識(shí)和經(jīng)驗(yàn)設(shè)定自己的方法。 強(qiáng)大的fbprophet軟件包可以讓你對(duì)股票市場(chǎng)的分析更加深入和輕松。
延伸閱讀:
經(jīng)典的深度學(xué)習(xí)教程及Python代碼實(shí)現(xiàn)
免流量費(fèi)下載資料----在經(jīng)管之家app可以下載論壇上的所有資源,并且不額外收取下載高峰期的論壇幣。
涵蓋所有經(jīng)管領(lǐng)域的優(yōu)秀內(nèi)容----覆蓋經(jīng)濟(jì)、管理、金融投資、計(jì)量統(tǒng)計(jì)、數(shù)據(jù)分析、國貿(mào)、財(cái)會(huì)等專業(yè)的學(xué)習(xí)寶庫,各類資料應(yīng)有盡有。
來自五湖四海的經(jīng)管達(dá)人----已經(jīng)有上千萬的經(jīng)管人來到這里,你可以找到任何學(xué)科方向、有共同話題的朋友。
經(jīng)管之家(原人大經(jīng)濟(jì)論壇),跨越高校的圍墻,帶你走進(jìn)經(jīng)管知識(shí)的新世界。
掃描下方二維碼下載并注冊(cè)APP
本文論壇網(wǎng)址:http://xalimeijing.com/thread-6693525-1-1.html
您可能感興趣的文章
人氣文章
本文標(biāo)題:股市風(fēng)起云涌,我用Python分析周期之道
本文鏈接網(wǎng)址:http://xalimeijing.com/jg/kaoyankaobo_kaoyan_6693525_1.html
2.轉(zhuǎn)載的文章僅代表原創(chuàng)作者觀點(diǎn),與本站無關(guān)。其原創(chuàng)性以及文中陳述文字和內(nèi)容未經(jīng)本站證實(shí),本站對(duì)該文以及其中全部或者部分內(nèi)容、文字的真實(shí)性、完整性、及時(shí)性,不作出任何保證或承若;
3.如本站轉(zhuǎn)載稿涉及版權(quán)等問題,請(qǐng)作者及時(shí)聯(lián)系本站,我們會(huì)及時(shí)處理。