我想使用MS SQL Server 2014计算平均真实范围。
主表如下所示:
TIME BID-OPEN BID-HIGH BID-LOW BID-CLOSE
1993-05-09 21:00:00.000 1.5786 1.5786 1.5311 1.5346
1993-05-10 21:00:00.000 1.5346 1.5551 1.5326 1.5391
1993-05-11 21:00:00.000 1.5391 1.5521 1.5299 1.5306
1993-05-12 21:00:00.000 1.5306 1.5451 1.5106 1.5256
1993-05-13 21:00:00.000 1.5256 1.5416 1.5211 1.5361
1993-05-16 21:00:00.000 1.5361 1.5534 1.5318 1.5361
1993-05-17 21:00:00.000 1.5361 1.5451 1.5243 1.5361
1993-05-18 21:00:00.000 1.5361 1.5506 1.5316 1.5431
1993-05-19 21:00:00.000 1.5431 1.5686 1.5391 1.5566
1993-05-20 21:00:00.000 1.5566 1.5665 1.5401 1.5481
1993-05-23 21:00:00.000 1.5481 1.5481 1.5221 1.5356
1993-05-24 21:00:00.000 1.5356 1.5491 1.5341 1.5436
1993-05-25 21:00:00.000 1.5436 1.5567 1.5421 1.5476
1993-05-26 21:00:00.000 1.5476 1.5656 1.5421 1.5621
1993-05-27 21:00:00.000 1.5621 1.5714 1.5546 1.5621
1993-05-30 21:00:00.000 1.5621 1.5631 1.5571 1.5621
1993-05-31 21:00:00.000 1.5621 1.5706 1.5421 1.5611
1993-06-01 21:00:00.000 1.5611 1.5611 1.5341 1.5341
1993-06-02 21:00:00.000 1.5341 1.5526 1.5341 1.5411
1993-06-03 21:00:00.000 1.5411 1.5566 1.5071 1.5081
1993-06-06 21:00:00.000 1.5081 1.5306 1.5071 1.5246
1993-06-07 21:00:00.000 1.5246 1.5306 1.5142 1.5221
1993-06-08 21:00:00.000 1.5221 1.5271 1.5076 1.5148
1993-06-09 21:00:00.000 1.5148 1.5326 1.5016 1.5301
1993-06-10 21:00:00.000 1.5301 1.5401 1.5056 1.5231
1993-06-13 21:00:00.000 1.5231 1.5331 1.5226 1.5281
1993-06-14 21:00:00.000 1.5281 1.5391 1.5151 1.5171
1993-06-15 21:00:00.000 1.5171 1.5283 1.4991 1.5063
1993-06-16 21:00:00.000 1.5063 1.5186 1.4994 1.5153
1993-06-17 21:00:00.000 1.5153 1.5171 1.4901 1.4941
1993-06-20 21:00:00.000 1.4941 1.4988 1.4808 1.4888
1993-06-21 21:00:00.000 1.4888 1.4911 1.4751 1.4788
1993-06-22 21:00:00.000 1.4788 1.4846 1.4681 1.4715
1993-06-23 21:00:00.000 1.4715 1.4776 1.4645 1.4704
1993-06-24 21:00:00.000 1.4704 1.4886 1.4661 1.4806
计算真实范围的当前查询输出为:
Time H-L H-Cp L-Cp TR
1993-05-09 21:00:00.000 0.0475 NULL NULL 0.0475
1993-05-10 21:00:00.000 0.0225 0.0205 0.002 0.0225
1993-05-11 21:00:00.000 0.0222 0.013 0.0092 0.0222
1993-05-12 21:00:00.000 0.0345 0.0145 0.02 0.0345
1993-05-13 21:00:00.000 0.0205 0.016 0.0045 0.0205
1993-05-16 21:00:00.000 0.0216 0.0173 0.0043 0.0216
1993-05-17 21:00:00.000 0.0208 0.009 0.0118 0.0208
1993-05-18 21:00:00.000 0.019 0.0145 0.0045 0.019
1993-05-19 21:00:00.000 0.0295 0.0255 0.004 0.0295
1993-05-20 21:00:00.000 0.0264 0.0099 0.0165 0.0264
1993-05-23 21:00:00.000 0.026 0 0.026 0.026
1993-05-24 21:00:00.000 0.015 0.0135 0.0015 0.015
1993-05-25 21:00:00.000 0.0146 0.0131 0.0015 0.0146
1993-05-26 21:00:00.000 0.0235 0.018 0.0055 0.0235
1993-05-27 21:00:00.000 0.0168 0.0093 0.0075 0.0168
1993-05-30 21:00:00.000 0.006 0.001 0.005 0.006
1993-05-31 21:00:00.000 0.0285 0.0085 0.02 0.0285
1993-06-01 21:00:00.000 0.027 0 0.027 0.027
1993-06-02 21:00:00.000 0.0185 0.0185 0 0.0185
1993-06-03 21:00:00.000 0.0495 0.0155 0.034 0.0495
1993-06-06 21:00:00.000 0.0235 0.0225 0.001 0.0235
1993-06-07 21:00:00.000 0.0164 0.006 0.0104 0.0164
1993-06-08 21:00:00.000 0.0195 0.005 0.0145 0.0195
1993-06-09 21:00:00.000 0.031 0.0178 0.0132 0.031
1993-06-10 21:00:00.000 0.0345 0.01 0.0245 0.0345
1993-06-13 21:00:00.000 0.0105 0.01 0.0005 0.0105
1993-06-14 21:00:00.000 0.024 0.011 0.013 0.024
1993-06-15 21:00:00.000 0.0292 0.0112 0.018 0.0292
1993-06-16 21:00:00.000 0.0192 0.0123 0.0069 0.0192
1993-06-17 21:00:00.000 0.027 0.0018 0.0252 0.027
1993-06-20 21:00:00.000 0.018 0.0047 0.0133 0.018
1993-06-21 21:00:00.000 0.016 0.0023 0.0137 0.016
1993-06-22 21:00:00.000 0.0165 0.0058 0.0107 0.0165
1993-06-23 21:00:00.000 0.0131 0.0061 0.007 0.0131
1993-06-24 21:00:00.000 0.0225 0.0182 0.0043 0.0225
使用此SQL查询:(感谢Lad2025)
WITH cte AS
(
SELECT
t.[Time]
,[H-L] = Round([BID-HIGH]-[BID-LOW],5)
,[H-Cp] = Abs(Round([BID-HIGH]-[prev_BID-CLOSE],5))
,[L-Cp] = Abs(Round([BID-LOW]-[prev_BID-CLOSE],5))
FROM (SELECT *,
[prev_BID-CLOSE] = LAG([BID-CLOSE]) OVER(ORDER BY [Time])
FROM [#tbl_GBP-USD_1-Day]) AS t
)
SELECT *
FROM cte
CROSS APPLY (SELECT MAX(v) AS v
FROM ( VALUES ([H-L]),([H-Cp]),([L-Cp])) AS value(v)
) AS sub([TR]);
#
以下示例ATR查询是10天ATR(平均真实范围)。
正如您所看到的,前9行是空白的,因为这些数据需要计算前10天的平均值[TR]。然后,第一次ATR计算后的每一行是最后[TR] 10天的平均值,依此类推。
TIME H-L H-Cp L-Cp TR ATR
1993/05/09 21:00:00.000 0.0475 NULL NULL 0.0475
1993/05/10 21:00:00.000 0.0225 0.0205 0.002 0.0225
1993/05/11 21:00:00.000 0.0222 0.013 0.0092 0.0222
1993/05/12 21:00:00.000 0.0345 0.0145 0.02 0.0345
1993/05/13 21:00:00.000 0.0205 0.016 0.0045 0.0205
1993/05/16 21:00:00.000 0.0216 0.0173 0.0043 0.0216
1993/05/17 21:00:00.000 0.0208 0.009 0.0118 0.0208
1993/05/18 21:00:00.000 0.019 0.0145 0.0045 0.019
1993/05/19 21:00:00.000 0.0295 0.0255 0.004 0.0295
1993/05/20 21:00:00.000 0.0264 0.0099 0.0165 0.0264 0.02645
1993/05/23 21:00:00.000 0.026 0 0.026 0.026 0.0243
1993/05/24 21:00:00.000 0.015 0.0135 0.0015 0.015 0.02355
1993/05/25 21:00:00.000 0.0146 0.0131 0.0015 0.0146 0.02279
1993/05/26 21:00:00.000 0.0235 0.018 0.0055 0.0235 0.02169
1993/05/27 21:00:00.000 0.0168 0.0093 0.0075 0.0168 0.02132
1993/05/30 21:00:00.000 0.006 0.001 0.005 0.006 0.01976
1993/05/31 21:00:00.000 0.0285 0.0085 0.02 0.0285 0.02053
1993/06/01 21:00:00.000 0.027 0 0.027 0.027 0.02133
1993/06/02 21:00:00.000 0.0185 0.0185 0 0.0185 0.02023
1993/06/03 21:00:00.000 0.0495 0.0155 0.034 0.0495 0.02254
1993/06/06 21:00:00.000 0.0235 0.0225 0.001 0.0235 0.02229
1993/06/07 21:00:00.000 0.0164 0.006 0.0104 0.0164 0.02243
1993/06/08 21:00:00.000 0.0195 0.005 0.0145 0.0195 0.02292
1993/06/09 21:00:00.000 0.031 0.0178 0.0132 0.031 0.02367
1993/06/10 21:00:00.000 0.0345 0.01 0.0245 0.0345 0.02544
1993/06/13 21:00:00.000 0.0105 0.01 0.0005 0.0105 0.02589
1993/06/14 21:00:00.000 0.024 0.011 0.013 0.024 0.02544
1993/06/15 21:00:00.000 0.0292 0.0112 0.018 0.0292 0.02566
1993/06/16 21:00:00.000 0.0192 0.0123 0.0069 0.0192 0.02573
1993/06/17 21:00:00.000 0.027 0.0018 0.0252 0.027 0.02348
1993/06/20 21:00:00.000 0.018 0.0047 0.0133 0.018 0.02293
1993/06/21 21:00:00.000 0.016 0.0023 0.0137 0.016 0.02289
1993/06/22 21:00:00.000 0.0165 0.0058 0.0107 0.0165 0.02259
1993/06/23 21:00:00.000 0.0131 0.0061 0.007 0.0131 0.0208
1993/06/24 21:00:00.000 0.0225 0.0182 0.0043 0.0225 0.0196
进一步扩大。
[H-L] = High (minus) Low,
[H-Cp] = High (Minus) Previous Day Close,
[L-Cp] = Low (Minus) Previous Day Close
[TR] = MAX Value of [H-L],[H-Cp],[L-Cp]
[ATR] = Average of TR over X amount of days
X in this case is 10 days
我需要一些SQL语句添加到上面的当前TR查询代码中。
谢谢你的帮助!
答案 0 :(得分:1)
这样的事情可能会这样做,使用与TR相同的方法:
WITH cteRange AS (
SELECT
t.[Time],
Round(t.[BID-HIGH]-t.[BID-LOW],5) AS [H-L],
Abs(Round(t.[BID-HIGH]-t.[prev_BID-CLOSE],5)) AS [H-Cp],
Abs(Round(t.[BID-LOW]-t.[prev_BID-CLOSE],5)) AS [L-Cp]
FROM (
SELECT *, [prev_BID-CLOSE] = LAG([BID-CLOSE]) OVER (ORDER BY [Time])
FROM [#tbl_GBP-USD_1-Day]
) AS t
), cteTrueRange AS (
SELECT *
FROM cteRange
CROSS APPLY (
SELECT MAX(v) AS v
FROM (VALUES ([H-L]), ([H-Cp]), ([L-Cp])) AS value(v)
) AS sub([TR])
), cteTrueRange10 AS (
SELECT
*,
LAG([TR], 1) OVER (ORDER BY [Time]) AS [TR1],
LAG([TR], 2) OVER (ORDER BY [Time]) AS [TR2],
LAG([TR], 3) OVER (ORDER BY [Time]) AS [TR3],
LAG([TR], 4) OVER (ORDER BY [Time]) AS [TR4],
LAG([TR], 5) OVER (ORDER BY [Time]) AS [TR5],
LAG([TR], 6) OVER (ORDER BY [Time]) AS [TR6],
LAG([TR], 7) OVER (ORDER BY [Time]) AS [TR7],
LAG([TR], 8) OVER (ORDER BY [Time]) AS [TR8],
LAG([TR], 9) OVER (ORDER BY [Time]) AS [TR9]
FROM cteTrueRange
)
SELECT [Time], [H-L], [H-Cp], [L-Cp], [TR], [TRA]
FROM cteTrueRange10
CROSS APPLY (
SELECT CASE WHEN [TR9] IS NOT NULL THEN AVG(v) END AS v
FROM (VALUES ([TR]), ([TR1]), ([TR2]), ([TR3]), ([TR4]), ([TR5]), ([TR6]), ([TR7]), ([TR8]), ([TR9])) AS value(v)
) AS sub([TRA]);
在这里,评论中解释了另一个解决方案,你可以在任何天数内平均得分(在这种情况下为100):
WITH cteRange AS (
SELECT
t.[Time],
ROUND(t.[BID-HIGH]-t.[BID-LOW],5) AS [H-L],
ABS(ROUND(t.[BID-HIGH]-t.[prev_BID-CLOSE],5)) AS [H-Cp],
ABS(ROUND(t.[BID-LOW]-t.[prev_BID-CLOSE],5)) AS [L-Cp]
FROM (
SELECT *, [prev_BID-CLOSE] = LAG(u.[BID-CLOSE]) OVER (ORDER BY u.[Time])
FROM [#tbl_GBP-USD_1-Day] u
) AS t
), cteTrueRange AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY [time]) AS ix
FROM cteRange
CROSS APPLY (
SELECT MAX(v) AS v
FROM (VALUES ([H-L]), ([H-Cp]), ([L-Cp])) AS value(v)
) AS sub([TR])
)
SELECT t.[Time], t.[H-L], t.[H-Cp], t.[L-Cp], t.[TR], CASE WHEN LAG(t.[TR], 100) OVER (ORDER BY t.[time]) IS NOT NULL THEN (
SELECT ROUND(AVG([TR]), 5) FROM cteTrueRange t2 WHERE (t2.ix > t.ix-100) AND (t2.ix <= t.ix)
) END AS [TRA]
FROM cteTrueRange t;
这里的LAG([TR], 100)
调用用于阻止平均值忽略NULL
- AVG()
的正常行为只是忽略空值,这不符合您为此返回null的要求前n-1天。
答案 1 :(得分:0)
以上答案是正确的。但是,此处计算 ATR 的方式不正确。真实范围计算很好,但 ATR 的公式(在本例中为 14 天)是:
ATR = [(之前的 ATR* x 13) + 当前的 TR] / 14
*第一个 ATR 使用过去 14 天“真实范围”的简单移动平均线 (SMA))
如您所见,它有点复杂。
我知道这是旧的,但我想我会在任何人(其他人)使用它进行分析之前更正计算。