立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 456|回复: 4

[分享] 如何判断时间序列是否具有周期性,以及季节性?

[复制链接]
发表于 2024-9-14 12:13 | 显示全部楼层 |阅读模式
回复

使用道具 举报

发表于 2024-9-14 12:13 | 显示全部楼层
从信号处理角度进行分析
简单的时间序列直接做各种谱分析(频谱,包络谱,平方包络谱,功率谱,倒谱等等)
比如一些简单的旋转机械振动时间序列信号


如果频谱不好分析,那可以分析如下图所示的时间序列的时频谱


给个简单的模拟信号的例子
t = 0:1/2000:1-1/2000;
dt = 1/2000;
x1 = sin(50*pi*t).*exp(-50*pi*(t-0.2).^2);
x2 = sin(50*pi*t).*exp(-100*pi*(t-0.5).^2);
x3 = 2*cos(140*pi*t).*exp(-50*pi*(t-0.2).^2);
x4 = 2*sin(140*pi*t).*exp(-80*pi*(t-0.8).^2);
x = x1+x2+x3+x4;
figure;
plot(t,x)
title('Superimposed Signal')

其连续小波变换时频谱如下


一个模拟的轴承内圈故障振动信号,带有明显的周期性


相应的频谱如下,红色虚线代表故障特征频率及相应的倍频


包络谱如下


看一下相应的CWT时频谱,很明显能看出冲击性


还可以试试小波相干与交叉小波分析
小波相干、交叉小波,可以很好地反映两个不同时间序列变化之间的“相关性”。小波相干分析,一般反映序列间周期性“变化趋势”的一致性,但不直接反映变化周期的强度关系;交叉小波分析,一般反映序列间“共有周期”的强度。






此外,如果时频谱线能量发散,时频脊线模糊,还可以试试同步压缩之类的算法
时间序列信号处理系列-基于Python的同步压缩变换 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/554189692
当时间序列信号中噪声较大时,为了有利于周期性分析,不可避免地要进行降噪前处理
比如K-SVD降噪


样条框架降噪


Morlet小波降噪










当待分析的时间序列过于复杂时,那可能要引入模态分解(多分辨分析),比如小波分解,经验模态分解及其变体,变分模态分解,经验小波变换,局部均值分解,辛几何模态分解,各种各样的自适应分解算法
基于小波脊线的时间序列分解










好多同学都对各种模态分解方法的时间序列处理感兴趣,那就随便说一下
实际上,时间序列通常由多个具有物理意义的分量组成,在很多时候,为了更容易的研究信号,我们希望在与原始数据相同的时间尺度上单独研究这些分量中的一个或多个,理想情况下,我们希望这些经MRA分解到的多个分量在物理上是有意义的,可容易解释的。多分辨率分析MRA通常与小波或小波包相关联,但诸如经验模态分解EMD,变分模态分解VMD等模态分解方法也可以构成MRA。
先给一个简单的合成信号,信号以1000Hz的频率采样1秒钟。
Fs = 1e3;
t = 0:1/Fs:1-1/Fs;
comp1 = cos(2*pi*200*t).*(t>0.7);
comp2 = cos(2*pi*60*t).*(t>=0.1 & t<0.3);
trend = sin(2*pi*1/2*t);
rng default
wgnNoise = 0.4*randn(size(t));
x = comp1+comp2+trend+wgnNoise;
plot(t,x)
xlabel('Seconds')
ylabel('Amplitude')
title('Synthetic Signal')

该信号由3个主要分量组成:频率为 60Hz的时间局部振荡分量、频率为 200 Hz的时间局部振荡分量和趋势项分量。趋势项分量为正弦曲线,频率为0.5Hz。60Hz的振荡分量发生在 0.1到 0.3 秒之间,而 200Hz的振荡分量发生在 0.7 到 1 秒之间。
但这些分量从时域波形中无法分辨,因此进行频域变换。
xdft = fft(x);
N = numel(x);
xdft = xdft(1:numel(xdft)/2+1);
freq = 0:Fs/N:Fs/2;
plot(freq,20*log10(abs(xdft)))
xlabel('Cycles/second')
ylabel('dB')
grid on

