用julialang进行KD,MACD指标的计算

2020-11-28  本文已影响0人  昵称违法

最近发现我用julialang写的KD指标和通达信计算的指标不一致,主要体现在初始的近30个值,有偏差。

于是我在通达信公式编辑器里,自己编制了几个指标,用于计算对比。

如下是我定制的两个指标:CLOSE_SMA 和 CLOSE_EMA

SMA和EMA指标

我在KD指标的基础上,放出两个新的指标,用于数据导出和图形观察,如图:


EMA和SMA指标观察

导出的数据,并用julialang计算相同的指标,用于观察是否计算正确,下图是计算结果。


通达信计算的指标和julialang计算的指标

总结:talib包里面有各种指标,但是与通达信的指标对比的时候,有出入。主要原因在于初始值的赋值,还有就是各种MA指标的计算有差异,比如talib.SMA与通达信的SMA有明显区别。

对于初学者,建议自己实现代码,如果要引用talib包的函数,也需要仔细对比。我给出一些对比方法:在通达信里面自己建立要核对的指标,导出数据后,用julialang读入数据并计算指标,然后plot观察,或者导出数据观察。

====用到的代码,欢迎大家指正====

"""
功能:计算EMA(X,N),求N周期X值计算指数加权移动平均(平滑移动平均)
计算的依据:通达信,东方财富,文化函数

输入:
X::Array{Float64,1} 要计算的系列
N::Int64 权重

输出:
Array{Float64,1}
"""
function EMA(X::Array{Float64,1}, N::Int64)
    Y = 0.0
    res = Array{Float64,1}(undef, length(X))

    #第一个初始值的计算
    res[1] = X[1]
    Y = X[1]

    #第二个值到结束的计算
    for (i, x) in zip(2:length(X), X[2:end])
        Y = (2 * x + (N - 1) * Y) / (N + 1)
        res[i] = Y
    end
    return res
end # function

"""
功能:计算MACD指标
计算的依据:通达信,东方财富,文化函数

输入:
CLOSE::Array{Float64,1}:收盘价系列
SHORT(短期):Int64
LONG(长期):Int64
M天数:Int64
一般而言:SHORT,LONG,M = 12、26、9

输出:
DIFF线 收盘价短期、长期指数平滑移动平均线间的差
DEA线 DIFF线的M日指数平滑移动平均线
MACD线 DIFF线与DEA线的差
"""
function MACD(CLOSE::Array{Float64,1},SHORT::Int64,LONG::Int64,MID::Int64)
    DIF = EMA(CLOSE,SHORT) .- EMA(CLOSE,LONG)
    DEA = EMA(DIF,MID)
    MACD = (DIF .- DEA) * 2
    return(dif = DIF,dea = DEA,macd = MACD)
end # function

"""
功能:通达信版本的SMA函数
SMA(X,N,M) 求X的N个周期内的扩展指数加权移动平均。M为权重。
输出:Array{Float64,1}
编写依据:文华函数文档
"""
function SMA(X::Array{Float64,1}, N::Int64, M::Int64)
    res = Array{Float64,1}(undef, length(X))
    Y::Float64 = 0.0

    #第一初始值
    res[1] = X[1]
    Y = X[1]

    #第二个值到结束的计算
    for (i, x) in zip(2:length(X), X[2:end])  #从第二个开始处理
        Y = (M * x + (N - M) * Y) / N
        res[i] = Y
    end
    return res
end

"""
给定一个系列ary,求N个窗口周期内的最大值,N包含当前数据
"""
function HHV(ary, N)
    res = Array{Float64,1}(undef, length(ary))
    for (idx, item) in zip(1:length(ary), ary)
        if idx <= N
            res[idx] = maximum(@view ary[1:idx])
        elseif idx > N
            res[idx] = maximum(@view ary[idx-N+1:idx])
        end
    end
    res
end # function

"""
给定一个系列ary,求N个窗口周期内的最小值,N包含当前数据
"""
function LLV(ary, N)
    res = Array{Float64,1}(undef, length(ary))
    for (idx, item) in zip(1:length(ary), ary)
        if idx <= N
            res[idx] = minimum(@view ary[1:idx])
        elseif idx > N
            res[idx] = minimum(@view ary[idx-N+1:idx])
        end
    end
    res
end # function

"""
计算KD指标
输入:CLOSE,LOW,HIGH,N,M1,M2
输出:K,D
"""
function KD(CLOSE, LOW, HIGH, N, M1, M2)
    RSV = (CLOSE .- LLV(LOW, N)) ./ (HHV(HIGH, N) .- LLV(LOW, N)) .* 100
    K = SMA(RSV, M1, 1)
    D = SMA(K, M2, 1)
    return (K = K, D = D)
end # function
上一篇下一篇

猜你喜欢

热点阅读