Python环境下基于动态模态分解的股票价格预测

2024-04-16 08:44

本文主要是介绍Python环境下基于动态模态分解的股票价格预测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

动态模态分解模型的基本思想是直接从数据模拟得到的流场中提取流动的动态信息,根据不同频率的流场变动寻找数据映射,基于动态非线性无穷维转化成动态线性有穷维的方式,采用了Arnoldi 方法以及奇异值分解SVD降维的思想,借鉴了ARIMA、SARIMA 以及季节模型等许多时间序列的关键特征,被广泛的使用在数学、物理、金融等领域。

动态模态分解按照频率对系统进行排序,提取系统特征频率,从而观察不同频率的流动结构对流场的贡献,同时动态模态分解模态特征值可以进行流场预测。因为动态模态分解算法理论的严密性、稳定性、简易性等优点,在不断被运用的同时,动态模态分解算法也在本来的基础之上不断被完善,如与SPA检验结合起来,以验证股票价格预测对比基准点的强有效性;以及通过联系动态模态分解算法和光谱研究的方式,模拟股票市场在循环经济当中的震动,均能够有效地采集分析数据,并最终得到结果。

import numpy as np
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import matplotlib as mpl#%% Load data
data = pd.read_csv('historical_stock_prices.csv')#%% User inputs
# Choose dates
start_date = '2014-03-18'
end_date = '2015-03-18'# Choose tickers
s1 = 'AEO'
s2 = 'ANF'
s3 = 'FL'
s4 = 'GPS'
s5 = 'SCVL'
s6 = 'RL'
s7 = 'URBN'
s8 = 'ROST'# Number of past days to build the DMD model on
mp = 7
# Number of future days to predict with DMD
mf = 1# Percentage of portfolio to sell off each day
sell_perc = 0.25# Initial capital
init_cap = 1e6#%% Functionsdef GetPrices(portfolio_size, bigX, current_day):'''Gets the day close prices of each company in the portfolio at the currentdayInputs:portfolio_size: int, the number of companies that we can trade withbigX: array (portfolio size * number of days), consisting of time series close prices along the columns and new companies along the rowscurrent_day: int, the last day considered in the DMD model construction inorder to make a prediction about the next dayreturns: day_close: array (portfolio size * 1), consisting of close prices for each company on the current day'''# Find prices on a given dayday_close = np.zeros(shape=(portfolio_size,1))for i in range(0,portfolio_size):day_close[i,0] = bigX[i,current_day-1]return day_closedef Trade(current_day, mp, mf, bigX, portfolio_size, stock_amounts, day_close, sell_perc):'''The core algorithm, executing trades and stepping forward days in time.Inputs:current_day: int, the last day considered in the DMD model construction inorder to make a prediction about the next daymp: int, number of historical days used to build the DMD modelmf: int, number of days to predict in the future with the DMD modelbigX: array (portfolio size * number of days), consisting of time series close prices along the columns and new companies along the rowsportfolio_size: int, the number of companies that we can trade withstock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio at the current dayday_close: array (portfolio size * 1), consisting of close prices for each company on the current daysell_perc: float, a user input defining which proportion of the portfolio valueshould be sold at the end of each dayreturns: stock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio after trades have been executedday_close: array (portfolio size * 1), consisting of the new day close prices after stepping forward one daycurrent_day: int, the next day after taking one step forward'''first_day = current_day - (mp-1)# Time vector spans mp+mf, DMD will extrapolate to make a prediction about mft = list(range(first_day,mp+first_day+1))# Form the DMD matricesX1 = bigX[:,(first_day-1):(current_day-1)]X2 = bigX[:,(first_day):current_day]# Snapshots separated by 1 trading daydt = 1# Conduct DMDPhi, b, omega = DMD(X1, X2, dt)# DMD reconstruction to predict price on current_day + 1price_predictions = DMDreconstruct(X1, t, b, omega, Phi, mp, mf)# Calculate increases in price between current_day and the following dayprice_increases = np.zeros(shape=(portfolio_size,1))for i in range(0,portfolio_size):price_increases[i,0] = (price_predictions[i] - bigX[i,current_day-1])/bigX[i,current_day-1]# Calculate current portfolio valueportfolio_value = np.zeros(shape=(portfolio_size,1))for i in range(0,portfolio_size):portfolio_value[i,0] = stock_amounts[i,0]*day_close[i,0]# Sell bottom 25% of portfoliocash, stock_amounts = Sell(portfolio_value, sell_perc, price_increases, portfolio_size, stock_amounts, day_close)# Buy best performing shares with cash from sales.stock_amounts = Buy(price_increases, cash, day_close, stock_amounts)# Increment daycurrent_day += 1# Get new day_close pricesday_close = GetPrices(portfolio_size, bigX, current_day)return stock_amounts, day_close, current_daydef Sell(portfolio_value, sell_perc, price_increases, portfolio_size, stock_amounts, day_close):'''Conducts the sale of a proportion of the stocks in the portfolio with theworst predicted next-day pricesInputs:portfolio_value: array (portfolio size * 1), calculating the total value of all stocks held in the portfolio according to the current day close pricessell_perc: float, a user input defining which proportion of the portfolio valueshould be sold at the end of each dayprice_increases: array (portfolio size * 1), calculating the predicted changesin price between the current day and the next-day prediction for each stock portfolio_size: int, the number of companies that we can trade withstock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio at the current dayday_close: array (portfolio size * 1), consisting of close prices for each company on the current dayreturns: cash: float, the amount of cash generated by the sale of the worst-performingstocksstock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio at the end of the sale'''sell_value = np.sum(portfolio_value)*sell_perccash = 0lowest = np.sort(price_increases,axis=None)for i in range(0,portfolio_size):# For each ticker, find location of lowest price in price_increases lowest_value = stock_amounts[price_increases == lowest[i]]*day_close[price_increases == lowest[i]]temp_cash = cash + lowest_valueif temp_cash < sell_value:stock_amounts[price_increases == lowest[i]] = 0cash = temp_cashelif temp_cash == sell_value:stock_amounts[price_increases == lowest[i]] = 0cash = temp_cashbreakelse:number_sold = (sell_value-cash)/day_close[price_increases == lowest[i]]stock_amounts[price_increases == lowest[i]] = stock_amounts[price_increases == lowest[i]] - number_soldnew_cash = number_sold*day_close[price_increases == lowest[i]]cash = new_cash + cashbreakreturn cash, stock_amountsdef Buy(price_increases, cash, day_close, stock_amounts):'''Purchases stocks using the cash generated by the sale of the bottom of the portfolio, with an even distribution between the top two performing stocks.Inputs:price_increases: array (portfolio size * 1), calculating the predicted changesin price between the current day and the next-day prediction for each stock cash: float, the amount of cash generated by the sale of the worst-performingstocksday_close: array (portfolio size * 1), consisting of close prices for each company on the current daystock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio at the end of the salereturns: stock_amounts: array (portfolio size * 1), the number of stocks for each company held in the portfolio at the end of the purchases'''best = np.sort(price_increases,axis=None)[::-1]number_bought1 = 0.5*cash/day_close[price_increases == best[0]]number_bought2 = 0.5*cash/day_close[price_increases == best[1]]    stock_amounts[price_increases == best[0]] = stock_amounts[price_increases == best[0]] + number_bought1stock_amounts[price_increases == best[1]] = stock_amounts[price_increases == best[1]] + number_bought2return stock_amountsdef DMD(X1, X2, dt):'''Conducts the DMD analysisInputs:X1: array (portfolio size * (mp-1)), the first DMD matrixX2: array (portfolio size * (mp-1)), the second DMD matrixdt: float, the time difference between snapshots of data (ie days)returns: Phi: array (portfolio size * (mp-1)), the DMD modesb: array ((mp-1) * 1), the DMD mode amplitudesomega: array ((mp-1) * 1), the DMD mode frequencies'''# SVD on X1U,S,V = np.linalg.svd(X1,full_matrices=0)Sigmar = np.diag(S)# Calculate AtildeAtilde = np.linalg.solve(Sigmar.T,(U.T @ X2 @ V.T).T).T# Eigendecomp of AtildeLambda, W = np.linalg.eig(Atilde)L = np.diag(Lambda)# DMD modesPhi = X2 @ np.linalg.solve(Sigmar.T,V).T @ W# DMD amplitudesalpha1 = Sigmar @ V[:,0]b = np.linalg.solve(W @ L,alpha1)# Frequencyomega = np.log(Lambda)/dtreturn Phi, b, omegadef DMDreconstruct(X1, t, b, omega, Phi, mp, mf):'''Conducts the DMD reconstruction in order to make a next-day price predictionInputs:X1: array (portfolio size * (mp-1)), the first DMD matrixt: list (length mp+mf), time vector used to reconstruct the data matrixb: array ((mp-1) * 1), the DMD mode amplitudesomega: array ((mp-1) * 1), the DMD mode frequenciesPhi: array (portfolio size * (mp-1)), the DMD modesmp: int, number of historical days used to build the DMD modelmf: int, number of days to predict in the future with the DMD modelreturns: price_predictions: array (portfolio size * 1), the DMD model of day close prices projected out mf day(s) into the future'''time_dynamics = np.zeros(shape=(X1.shape[1],len(t)),dtype=np.complex128)for i in range(0,len(t)):time_dynamics[:,i] = np.multiply(b,np.exp(omega*t[i]))X_dmd = Phi @ time_dynamicsprice_predictions = np.real(X_dmd[:,(mp)])return price_predictions#%% Set parameters and reduce table size
after_start_date = data['date'] >= start_date
before_end_date = data['date'] <= end_date
between_two_dates = after_start_date & before_end_datetabledates = data.loc[between_two_dates]tickers = [s1,s2,s3,s4,s5,s6,s7,s8]
portfolio_size = len(tickers)# Get retail_table in the specified date range
reduced_table = []
for i in tickers:ticker_loc = tabledates['ticker'] == ireduced_table.append(tabledates.loc[ticker_loc])retail_table = pd.concat(reduced_table)# Form the big data matrix.
# For each ticker, get all the close prices and store.
days = len(retail_table[retail_table['ticker'] == tickers[0]])
bigX = np.zeros(shape=(portfolio_size,days))
for i in range(0,portfolio_size):temp = retail_table[retail_table['ticker'] == tickers[i]]temp_price_vector =  temp['close'].values.tolist()bigX[i,:] = temp_price_vector#%% Initialise the trading
# Initialise at day 7, as DMD uses data on the previous 7 days to predict
# the price on the following day
current_day = 7# Initialise capital and date
init_each = 1e6/portfolio_size
init_day = datetime.datetime.strptime(start_date,'%Y-%m-%d') + datetime.timedelta(days = (mp-1))day_close = GetPrices(portfolio_size, bigX, current_day)# Evenly distribute stock
stock_amounts = np.zeros(shape=(portfolio_size,1))
for i in range(0,portfolio_size):stock_amounts[i,0] = init_each/day_close[i]#%% The trading
# Initialise portfolio value over time
valuet = np.zeros(shape=(1,days))# Trade
for i in range(0,days-mp-1):stock_amounts, day_close, current_day = Trade(current_day, mp, mf, bigX, portfolio_size, stock_amounts, day_close, sell_perc);# Calculate value of portfolio and store in valuetvalue = np.sum(stock_amounts*day_close)valuet[0,i] = value#%% Load S&P data
SP = pd.read_csv('S&Pretail_reduced.csv')#%% Average returns
returnDMD = valuet[0,0:days-(mp+mf)] - 1e6
avreturnDMD = np.mean(returnDMD)
returnSP = SP['close'][0:days-(mp+mf)] - 1e6
avreturnSP = np.mean(returnSP)
DMDperformance = avreturnDMD/avreturnSP
print('DMD produces average returns of',round(DMDperformance,1),'times the S&P index.')#%% Plot
axdates = pd.to_datetime(SP['date'][0:days-(mp+mf)],dayfirst=True)plt.figure()
mpl.rc('font',family='Times New Roman')
plt.plot(axdates,valuet[0,0:days-(mp+mf)]/1e6,linewidth=3,color="#0072BD")
plt.plot(axdates,SP['close'][0:days-(mp+mf)]/1e6,linewidth=3,color="#7E2F8E")
plt.ylabel('USD (millions)',fontsize=20)
plt.legend(['DMD Algorithm','S&P Retail Index'],)
plt.grid()
plt.show()

