Group OHLC-Stockmarket Data into multiple timeframes - Mysql

后端 未结 4 1373
死守一世寂寞
死守一世寂寞 2021-01-01 00:52

I need to group stockmarket \"1min\" data with {Name, DateTime, Open, High, Low, Close, Volume} into different timeframes ie. \"5mins/15mins/60mins\" on MYSQL. Schema built

相关标签:
4条回答
  • 2021-01-01 01:20

    I know this is an old question, but look at this much "simpler" solution. There is a trick for open and close price. You might like it.

    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  
    

    period is in seconds

    0 讨论(0)
  • 2021-01-01 01:21

    Finally resolved the issue with the following mysql query:

    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 ))
    

    Toughest part was to get the Open and Close for the "Specific Time Intervals". I am doing an inner join of 'high,low,open' with 'close' on 'date'. I can switch the time intervals by changing the denominator in (Floor(unix_timestamp(mydate)/300 )). Currently not worried about the performance as long as it works :).

    0 讨论(0)
  • 2021-01-01 01:28

    Query has error, change MIN to MAX for Close price:

    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  
    
    0 讨论(0)
  • 2021-01-01 01:30

    I found that the solution of @Ruslan doesn't work in latest versions of MySQL so posting a version that works:

    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) 
    
    0 讨论(0)
提交回复
热议问题