Re: Need some tips on query generating averages on time series data
From: <tonkuma_at_fiberbit.net>
Date: Sat, 26 Oct 2013 03:29:25 -0700 (PDT)
Message-ID: <d562e4cc-c34f-4ef0-887f-93115f243e38_at_googlegroups.com>
So, I tried on DB2.
{code}
WITH
sample_data
( stock , timestamp_sec , quantity ) AS ( VALUES
)
, add_cum AS (
SELECT t.*
)
, cum_range AS (
SELECT cumulative
FROM cum_range AS c
INNER JOIN
add_cum AS s
AND b.cumulative >= c.cumulative
AND b.lag_cumul <= c.lag_cumul
GROUP BY
;
Date: Sat, 26 Oct 2013 03:29:25 -0700 (PDT)
Message-ID: <d562e4cc-c34f-4ef0-887f-93115f243e38_at_googlegroups.com>
On Wednesday, October 23, 2013 11:35:52 AM UTC+9, TomGar wrote:
> I need to generate average hold times for various stock of companies as follows: The data looks like: stock timestamp (sec) quantity ----- ---------------- --------- GOOG 12459.6 -100 <-- SELL GOOG 12634.0 +100 <-- BUY GOOG 12636.2 +200 GOOG 12464.8 -100 GOOG 12568.3 -300 GOOG 12678.0 +200 .... .... The rules are 1. begin and end day with balance 0 2. can short sell, i.e. can sell shares even if balance is currently 0 3. hold time is defined as number of seconds stock was held before it was sold 4. first stock purchased are sold first I need to generate the average hold times seconds per share. I'd prefer to do this using SQL and NOT a procedure. Any tips on how to go about calculating this? I have looked at various analytic functions, but still not sure. Thank you.I can't access Oracle.
So, I tried on DB2.
{code}
WITH
sample_data
( stock , timestamp_sec , quantity ) AS ( VALUES
( 'GOOG' , 12459.6 , -100 ) , ( 'GOOG' , 12464.8 , -100 ) , ( 'GOOG' , 12568.3 , -300 ) , ( 'GOOG' , 12634.0 , 100 ) , ( 'GOOG' , 12636.2 , 200 ) , ( 'GOOG' , 12678.0 , 200 )
)
, add_cum AS (
SELECT t.*
, LAG(cumulative , 1 , 0)
OVER( PARTITION BY sell_buy ORDER BY cumulative ) AS lag_cumul FROM (SELECT t.* , SUM( ABS(quantity) ) OVER( PARTITION BY SIGN(quantity) ORDER BY timestamp_sec ) AS cumulative , CASE SIGN(quantity) WHEN -1 THEN 'sell' ELSE 'buy' END AS sell_buy FROM sample_data AS t ) AS t
)
, cum_range AS (
SELECT cumulative
, LAG(cumulative , 1 , 0)
OVER( ORDER BY cumulative ) AS lag_cumul FROM (SELECT DISTINCT
cumulative FROM add_cum ) ) SELECT s.timestamp_sec AS time
, SIGN(1 - GROUPING(c.cumulative) * 2)
* SUM(c.lag_cumul - c.cumulative) AS qnt
, - c.cumulative AS cumul
, b.timestamp_sec - s.timestamp_sec AS hold_time
, DEC( SUM( (b.timestamp_sec - s.timestamp_sec)
* (c.cumulative - c.lag_cumul) ) , 15 , 1 ) AS weighted_hold_time
, CASE GROUPING(c.cumulative)
WHEN 1 THEN - DEC( SUM( (b.timestamp_sec - s.timestamp_sec) * (c.cumulative - c.lag_cumul) ) , 31 , 2 ) / SUM(c.lag_cumul - c.cumulative) END AS weighted_avg_hold_time
FROM cum_range AS c
INNER JOIN
add_cum AS s
ON s.sell_buy = 'sell' AND s.cumulative >= c.cumulative AND s.lag_cumul <= c.lag_cumul INNER JOIN add_cum AS b ON b.sell_buy = 'buy'
AND b.cumulative >= c.cumulative
AND b.lag_cumul <= c.lag_cumul
GROUP BY
ROLLUP ( ( c.cumulative , c.lag_cumul , s.timestamp_sec , b.timestamp_sec ) ) ORDER BY time
, cumul DESC
;
TIME QNT CUMUL HOLD_TIME WEIGHTED_HOLD_TIME WEIGHTED_AVG_HOLD_TIME
-------- ----------- ----------- --------- ------------------ --------------------------------- 12459.6 -100 -100 174.4 17440.0 - 12464.8 -100 -200 171.4 17140.0 - 12568.3 -100 -300 67.9 6790.0 - 12568.3 -200 -500 109.7 21940.0 - - 500 - - 63310.0 126.62
5 record(s) selected.
{code}
Received on Sat Oct 26 2013 - 12:29:25 CEST