2013-04-28 91 views
3

第一:此問題不重複。我已經在這裏問過這個問題了,它已經作爲一個副本關閉了。雖然它與stackoverflow上的其他線程類似,但它實際上要複雜得多。假設它是重複的,請先閱讀帖子:SQL - 計算變量長度上的變量移動平均數

我想用變量日期計算變量移動平均值交叉。

即:我想提示用戶輸入3個值和1個選項。輸入是通過Web前端,所以我可以根據輸入構建/編輯查詢,或者根據需要進行多個查詢。

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 

我有一個B樹索引:

daily_data(stock_id, date, adj_close) 

stock_id 

我被困在這個查詢,並有很多的麻煩寫它。如果變量是固定的,它看起來很平凡,但是因爲X,Y,Z都是100%彼此獨立的(例如,可以查看過去100天內的5日移動平均線或過去5日內的100日移動平均線)我在編碼時遇到了很多麻煩。

請幫忙! :(

編輯:我已經告訴一些情況下可能會有所幫助

我們正在創建一個開放式股票分析系統,用戶可以進行趨勢分析我有一個包含3500只股票和其價格的歷史數據庫追溯到1970年

這個查詢將每天運行,以便找到符合某些標準 例如股票:

10天超過20天移動平均線在5均線天

20天交叉UNDER 10日均線在5天內

55天交叉未滿22日均線在100天內

但是每個用戶可能感興趣的不同的分析,所以我不能只存儲每行的移動平均數,必須進行計算。

+0

你想要的任何機會,你可以發佈一個小數據集和輸出在一組參數下查詢? – 2013-04-28 20:37:58

+0

當然,即將推出... 樣本數據:http://zbt-psu.org/daily_data.zip – user1797484 2013-04-28 20:51:04

+0

用一些參數編輯上述問題。輸出=對於每個符合輸入參數的股票:股票的符號,兩個計算的移動平均線和股票的符號。在選定的時間內輸出每隻股票的每日價格歷史將會很不錯,但這不是必需的。 – user1797484 2013-04-28 20:54:36

回答

2

我不知道我是否完全理解這個問題......但這樣的事情可能會幫助你得到你需要去: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 

基於由@湯姆^ h這裏的答案:How do I calculate a moving average using MySQL?

+0

我也不明白這個問題,但是嘗試+1,它對我來說很好。我唯一的建議是使用OP的參數名稱(X,Y,Z和選項)更清晰。 – BellevueBob 2013-04-28 22:03:26

+0

好點@BellevueBob,編輯 – 2013-04-28 22:08:14

+0

伊恩:哇,很好的工作。這對我來說是正確的。不過,我試圖在20小時前跑步。它仍在運行....哈。 – user1797484 2013-04-29 19:59:16