2022年美赛C题M奖思路复盘(附代码、附论文)
前言
美賽已經(jīng)結(jié)束4天了,一直忙于教資考試的準(zhǔn)備,今天我終于抽空寫了這篇C題思路復(fù)盤的博客。
題目大致要求
題目叫'Trading Strategies(交易策略)',一共給了兩個(gè)文件,分別是比特幣和黃金價(jià)格隨時(shí)間變化的CSV文件。大致要求可以分為以下四個(gè)步驟:
具體題目內(nèi)容見美賽網(wǎng)站:2022 MCM Problem C (immchallenge.org)http://www.immchallenge.org/mcm/2022_MCM_Problem_C.pdf
分析題目?
對于問題1,思路無非是分為兩個(gè)步驟,第一個(gè)步驟是預(yù)測出后幾日的價(jià)格進(jìn)而估計(jì)得到后幾日的收益率,然后通過動(dòng)態(tài)規(guī)劃模型進(jìn)行最優(yōu)化的求解。具體思路如下:
首先先看數(shù)據(jù)集,你會(huì)發(fā)現(xiàn)數(shù)據(jù)集只有兩列,時(shí)間一列和價(jià)格一列。這意味著知網(wǎng)或者其他數(shù)據(jù)庫中查到的很多論文寫的預(yù)測算法你都用不了了。為什么呢?因?yàn)槿思覍懻撐臅r(shí)候用的數(shù)據(jù)集都有其他的特征,而不是這里只有時(shí)間一列特征。所以那些什么SVM、貝葉斯網(wǎng)、向量自回歸等要求多維特征的算法都不適用。查來查去,有推薦使用LSTM、神經(jīng)網(wǎng)絡(luò)模型還有xgboost算法,但我都是不是很熟悉,最終還是用了時(shí)間序列ARIMA模型來做的預(yù)測。為什么用ARIMA模型來做的預(yù)測,我給出以下幾點(diǎn)原因:
- ARIMA模型屬于單時(shí)間序列模型,符合題目數(shù)據(jù)集提供的數(shù)據(jù)以及題目給出的要求。
- ARIMA模型是一個(gè)很常見的時(shí)間序列模型,較為成熟也是我所熟悉的,我能拿它寫不少東西。
- 我使用Python編程,而Python的statsmodels庫中提供了ARIMA現(xiàn)成的API,不用另外寫代碼,而且調(diào)用API繪制圖像的操作十分方便。
對于問題二呢,網(wǎng)上的思路都是說,改變什么參數(shù),看看收益率會(huì)不會(huì)提高,如果不會(huì)的話就說明是最優(yōu)的,但也沒說清楚具體怎么操作。而我的想法不完全是這樣的,我看了他們的思路突然想到了"梯度下降法",那你說如果我用模型的兩個(gè)參數(shù)(具體來講一個(gè)是ARIMA模型的AR參數(shù)另一個(gè)是MA參數(shù),作為梯度下降法改變模型的兩個(gè)搜索方向,然后進(jìn)行算法計(jì)算,理論上是完全可行的,于是乎我就這么干了。
對于問題三和問題四就不再多說了。但我也羅嗦一下,問敏感性分析,我除了做了問題三的手續(xù)費(fèi)的敏感性分析外,我還針對ARIMA模型做了敏感度分析。問題四就總分總來寫,總一段,分三段,也就是戰(zhàn)略、模型和結(jié)果各一段寫,最后寫個(gè)總結(jié),要注意的是英文備忘錄是有格式的,得按照格式來,要有點(diǎn)儀式感,不然你就可能會(huì)被扣分。
還有就是別忘了一開始寫數(shù)據(jù)清洗那一段,我用了基于時(shí)間序列的牛頓插值法進(jìn)行插補(bǔ),用箱型圖法判斷離群點(diǎn)。
接下來我貼出我的代碼。
代碼
import pandas as pd from pylab import * import statsmodels.api as sm from datetime import datetime from statsmodels.tsa.stattools import adfuller from statsmodels.tsa.stattools import kpss from statsmodels.stats.diagnostic import acorr_ljungboxdef adf_test(timeseries):print('Results of Dickey-Fuller Test:')dftest = adfuller(timeseries, autolag='AIC')dfoutput = pd.Series(dftest[0:4], index=['Test Statistic', 'p-value', '#Lags Used', 'Number of Observations Used'])for key, value in dftest[4].items():dfoutput['Critical Value (%s)'%key] = valueprint(dfoutput)def kpss_test(timeseries):print('Results of KPSS Test:')kpsstest = kpss(timeseries, regression='c')kpss_output = pd.Series(kpsstest[0:3], index=['Test Statistic','p-value','Lags Used'])for key, value in kpsstest[3].items():kpss_output['Critical Value (%s)'%key] = valueprint(kpss_output)dataGOLD = pd.read_csv("C:\\ProblemC\\LBMA-GOLD.csv") dataMKPRU = pd.read_csv("C:\\ProblemC\\BCHAIN-MKPRU.csv") dataGOLD['Date'] = pd.to_datetime(dataGOLD.Date) dataMKPRU['Date'] = pd.to_datetime(dataMKPRU.Date) dataGOLD = dataGOLD[dataGOLD['Date'] >= datetime.strptime('2016-9-11', "%Y-%m-%d")] dataMKPRU = dataMKPRU[dataMKPRU['Date'] >= datetime.strptime('2016-9-11', "%Y-%m-%d")] dataGOLD = dataGOLD[dataGOLD['Date'] <= datetime.strptime('2021-9-10', "%Y-%m-%d")] dataMKPRU = dataMKPRU[dataMKPRU['Date'] <= datetime.strptime('2021-9-10', "%Y-%m-%d")] dataGOLD = dataGOLD.sort_values('Date').reset_index(drop=True) dataMKPRU = dataMKPRU.sort_values('Date').reset_index(drop=True)adf_test(dataGOLD['Value']) kpss_test(dataGOLD['Value'])diffGOLD = dataGOLD['Value'].diff(1).dropna() diffMKPRU = dataMKPRU['Value'].diff(1).dropna()fig = plt.figure(figsize=(12, 8)) ax1 = fig.add_subplot(211) sm.graphics.tsa.plot_acf(diffMKPRU, ax=ax1) ax1.xaxis.set_ticks_position('top') ax2 = fig.add_subplot(212) sm.graphics.tsa.plot_pacf(diffMKPRU, ax=ax2) ax2.xaxis.set_ticks_position('bottom') fig.tight_layout() plt.show()fig = plt.figure(figsize=(12, 8)) ax11 = fig.add_subplot(211) sm.graphics.tsa.plot_acf(diffGOLD, ax=ax11) ax11.xaxis.set_ticks_position('top') ax22 = fig.add_subplot(212) sm.graphics.tsa.plot_pacf(diffGOLD, ax=ax22) ax22.xaxis.set_ticks_position('bottom') fig.tight_layout() plt.show()p_value = acorr_ljungbox(dataGOLD['Value']) print(p_value)results = sm.tsa.arma_order_select_ic(dataMKPRU['Value'], ic=['aic', 'bic'], trend='nc', max_ar=5, max_ma=5) print('AIC', results.aic_min_order) print('BIC', results.bic_min_order)n_sample = dataGOLD['Value'].shape[0] n_train = int(n_sample * 0.95) + 1 n_forecast = n_sample - n_traints_train = dataGOLD.iloc[:n_train]['Value'] ts_test = dataGOLD.iloc[n_train:]['Value']arima = sm.tsa.SARIMAX(ts_train, order=(2, 1, 0)) model_results = arima.fit() model_results.plot_diagnostics(figsize=(16, 12)) plt.show() print(model_results.summary())plt.title("Bitcoin price image after first-order difference") plt.plot(dataMKPRU['Date'], dataMKPRU['Value'].diff(1)) plt.show()plt.title("Gold price image after first-order difference") plt.plot(dataGOLD['Date'], dataGOLD['Value'].diff(1)) plt.show()代碼繪圖展示
我們使用matplotlib進(jìn)行繪圖,繪制了如下的圖片進(jìn)行展示:
箱型圖法檢測的兩張圖,如下:
價(jià)格隨時(shí)間變化的趨勢圖兩張:
一階差分圖兩張:?
應(yīng)用新策略后的趨勢圖一張:
?ARIMA模型預(yù)測圖一張
ACF圖和PACF圖兩張:?
各類圖表:一階差分圖、正態(tài)分布直方圖、QQ圖等?
代碼分析與第一問細(xì)節(jié)?
可以看到,statsmodels確實(shí)十分強(qiáng)大,各種API拿來就用,十分方便。
其中我們用ACF圖和PACF圖確定了參數(shù)的大致階數(shù),然后用BIC和AIC來定階。代碼只展示了黃金的ARIMA模型的階數(shù)為(2,1,0),比特幣模型的階數(shù)只要改下變量就行了,就不在展示了,比特幣模型的階數(shù)最終定為(4,1,4)。
就寫到這里吧,僅供參考和復(fù)盤。
最終獲獎(jiǎng)結(jié)果
更新于5月8日。
我們團(tuán)隊(duì)最終獲得了M獎(jiǎng),祝賀所有人!!!
結(jié)語
?這是我們的論文鏈接,僅供參考!學(xué)術(shù)生涯不易,請投喂我們,論文只要1.9元,也不是很貴!
2022年美賽(MCM)C題M獎(jiǎng)?wù)撐?/span>https://download.csdn.net/download/qq_41938259/85318021
END
總結(jié)
以上是生活随笔為你收集整理的2022年美赛C题M奖思路复盘(附代码、附论文)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT 5.9.0下载安装及配置教程
- 下一篇: 惠普局域网共享打印机设置_已解决: hp