图片

知乎学术咨询:

哥廷根数学学派 - 知乎

工学博士,担任《Mechanical System and Signal Processing》,《中国电机工程学报》等期刊审稿专家,擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

这篇关于Python环境下基于动态模态分解的股票价格预测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/908310

相关文章

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

基于Python实现高效PPT转图片工具

《基于Python实现高效PPT转图片工具》在日常工作中,PPT是我们常用的演示工具,但有时候我们需要将PPT的内容提取为图片格式以便于展示或保存,所以本文将用Python实现PPT转PNG工具,希望... 目录1. 概述2. 功能使用2.1 安装依赖2.2 使用步骤2.3 代码实现2.4 GUI界面3.效

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

Python从零打造高安全密码管理器

《Python从零打造高安全密码管理器》在数字化时代,每人平均需要管理近百个账号密码,本文将带大家深入剖析一个基于Python的高安全性密码管理器实现方案,感兴趣的小伙伴可以参考一下... 目录一、前言:为什么我们需要专属密码管理器二、系统架构设计2.1 安全加密体系2.2 密码强度策略三、核心功能实现详解

Python Faker库基本用法详解

《PythonFaker库基本用法详解》Faker是一个非常强大的库,适用于生成各种类型的伪随机数据,可以帮助开发者在测试、数据生成、或其他需要随机数据的场景中提高效率,本文给大家介绍PythonF... 目录安装基本用法主要功能示例代码语言和地区生成多条假数据自定义字段小结Faker 是一个 python

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Python实现AVIF图片与其他图片格式间的批量转换

《Python实现AVIF图片与其他图片格式间的批量转换》这篇文章主要为大家详细介绍了如何使用Pillow库实现AVIF与其他格式的相互转换,即将AVIF转换为常见的格式,比如JPG或PNG,需要的小... 目录环境配置1.将单个 AVIF 图片转换为 JPG 和 PNG2.批量转换目录下所有 AVIF 图

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.