从频率中可以更容易地辨别振荡分量的频率,但时间局部性信号却丢失。为了同时定位时间和频率信息,使用连续小波变换进行分析。


从CWT时频谱图中可以看出60Hz和200Hz分量的时间范围,但没有发现趋势项分量。为了分离出信号的分量并单独进行分析,接下来使用多分辨分析,直接在时域中进行相关操作。
多分辨分析通过将信号分成不同分辨率的分量进而缩小分析范围,而提取不同分辨率的信号分量相当于分解数据在不同时间尺度上的变化,或等效地在不同频带上进行分析。首先,采用离散小波变换的变体最大重叠离散小波变换对信号进行多分辨分析,分解层数为8。关于最大重叠离散小波变换的相关内容,请查看如下文献。


最大重叠离散小波变换的8层多分辨分析分解如下:


如果从上向下看,会看到所分解的分量变得越来越平滑,即分量频率越来越低。回想一下,原始信号包含3个主要分量,一个 200 Hz 的高频振荡成分、一个 60 Hz 的低频振荡成分和一个趋势成分,它们都被加性噪声破坏了。
从D2 图中可以看出时间局部化的高频分量被分解出来,而下面的两个图包含较低频率的振荡分量,这是多分辨率分析的一个重要方面,最后S8子图中包含了趋势项分量。
除了小波多分辨分析,经验模态分解 (EMD) 是一种所谓的数据自适应多分辨技术。 EMD 在不使用固定基函数的情况下递归地从数据中提取不同的分辨率成分,关于EMD相关文献浩如烟海,不做赘述了。EMD的多分辨分析分解如下所示:


虽然MRA分解分量的数目不同,但 EMD MRA和小波 MRA会产生相似的信号波形,在 EMD MRA分解中,高频振荡成分位于第1个本征模态函数中 (IMF1),低频振荡成分主要位于IMF2和IMF3中,IMF6 中的趋势项分量与小波技术提取的趋势分量非常相似。
自适应多分辨分析的另一种技术是变分模态分解 (VMD),VMD 从信号中提取固有模式函数或振荡模式,并不使用固定基函数进行分析。EMD在时域上递归,以逐步提取低频IMF分量,而VMD 首先识别频域中的信号峰值并同时提取所有模式,相关文献如下:
Dragomiretskiy, Konstantin, and Dominique Zosso. “Variational Mode Decomposition.” IEEE Transactions on Signal Processing 62, no. 3 (February 2014): 531–44. https://doi.org/10.1109/TSP.2013.2288675.
VMD的多分辨分析分解如下所示:


由上图可知,与小波和EMD类似,VMD将3个分量基本分离了出来。
还有一种数据自适应多分辨分析技术:经验小波变换 (EWT) ,EWT根据分析信号的频率构造 Meye小波进而进行自适应小波,之前写过EWT相关的内容:
经验小波变换在信号处理及轴承故障诊断中的应用 - 哥廷根数学学派的文章 - 知乎https://zhuanlan.zhihu.com/p/53
EWT的多分辨分析分解如下所示:


与之前的EMD和小波MRA类似,EWT分解出了相关的振荡分量,用于执行分析的滤波器及其通带信息如下:


下面考虑一段神户地震信号,源于1995 年 1 月 16 日在澳大利亚霍巴特的塔斯马尼亚大学记录,从 20:56:51 (GMT) 开始,以 1 秒的间隔持续 51分钟。
figure
plot(T,kobe)
title('Kobe Earthquake Seismograph')
ylabel('Vertical Acceleration (nm/s^2)')
xlabel('Time')
axis tight
grid on

以最大重叠离散小波变换为例,其8层MRA分解如下:


