目的根据输入日期而非最新日期选择每只股票最近30个交易日的平均收盘价
鉴于此;
1)如果输入日期是2015-09-18,则选择最近30个交易日的平均收盘价,例如(2015-09-18,2015-09-17,2015-09-16,...... 30天)
2)如果输入日期是2015-09-01,则选择最近30个交易日的平均收盘价,例如(2015-09-01,2015-09-31,2015-09-28,...... 30天)
3)表栏:自动收报机|代码|日期|打开|高|低|关闭|卷
4)表格仅包含交易日,周末和假日的记录
5)对于每只股票,有数千天的记录,但我们只想在任何给定时间点获得30天MA
Input date: 2015-09-01
Desired output
date | ticker | code | 30 day average closing price
2015-09-01 AAA 1122 1.33
2015-09-01 BBB 3344 0.79
...
...
...and so on for each stock
答案 0 :(得分:0)
EDIT
这个版本应该是灵活的,我希望不要太慢。由于不知道表格中的内容以及表格的调用方式,因此我假设一个表格可以使用代码=' AAA'' BBB'所以和close
意味着价格。您的指定日期应为' 2015-09-12'这里。替换' 2015-09-12'无论你喜欢什么。
30应该是交易日数。在'限制30'。
中替换您想要的任何内容自动收报机|代码|日期|打开|高|低|关闭|体积
尝试此版本
select pt.code, sum(pt.close) / count(*) as average
from pricetable pt
inner join
( select distinct `date`
from pricetable
where `date` <= '2015-09-12' # your given date
order by `date` desc
limit 30 # the number of trading days
) as d on d.`date` = pt.`date`
where code in ("AAA","BBB","CCC")
group by code
order by average desc;
如果子选择太慢,请使用后面的一些版本。
你绝对应该制作一个包含日历日的表格,并且他们会得到一个标记交易日的列。如果它们还包含30天前和90天前的参考,那将会容易得多。
create table calendar_days
(
id int(11) not null auto_increment primary key,
calday date not null,
is_trading tinyint,
trading_before_30 date,
trading_before_90 date
);
然后变得容易:
select pt.stockname, sum(pt.closing_price) / count(*) as avg_close
from calendar_days d
inner join pricetable pt on pt.day between d.calday and d.trading_before_30
where d.calday = '2015-08-15'
group by pt.stockname;
您可以从库存表中轻松填写该日历日表。
编辑:这样您就可以在第一天的请求中填写它,假设仅交易日在此表中。
insert into calendar_days (calday, is_trading)
select distinct day, 1
from pricetable pt
where pt.day > (select max(calday from calendar_days);
update calendar_days d1
inner join calendar_days d2 on d2.nr = d1.nr - 29
set d1.trading_before_30 = d2.calday
where d1.trading_before_30 is null;
您当然可以尝试动态构建您的stockprice表中最近30个交易日的列表,但该表每天有很多条目,因此这将是一个不必要的减慢您的查询 - 当天更改很少,每天只有一次。
您甚至可以在截止日期表中添加触发器,以便在每个插页上检查日历天是否需要重新填充。
没有该表的版本如下所示:
drop temporary table if exists tmp_days;
create temporary table tmp_days (tradingday date not null primary key);
insert into tmp_days
select distinct `day`
from pricetable
where day <= '2015-08-15'
order by day desc limit 30;
然后
select pt.stockname, sum(pt.price) / count(*) as average
from pricetable pt
inner join tmp_days d on d.tradingday = pt.day;
临时表只能在一个连接中显示。
答案 1 :(得分:0)
作为起点,请参阅https://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-add这些功能。应该像(未经测试):
SELECT `date`, ticker, avg(`close`) from TRADES where
date <= '2015-09-01' and date >= DATE_SUB('2015-09-01', INTERVAL 30 DAY)
GROUP BY ticker