mysql - SQL - 计算可变长度的可变移动平均值

标签 mysql sql database innodb

第一:这个问题不是重复的。我已经在这里问过了,它作为重复项被关闭了。虽然它与 stackoverflow 上的其他线程类似,但实际上要复杂得多。在假设它是重复的之前,请先阅读该帖子:

我正在尝试计算具有可变日期的可变移动平均线交叉。

即:我想提示用户输入 3 个值和 1 个选项。输入是通过网络前端进行的,因此我可以根据输入构建/编辑查询,或者在需要时进行多个查询。

X = 1st moving average term  (N day moving average. Any number 1-N)
Y = 2nd moving average term. (N day moving average. Any number 1-N)
Z = Amount of days back from present to search for the occurance of:
option = Over/Under: (> or <. X passing over Y, or X passing Under Y)


X day moving average passing over OR under Y day moving average
within the past Z days.

我的数据库是结构化的:

tbl_daily_data

id
stock_id
date
adj_close

和:

tbl_stocks

stock_id
symbol

我有一个 btree 索引:

daily_data(stock_id, date, adj_close)

stock_id

我被困在这个查询上并且在编写它时遇到了很多麻烦。如果变量是固定的,它看起来微不足道,但因为 X、Y、Z 都是 100% 相互独立的(例如,可以查看过去 100 天内的 5 天移动平均线,或过去 5 天内的 100 天移动平均线) 我在编码时遇到了很多麻烦。

求助! :(

编辑:有人告诉我更多的上下文可能会有帮助?

我们正在创建一个开放的股票分析系统,用户可以在其中执行趋势分析。我有一个数据库,其中包含 3500 只股票及其自 1970 年以来的价格历史记录。

此查询将每天运行以查找符合特定条件的股票 例如:

10 day moving average crossing over 20 day moving average within 5 days

20 day crossing UNDER 10 day moving average within 5 days

55 day crossing UNDER 22 day moving average within 100 days

但是每个用户可能对不同的分析感兴趣,所以我不能只存储每一行​​的移动平均值,它必须被计算。

最佳答案

我不确定我是否完全理解这个问题......但是这样的事情可能会帮助你到达你需要去的地方:sqlfiddle

SET @X:=5;
SET @Y:=3;
set @Z:=25;
set @option:='under';

select * from ( 

SELECT stock_id,
datediff(current_date(), date) days_ago, 
     adj_close,
     (
     SELECT
          AVG(adj_close) AS moving_average
     FROM
          tbl_daily_data T2
     WHERE
          (
               SELECT
                    COUNT(*)
               FROM
                    tbl_daily_data T3
               WHERE
                    date BETWEEN T2.date AND T1.date
          ) BETWEEN 1 AND @X
     ) move_av_1,
    (
     SELECT
          AVG(adj_close) AS moving_average
     FROM
          tbl_daily_data T2
     WHERE
          (
               SELECT
                    COUNT(*)
               FROM
                    tbl_daily_data T3
               WHERE
                    date BETWEEN T2.date AND T1.date
          ) BETWEEN 1 AND @Y
     ) move_av_2

FROM
     tbl_daily_data T1

where   
datediff(current_date(), date) <= @z
) x
where 
  case when @option ='over'  and move_av_1 > move_av_2 then 1 else 0 end + 
  case when @option ='under' and move_av_2 > move_av_1 then 1 else 0 end  > 0
order by stock_id, days_ago

基于@Tom H 的回答:How do I calculate a moving average using MySQL?

关于mysql - SQL - 计算可变长度的可变移动平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16267427/

相关文章:

java - C# 和 Java 将 DateTime 转换为字节数组时的区别

mysql - MySQL Workbench 的导入问题

php - 有什么方法可以将值传递给变量和总和吗?

java - CSV 到 MySQl 导入

sql - 如何计算 Oracle SQL 中计数列的总和?

sql - 甲骨文 10g : truncate string

sql-server - 按纬度/经度搜索半径

c# - 遇到 SQL 语法错误

MySQL查询合并表

java - java在内存中存储数据的数据库是哪个?