从D4和D5子图中可以看出初级与延迟次级波分量,地震波中的分量以不同的速度传播,初级波比次级(剪切)波传播的更快。
将信号分解为若干分量的目的通常是去除某些分量以减轻对信号分析的影响,MRA技术的关键是重建原始信号的能力,如下:


每种方法的最大重建误差约为10^(-12) 或更小,表明它们可以完美地对信号进行重建。在很多研究中我们对趋势项不感兴趣,由于趋势项一般位于最后一个 MRA 分解分量中,因此只需将该分量去除,然后进行重建。


此外,再删除第1个MRA分解分量(看起来主要是噪声)


在前面我们将趋势项删除,然而在许多应用中,趋势项可能是我们的主要研究部分,因此可视化几种MRA方法所提取的趋势项分量。


根据以上的分析,小波MRA技术可以更平滑且最准确地提取趋势项,EMD提取了一个平滑的趋势项,但它相对于真实趋势幅度发生了偏移,而 VMD似乎比小波和EMD更偏向于提取振荡分量。
在前面的示例中,强调了多分辨分析在检测数据中的振荡分量和总体趋势中的作用,然而MRA还可以定位和检测信号中的瞬态成分。为了说明这一点,以1947年第一季度至 2011 年第四季度美国实际国内生产总值 (GDP) 数据,垂直的黑线标志着“大缓和”的开始,标志着从 1980 年代中期开始,美国宏观经济波动性减弱的时期,很难从原始数据中辨别出来。

回复 支持 反对

使用道具 举报

发表于 2024-9-14 12:14 | 显示全部楼层
ACM SIGKDD国际会议(简称 KDD)是由ACM的数据挖掘及知识发现专委会主办的数据挖掘研究领域的顶级年会,是数据挖掘领域历史最悠久、规模最大的国际顶级学术会议,会议分为研究和应用科学两个方向,在知识发现、数据挖掘、人工智能等领域具有重大影响力。第28届KDD会议于2022于8月14日至18日在美国华盛顿举行。
复杂时间序列的预测问题在实际应用中十分常见,这类序列往往带有复杂的周期性,但很少有模型能够处理复杂的周期性模式,例如真实数据集中的多个周期、可变周期和相位转移。本次分享的论文将周期和相位以可学习的形式融入Transformer,以解决复杂时间序列预测问题。
Learning to Rotate: Quaternion Transformer for Complicated Periodical Time Series Forecasting

Chen, W., Wang, W., Peng, B., Wen, Q., Zhou, T., & Sun, L. (2022, August).
DAMO Academy, Alibaba Group, Hangzhou, China
1. 背景和问题

时间序列预测在能源、交通、经济、气象和传染疾病等领域都有非常重要的应用。长期的预测可以为规划和预警提供指导。为了预测的准确性,需要对复杂时间依赖进行建模,包括周期性的和趋势性的依赖。此外还需要降低计算复杂度。
在微软大数据中心,60%以上的时间序列表现出周期性,尤其是面向业务的时间序列数据。复杂周期性由于多周期、变周期和相移等原因,在时间序列预测中十分复杂。
已有的基于Transformer的时间序列预测方法:
LogTrans:利用子序列级的注意力机制,利用距离的指数增加注意力稀疏度
Informer:query稀疏性(删除信息较少的queries),降尺度
Autoformer:Season-trend分解,序列级(非点级)的聚合
但是前两者不能显式地建模周期模式,最后一种方法不能处理复杂周期模式(例如可变周期或相移)。 当前仍存在问题:
1)由于时序依赖关系可能被纠缠的趋势和周期模式所掩盖,如何对时序依赖关系进行建模仍然是一个挑战。
2)传统的预测方法,如seasonal ARIMA和Prophet,也利用了具有启发式周期先验的分解,但未能自动智能地建模复杂的周期模式。
2. 方法介绍

