Сгруппируйте данные OHLC-Stock Market по нескольким таймфреймам - Mysql

Мне нужно сгруппировать данные фондовой биржи "1мин" с {Name, DateTime, Open, High, Low, Close, Volume} в разные таймфреймы, т.е. «5 минут / 15 минут / 60 минут» на MYSQL. Схема построена на sqlfiddle - http://sqlfiddle.com/#!2/91433.

Я нашел ссылку - Сгруппируйте данные OHLC-Stockmarket в несколько таймфреймы с T-SQL с аналогичными требованиями для MSSQL.

Я попытался перейти по ссылке - http://briansteffens.com/2011/07/19/row_number-partition-and-over-in-mysql/, чтобы получить row_number () поверх раздела в mysql для решения проблемы.

Я новичок в sql, может ли кто-нибудь указать мне в правильном направлении?


person Sri    schedule 20.09.2012    source источник
comment
У вас действительно есть проблема, или вы просто констатируете, что уже сделали?   -  person Bojangles    schedule 21.09.2012
comment
@JamWaffles, спасибо, что разобрались с этим. У меня нет решения проблемы. Я хочу, чтобы SQL-запрос преобразовал 1-минутные данные ohlc в 5-минутные интервалы.   -  person Sri    schedule 21.09.2012


Ответы (4)


Я знаю, что это старый вопрос, но посмотрите на это гораздо «более простое» решение. Есть уловка для цены открытия и закрытия. Вам это может понравиться.

SELECT
  FLOOR(MIN(`timestamp`)/"+period+")*"+period+" AS timestamp,
  SUM(amount) AS volume,
  SUM(price*amount)/sum(amount) AS wavg_price,
  SUBSTRING_INDEX(MIN(CONCAT(`timestamp`, '_', price)), '_', -1) AS `open`,
  MAX(price) AS high,
  MIN(price) AS low,
  SUBSTRING_INDEX(MAX(CONCAT(`timestamp`, '_', price)), '_', -1) AS `close`
FROM transactions_history -- this table has 3 columns (timestamp, amount, price)
GROUP BY FLOOR(`timestamp`/"+period+")
ORDER BY timestamp  

период в секундах

person Andrej Mikulik    schedule 15.11.2013
comment
Отличная идея, чтобы избежать множественных запросов! Большое спасибо - person iMacTia; 25.11.2014
comment
что содержит period? это просто нить? - person Sisir; 25.05.2015
comment
Это было давно. Но когда я смотрю на это сейчас: это целое число / строка, предоставленная извне. В запросе использовалась строка, заключенная в. Stackoverflow удалил эти цитаты. Точка объединяется с остальной частью строки запроса ... т.е. с точки зрения SQL это константа. Вы можете поставить 300 вместо + точка +, и у вас будет жестко запрограммировано 5 минут. - person Andrej Mikulik; 01.06.2015

Наконец, проблема решена с помощью следующего запроса mysql:

select min(a.mydate),max(a.myhigh) as high,min(a.mylow) as low, 
min(case when rn_asc = 1 then a.myopen end) as open,
min(case when rn_desc = 1 then b.myclose end) as close

from( 

select 
@i := if((@lastdate) != (Floor(unix_timestamp(mydate)/300 )), 1, @i + 1) as rn_asc,
          mydate, myhigh, mylow, myopen, myclose,
          @lastdate := (Floor(unix_timestamp(mydate)/300 ))

from
  onemindata_1,
  (select @i := 0) vt1,
  (select @lastdate := null) vt2 order by mydate

) a

inner join(

select 
@j := if((@lastdate1) != (Floor(unix_timestamp(mydate)/300 )), 1, @j + 1) as rn_desc,
          mydate,myclose,
          @lastdate1 := (Floor(unix_timestamp(mydate)/300 ))

from
  onemindata_1,
  (select @j := 0) vt1,
  (select @lastdate1 := null) vt2 order by mydate desc

)b
on a.mydate=b.mydate
group by (Floor(unix_timestamp(a.mydate)/300 ))

Самой сложной задачей было получить открытие и закрытие для «определенных временных интервалов». Я делаю внутреннее соединение «максимум, минимум, открытие» с «закрытием» на «дату». Я могу переключать временные интервалы, изменяя знаменатель в (Floor (unix_timestamp (mydate) / 300)). На данный момент за производительность не парюсь, пока работает :).

person Sri    schedule 21.09.2012

Запрос содержит ошибку, измените MIN на MAX для цены закрытия:

SELECT
  FLOOR(MIN(`timestamp`)/"+period+")*"+period+" AS timestamp,
  SUM(amount) AS volume,
  SUM(price*amount)/sum(amount) AS wavg_price,
  SUBSTRING_INDEX(MIN(CONCAT(`timestamp`, '_', price)), '_', -1) AS `open`,
  MAX(price) AS high,
  MIN(price) AS low,
  SUBSTRING_INDEX(MAX(CONCAT(`timestamp`, '_', price)), '_', -1) AS `close`
FROM transactions_history -- this table has 3 columns (timestamp, amount, price)
GROUP BY FLOOR(`timestamp`/"+period+")
ORDER BY timestamp  
person Ruslan    schedule 12.08.2015

Я обнаружил, что решение @Ruslan не работает в последних версиях MySQL, поэтому разместите версию, которая работает:

select 
date_add(str_to_date(date_format(ev.startdatetime, '%Y-%m-%d'),'%Y-%m-%d'), interval 
 hour(ev.startdatetime)*60 + floor(minute(ev.startdatetime)/5)*5 minute) timeframe
 , sum(ev.volume) volume
 , min(ev.startdatetime) mintime
 , substring_index(group_concat(open),',',1) open
 , max(high) as high 
 , min(low) as low
 , substring_index(group_concat(close),',',-1) close
from es1min_v ev
group by 
date_add(str_to_date(date_format(ev.startdatetime, '%Y-%m-%d'),'%Y-%m-%d'), interval 
 hour(ev.startdatetime)*60 + floor(minute(ev.startdatetime)/5)*5 minute) 
person Oraculo    schedule 30.06.2020