本文提出了方法框架——Quaternion Transformer——可以处理复杂的周期模式,并且打破长时间序列预测的计算效率瓶颈,主要目标是对复杂的周期模式进行建模,以实现准确的时间序列预测。框架如下图所示,其中learning-to-rotate attention (LRA) with quaternion用于对时间序列复杂的周期依赖进行建模;trend normalization和layer normalization类似,但强调隐藏层中序列表示的缓慢变化趋势;除此之外,框架还提出了用解耦注意力机制来将LRA的二次复杂度降低到线性复杂度。


图1 模型框架
2.1 Learning-to-Rotate Attention

本方法设计了一种新的核,即rotatory softmax-kernel,通过四元数形式将给定时间序列的表示序列按频率(或周期)进行旋转,从而在测量成对相似性时融入周期和相位信息。




图2 典型的注意力结构 vs LRA
四元数和rotatory softmax-kernel需要满足如下三个特性。其一是有界性,由此保证新内积的稳定性,其二是初始值不变性,在初始位置上,新的核与原始的soft-max核一致。



其三是周期无关性和相位有关性,计算的相似性取决于相位,而不是周期。



本文找到了四元数这一形式满足这些特性的需求。 Quaternions(四元数)是一种对复数的扩展,相关的计算规则如下:



将实值向量转换为四元数形式:



利用四元数实现Rotatory Softmax核:



图3 旋转性的多维展示


图4 LRA结构的详细阐述
该内核可以直接插入点积注意力。为进一步处理多个周期、可变周期和相位偏移,本文提出以数据驱动的方式学习潜在的频率和相位,得到旋转学习注意力,保留了对注意力机制长程依赖的建模能力,并利用了时间序列的周期特性。
2.2 趋势归一化

时间序列的趋势,是一个变化缓慢的方程,在隐藏层中对这个趋势进行建模。本文提出趋势归一化,通过强制趋势分量的缓慢变化特性来更好地归一化隐藏层中的序列表示。


图5 趋势归一化
2.3 用全局memory解耦注意力机制

LRA的复杂度是,计算成本太高,为此本方法引入了momentum-updated c-length latent series
可以将注意力机制,解耦为如下形式:


的更新方式:



通过引入一个额外的固定长度的潜序列来存储全局记忆,将注意力机制解耦为两个具有线性复杂度的注意力。
3. 实验和结果

数据集
实验中用到了6个数据集



Baseline



参数设置



评估方式



实验结果



图6 实验结果对比 与所有数据集和所有设置中第二好的模型Autoformer相比,本文方法的MSE总体提高了8.1%,MSE提高了18.5%。
消融实验
论文方法优于经典的注意力机制:




图7 LRA与传统方法的对比
趋势归一化的有效性:



计算效率的提升:



图8 内存占用率和运行效率的对比
Momentum优化更新机制的有效性:



4. 结论和展望

对于复杂周期模式,LRA采用四元数表征引入了周期和相位信息;对于趋势的表征,Quatform采用了多项式近似的趋势归一化;对于长序列,Quatform采用全局共享的memory实现注意力解耦。



图9 Quatform的创新性总结
三个方面的优化提升让本文提出的方法Quatform不仅可以捕捉时间序列中的复杂周期模式(多周期,可变周期,相移),还对其中的趋势缓慢变化特性进行了建模,并且改善了方法的计算效率。
自 Transformer 大火以来,出现了各种对 Transformer 模型的改进,一般称之为X-former,这些模型大都集中于改进 Transformer 的时间复杂度和空间复杂度,大部分都是对 self-attention 部分进行改进。今天分享的论文延续了这一思路,将周期模式融入,增强了模型对复杂周期的适用性。
更多内容,敬请关注同名微信公众号:时空大数据兴趣小组。

回复 支持 反对

使用道具 举报

发表于 2024-9-14 12:14 | 显示全部楼层
研究时间序列投资有两种思路,一种是用模型给出未来价格的随机分布情况,另一种是用模型直接给出买卖点。这篇文章主要介绍后一种思路中的关键步骤,买卖点确认问题。

买卖点的作用
买卖点的确认相当于是为以后的拟合算法制作标准答案。

买卖点确认问题
可能有些人认为这不是个问题。直接用两天的数据比对,如果涨就买,如果跌就卖。但这样的买卖点做出来之后会表现得非常随机,以至于很难去做一个模型去预测这样几乎没有规律的买卖点,或者说即使能预测也会很麻烦,要结合很多方面的数据。而只要减少交易次数,有些指标就可以给出一点趋势的痕迹。从而达到“顺势而为”的目的。但在此之前我们需要用算法来解决上述提到的问题。

问题:
有一个已知的时间序列,问如何交易才能使得固定交易次数的情况下,获利最多。

为什么一到要取最优解,看着能赚钱就好了不是么?
在制作模型阶段,任何东西都可能导致整个模型意外,而买卖点就是程序需要学习的答案,如果这一步就没有达到最优解,那么接下来做模型只会错得更离谱。买卖点的确认首先是确认上限在哪,在真正预测的时候是没法达到上限的,可能能有上限的10%就已经很不错了。这时候如果没有达到最优解,胡乱的浪费交易次数会对预测造成严重干扰。
试想一下三年内,总共交易150次,结果按照凭感觉的做出的买卖点只能略微跑赢大盘,那么模型学习阶段就会把一个不完美的买卖点当做标准答案,学出来的结果大概率跑不赢大盘。
用代码定义一下:
def getOptimalBS(ys,tradeNumber)
  """
  ys: 时间序列 长度为N
  tradeNumber: 交易次数  
  return 买入为1 卖出为0,长度为N的序列
  """近似算法
def getWaitAllGreedyOPT(ys,prd=5):
        qs = np.zeros(len(ys))
        pre_q = 0
        for i in range(len(ys[:-prd])):
                #last chunck is -prd-1,-prd,,-prd+1,-prd+2 ... -prd+(prd-1)=-1 total N
                #            num of chunck = prd+1
                sub = ys[i:i+prd+1]
                #   chunck =  i+0, i+1,..., i+(prd)
                #   num of chunk = prd+1 including the current idx
                logSub = np.log(sub)
                log_gain_loss = logSub[1:]-logSub[0]
                if pre_q == 1:
                        if np.all(log_gain_loss<0):
                                qs = -1
                        else:
                                qs = 1
                elif pre_q == -1:
                        if np.all(log_gain_loss>0):
                                qs = 1
                        else:
                                qs= -1
                else:
                        if np.all(log_gain_loss>0):
                                qs = 1
                        else:
                                qs = -1
                pre_q = qs
        return qs

def getWaitGreedyOPT(ys,prd=5):
        qs = np.zeros(len(ys))
        pre_q = 0
        for i in range(len(ys[:-prd])):
                #last chunck is -prd-1,-prd,,-prd+1,-prd+2 ... -prd+(prd-1)=-1 total N
                #            num of chunck = prd+1
                sub = ys[i:i+prd+1]
                #   chunck =  i+0, i+1,..., i+(prd)
                #   num of chunk = prd+1 including the current idx
                logSub = np.log(sub)
                log_gain_loss = logSub[1:]-logSub[:-1]
                head,tail = logSub[0],logSub[-1]
                if pre_q == 1:
                        if tail<head and log_gain_loss[0]<0:
                                qs = -1
                        else:
                                qs = 1
                elif pre_q == -1:
                        if tail>head and log_gain_loss[0]>0:
                                qs = 1
                        else:
                                qs= -1
                else:
                        if log_gain_loss[0]>0:
                                qs = 1
                        else:
                                qs = -1
                pre_q = qs
        return qs

def getGreedyDailyOPT(ys,prd=5):
        qs = np.zeros(len(ys))
        for i in range(len(ys[:-prd])):
                sub = ys[i:i+prd+1]
                logSub = np.log(sub)
                log_gain_loss = logSub[1:]-logSub[:-1]
                if log_gain_loss[0]>0:
                                qs = 1
                else:
                                qs = -1
        return qs

def getLongWaitOPT(ys,prd=5):
        qs = np.zeros(len(ys))
        for i in range(len(ys[:-prd])):
                sub = ys[i:i+prd+1]
                head,tail = sub[0],sub[-1]
                if tail>head:
                        qs = 1
                else:
                        qs = -1
        return qs
结果
Code                     Algo Default Gain     Trade Gain #Trade #Data Point
0        #GBTC     getGreedyDailyOPT-D1       239.7%  1300300471.0%    380         756
1        #GBTC   getWaitAllGreedyOPT-D1       239.7%  1300300471.0%    380         756
2        #GBTC      getWaitGreedyOPT-D5       239.7%     9376123.5%    134         756
3        #GBTC   getWaitAllGreedyOPT-D5       239.7%    13366867.9%    106         756
4        #GBTC        getLongWaitOPT-D5       239.7%      264767.9%    148         756
5                                                                                    
6        #GBTC     getGreedyDailyOPT-D1       239.7%  1300300471.0%    380         756
7        #GBTC   getWaitAllGreedyOPT-D1       239.7%  1300300471.0%    380         756
8        #GBTC     getWaitGreedyOPT-D10       239.7%      558461.3%     92         756
9        #GBTC  getWaitAllGreedyOPT-D10       239.7%      325524.4%     42         756
10       #GBTC       getLongWaitOPT-D10       239.7%       42862.2%     98         756
11                                                                                    
12       #GBTC     getGreedyDailyOPT-D1       239.7%  1300300471.0%    380         756
13       #GBTC   getWaitAllGreedyOPT-D1       239.7%  1300300471.0%    380         756
14       #GBTC     getWaitGreedyOPT-D20       239.7%      117150.5%     54         756
15       #GBTC  getWaitAllGreedyOPT-D20       239.7%      100793.4%     24         756
16       #GBTC       getLongWaitOPT-D20       239.7%        8034.3%     56         756
17                                                                                    
18        #QQQ     getGreedyDailyOPT-D1       192.5%        7238.2%    396         756
19        #QQQ   getWaitAllGreedyOPT-D1       192.5%        7238.2%    396         756
20        #QQQ      getWaitGreedyOPT-D5       192.5%        2015.2%    132         756
21        #QQQ   getWaitAllGreedyOPT-D5       192.5%        1819.2%     88         756
22        #QQQ        getLongWaitOPT-D5       192.5%         895.6%    148         756
23                                                                                    
24        #QQQ     getGreedyDailyOPT-D1       192.5%        7238.2%    396         756
25        #QQQ   getWaitAllGreedyOPT-D1       192.5%        7238.2%    396         756
26        #QQQ     getWaitGreedyOPT-D10       192.5%         982.6%     78         756
27        #QQQ  getWaitAllGreedyOPT-D10       192.5%         877.9%     36         756
28        #QQQ       getLongWaitOPT-D10       192.5%         603.1%     88         756
29                                                                                    
30        #QQQ     getGreedyDailyOPT-D1       192.5%        7238.2%    396         756
31        #QQQ   getWaitAllGreedyOPT-D1       192.5%        7238.2%    396         756
32        #QQQ     getWaitGreedyOPT-D20       192.5%         473.6%     48         756
33        #QQQ  getWaitAllGreedyOPT-D20       192.5%         585.0%     18         756
34        #QQQ       getLongWaitOPT-D20       192.5%         335.2%     50         756
35                                                                                    
36        #DIA     getGreedyDailyOPT-D1       143.4%        1697.4%    376         756
37        #DIA   getWaitAllGreedyOPT-D1       143.4%        1697.4%    372         756
38        #DIA      getWaitGreedyOPT-D5       143.4%         642.4%    120         756
39        #DIA   getWaitAllGreedyOPT-D5       143.4%         751.1%     92         756
40        #DIA        getLongWaitOPT-D5       143.4%         360.4%    134         756
41                                                                                    
42        #DIA     getGreedyDailyOPT-D1       143.4%        1697.4%    376         756
43        #DIA   getWaitAllGreedyOPT-D1       143.4%        1697.4%    372         756
44        #DIA     getWaitGreedyOPT-D10       143.4%         466.6%     78         756
45        #DIA  getWaitAllGreedyOPT-D10       143.4%         476.6%     38         756
46        #DIA       getLongWaitOPT-D10       143.4%         284.0%     86         756
47                                                                                    
48        #DIA     getGreedyDailyOPT-D1       143.4%        1697.4%    376         756
49        #DIA   getWaitAllGreedyOPT-D1       143.4%        1697.4%    372         756
50        #DIA     getWaitGreedyOPT-D20       143.4%         288.1%     48         756
51        #DIA  getWaitAllGreedyOPT-D20       143.4%         329.5%     18         756
52        #DIA       getLongWaitOPT-D20       143.4%         215.5%     58         756
53                                                                                    
54  #510300.SS     getGreedyDailyOPT-D1       138.4%        5160.6%    376         756
55  #510300.SS   getWaitAllGreedyOPT-D1       138.4%        5160.6%    372         756
56  #510300.SS      getWaitGreedyOPT-D5       138.4%        1850.3%    138         756
57  #510300.SS   getWaitAllGreedyOPT-D5       138.4%        1872.1%    102         756
58  #510300.SS        getLongWaitOPT-D5       138.4%         787.2%    154         756
59                                                                                    
60  #510300.SS     getGreedyDailyOPT-D1       138.4%        5160.6%    376         756
61  #510300.SS   getWaitAllGreedyOPT-D1       138.4%        5160.6%    372         756
62  #510300.SS     getWaitGreedyOPT-D10       138.4%         922.1%    106         756
63  #510300.SS  getWaitAllGreedyOPT-D10       138.4%         874.0%     50         756
64  #510300.SS       getLongWaitOPT-D10       138.4%         484.4%    122         756
65                                                                                    
66  #510300.SS     getGreedyDailyOPT-D1       138.4%        5160.6%    376         756
67  #510300.SS   getWaitAllGreedyOPT-D1       138.4%        5160.6%    372         756
68  #510300.SS     getWaitGreedyOPT-D20       138.4%         555.5%     70         756
69  #510300.SS  getWaitAllGreedyOPT-D20       138.4%         527.6%     28         756
70  #510300.SS       getLongWaitOPT-D20       138.4%         318.0%     84         756
getGreedyDailyOPT 就是时间序列在完全已知的情况下的极限收益率
getLongWaitOPT 如果5天(包括当天收盘价)会涨就买,跌就卖。
getWaitGreedyOPT 可以理解为一定程度的延迟,等到真的出现拐点的时候再交易,而不是在之前还能涨,或者还没跌完的时候交易。这种交易方法可以比getLongWaitOPT 使用更少的交易次数,赚更多的收益。
getWaitAllGreedyOPT 是在getWaitGreedyOPT 上进一步改进,只有当local min和local max出现的时候才开始交易。其余时间都保持原有的状态,收益和getWaitGreedyOPT相比收益可能低,也可能高,但可以大幅度减少交易次数。
getWaitAllGreedyOPT-D1 可以看做是在getGreedyDailyOPT经常时间上做的一点点优化。

注:如果有人做出来这个最优买卖点算法请告诉我,不胜感激。
回复 支持 反对

使用道具 举报

发表于 2024-9-14 12:14 | 显示全部楼层
利用傅里叶变换,观察是否存在明显峰值
利用函数自相关性,观察是否有周期性的相关性
绘制函数的时间-频域图,观察是否在存在规律性
绘制信号-信号随时间导数组成的相空间图,观察是否能够形成一个规律图形。或者绘制庞加莱截面,观察截面上系统的交点是否具有周期性或准周期性。
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表