QUANTAXIS指标系统

In [306]:
import QUANTAXIS as QA
import pandas as pd
import numpy as np
  • 源码目录:QUANTAXIS/QUANTAXIS/QAIndicator/base.py
In [170]:
# 配置数据
t = QA.QA_fetch_stock_day_adv('000948','2021-07-20','2021-09-01').close
print(t.index)
t
MultiIndex([('2021-07-20', '000948'),
            ('2021-07-21', '000948'),
            ('2021-07-22', '000948'),
            ('2021-07-23', '000948'),
            ('2021-07-26', '000948'),
            ('2021-07-27', '000948'),
            ('2021-07-28', '000948'),
            ('2021-07-29', '000948'),
            ('2021-07-30', '000948'),
            ('2021-08-02', '000948'),
            ('2021-08-03', '000948'),
            ('2021-08-04', '000948'),
            ('2021-08-05', '000948'),
            ('2021-08-06', '000948'),
            ('2021-08-09', '000948'),
            ('2021-08-10', '000948'),
            ('2021-08-11', '000948'),
            ('2021-08-12', '000948'),
            ('2021-08-13', '000948'),
            ('2021-08-16', '000948'),
            ('2021-08-17', '000948'),
            ('2021-08-18', '000948'),
            ('2021-08-19', '000948'),
            ('2021-08-20', '000948'),
            ('2021-08-23', '000948'),
            ('2021-08-24', '000948'),
            ('2021-08-25', '000948'),
            ('2021-08-26', '000948'),
            ('2021-08-27', '000948'),
            ('2021-08-30', '000948'),
            ('2021-08-31', '000948'),
            ('2021-09-01', '000948')],
           names=['date', 'code'])
Out[170]:
date        code  
2021-07-20  000948    11.98
2021-07-21  000948    12.03
2021-07-22  000948    12.11
2021-07-23  000948    11.69
2021-07-26  000948    11.11
2021-07-27  000948    11.08
2021-07-28  000948    10.73
2021-07-29  000948    10.90
2021-07-30  000948    11.20
2021-08-02  000948    11.41
2021-08-03  000948    11.68
2021-08-04  000948    11.68
2021-08-05  000948    11.47
2021-08-06  000948    11.61
2021-08-09  000948    11.67
2021-08-10  000948    11.62
2021-08-11  000948    11.58
2021-08-12  000948    11.87
2021-08-13  000948    12.08
2021-08-16  000948    12.54
2021-08-17  000948    12.09
2021-08-18  000948    12.38
2021-08-19  000948    12.24
2021-08-20  000948    12.19
2021-08-23  000948    12.22
2021-08-24  000948    12.00
2021-08-25  000948    11.92
2021-08-26  000948    11.83
2021-08-27  000948    12.46
2021-08-30  000948    12.61
2021-08-31  000948    13.04
2021-09-01  000948    13.24
Name: close, dtype: float64

基础类指标 [基本和同花顺/通达信一致]

  • Series 类
    • 以DataFrame为输入的基础函数
    • return pd.Series format

QA.MA(Series, N)

In [155]:
def MA(Series, N):    
    return pd.Series.rolling(Series, N).mean()
  • 移动平均线,Moving Average,简称 MA
  • MA是用统计分析的方法,将一定时期内的证券价格(指数)加以平均,并把不同时间的平均值连接起来,形成一根MA
    • 用以观察证券价格变动趋势的一种技术指标
    • 帮助交易者确认现有趋势、判断将出现的趋势、发现过度延生即将反转的趋势
  • 移动平均线常用线有5天、10天、30天、60天、120天和240天的指标
  • 其中
    • 5天和10天的短期移动平均线,是短线操作的参照指标,称做日均线指标
    • 30天和60天的是中期均线指标,称做季均线指标
    • 120天、240天的是长期均线指标,称做年均线指标
    • 人们认为,移动平均线,“线”是支撑或阻挡价格的有力标准
      • 价格应自移动平均线反弹
      • 若未反弹而突破,那么它应继续在该方向上发展,直至其找到能够保持的新水平面
In [79]:
QA.MA(t,5)
Out[79]:
date        code  
2021-07-20  000948       NaN
2021-07-21  000948       NaN
2021-07-22  000948       NaN
2021-07-23  000948       NaN
2021-07-26  000948    11.784
2021-07-27  000948    11.604
2021-07-28  000948    11.344
2021-07-29  000948    11.102
2021-07-30  000948    11.004
2021-08-02  000948    11.064
2021-08-03  000948    11.184
2021-08-04  000948    11.374
2021-08-05  000948    11.488
2021-08-06  000948    11.570
2021-08-09  000948    11.622
2021-08-10  000948    11.610
2021-08-11  000948    11.590
2021-08-12  000948    11.670
2021-08-13  000948    11.764
2021-08-16  000948    11.938
2021-08-17  000948    12.032
2021-08-18  000948    12.192
2021-08-19  000948    12.266
2021-08-20  000948    12.288
2021-08-23  000948    12.224
2021-08-24  000948    12.206
2021-08-25  000948    12.114
2021-08-26  000948    12.032
2021-08-27  000948    12.086
2021-08-30  000948    12.164
2021-08-31  000948    12.372
2021-09-01  000948    12.636
Name: close, dtype: float64

QA.EMA(Series, N)

In [69]:
def EMA(Series, N):
    return pd.Series.ewm(Series, span=N, min_periods=N - 1, adjust=True).mean()
  • Exponential Moving Average
  • An exponential moving average (EMA) is a type of moving average (MA) that places a greater weight and significance on the most recent data points.
    • 指数移动平均指标,是一种移动平均指标,它给予最近的数据以更大的权重和重要性
  • The exponential moving average is also referred to as the exponentially weighted moving average.
    • 该指标也被称为加权移动平均指标
  • An exponentially weighted moving average reacts more significantly to recent price changes than a simple moving average (SMA), which applies an equal weight to all observations in the period.
    • 相对于简单移动平均指标加权移动平均指标对最近的价格变化有着显著的反应,简单移动平均指标对于每一个观察期都给予相同的权重。
  • 用途
    • 当要比较数值与均价的关系时,用 MA 就可以了
    • 而要比较均价的趋势快慢时,用 EMA 更稳定
    • 有时,在均价值不重要时,也用 EMA 来平滑和美观曲线
$$EMA_{today} = α * Price_{today} + ( 1 - α ) * EMA_{yesterday}$$
  • 其中
    • α 为平滑指数,一般取作2/(N+1)
    • 在计算 MACD 指标时,EMA计算中的 N 一般选取12和26天,因此 α 相应为 2/13 和 2/27
$$EMA_{today} = (\frac{Smoothing}{1+Days}) * Price_{today} + ( 1 - (\frac{Smoothing}{1+Days}) ) * EMA_{yesterday}$$
  • While there are many possible choices for the smoothing factor, the most common choice is:
    • Smoothing = 2
    • That gives the most recent observation more weight.
    • If the smoothing factor is increased, more recent observations have more influence on the EMA.
    • smoothing factor typically follows the formula: [2 ÷ (number of observations + 1)].
      • For a 20-day moving average, the multiplier would be [2/(20+1)] = 0.0952
In [80]:
QA.EMA(t,12)
Out[80]:
date        code  
2021-07-20  000948          NaN
2021-07-21  000948          NaN
2021-07-22  000948          NaN
2021-07-23  000948          NaN
2021-07-26  000948          NaN
2021-07-27  000948          NaN
2021-07-28  000948          NaN
2021-07-29  000948          NaN
2021-07-30  000948          NaN
2021-08-02  000948          NaN
2021-08-03  000948    11.359654
2021-08-04  000948    11.416610
2021-08-05  000948    11.425881
2021-08-06  000948    11.457231
2021-08-09  000948    11.492873
2021-08-10  000948    11.513882
2021-08-11  000948    11.524685
2021-08-12  000948    11.580574
2021-08-13  000948    11.660763
2021-08-16  000948    11.800994
2021-08-17  000948    11.846830
2021-08-18  000948    11.930989
2021-08-19  000948    11.979571
2021-08-20  000948    12.012543
2021-08-23  000948    12.044957
2021-08-24  000948    12.037950
2021-08-25  000948    12.019602
2021-08-26  000948    11.990158
2021-08-27  000948    12.063015
2021-08-30  000948    12.147731
2021-08-31  000948    12.285781
2021-09-01  000948    12.433287
Name: close, dtype: float64

QA.SMA(Series, N, M=1)

In [109]:
def SMA(Series, N, M=1):
    """
    威廉SMA算法
    本次修正主要是对于返回值的优化,现在的返回值会带上原先输入的索引index
    2018/5/3
    @yutiansut
    """
    ret = []
    # 循环是从 1 开始(而不是从 0 开始)
    i = 1
    length = len(Series)
    # 跳过X中前面几个 nan 值
    # 如果遇到空值,跳过,进入下一个 i
    while i < length:
        if np.isnan(Series.iloc[i]):
            i += 1
        else:
            break
    # 前值,就使用非空的当前第一个值
    preY = Series.iloc[i]  # Y'
    # 追加到 list 中
    ret.append(preY)
    while i < length:
        # M/N 作为平滑系数,加在当前值之上, 而 (N - M)/N ,加在前值之上
        Y = (M * Series.iloc[i] + (N - M) * preY) / float(N)
        # 最新值追加到list尾部
        ret.append(Y)
        # 最新值赋值给前值,用于下一次计算(在 i+1 之后,产生新的最新值)
        preY = Y
        i += 1
    return pd.Series(ret, index=Series.tail(len(ret)).index)
In [110]:
SMA(t, 5, M=0.75)
Out[110]:
date        code  
2021-07-20  000948    12.030000
2021-07-21  000948    12.030000
2021-07-22  000948    12.042000
2021-07-23  000948    11.989200
2021-07-26  000948    11.857320
2021-07-27  000948    11.740722
2021-07-28  000948    11.589114
2021-07-29  000948    11.485747
2021-07-30  000948    11.442885
2021-08-02  000948    11.437952
2021-08-03  000948    11.474259
2021-08-04  000948    11.505120
2021-08-05  000948    11.499852
2021-08-06  000948    11.516374
2021-08-09  000948    11.539418
2021-08-10  000948    11.551506
2021-08-11  000948    11.555780
2021-08-12  000948    11.602913
2021-08-13  000948    11.674476
2021-08-16  000948    11.804304
2021-08-17  000948    11.847159
2021-08-18  000948    11.927085
2021-08-19  000948    11.974022
2021-08-20  000948    12.006419
2021-08-23  000948    12.038456
2021-08-24  000948    12.032688
2021-08-25  000948    12.015784
2021-08-26  000948    11.987917
2021-08-27  000948    12.058729
2021-08-30  000948    12.141420
2021-08-31  000948    12.276207
2021-09-01  000948    12.420776
dtype: float64

QA.DIFF(Series, N=1)

In [128]:
# 当前值与前 N 个位置的值得差
def DIFF(Series, N=1):
    return pd.Series(Series).diff(N)
In [113]:
DIFF(t,N=1)
Out[113]:
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948   -0.42
2021-07-26  000948   -0.58
2021-07-27  000948   -0.03
2021-07-28  000948   -0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948   -0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948   -0.05
2021-08-11  000948   -0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948   -0.45
2021-08-18  000948    0.29
2021-08-19  000948   -0.14
2021-08-20  000948   -0.05
2021-08-23  000948    0.03
2021-08-24  000948   -0.22
2021-08-25  000948   -0.08
2021-08-26  000948   -0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
Name: close, dtype: float64

QA.HHV(Series, N)

In [54]:
# rolling表示滑动窗口,即滑动N个位置,作为窗口,计算 max()
def HHV(Series, N):
    return pd.Series(Series).rolling(N).max()
In [114]:
HHV(t,2)
Out[114]:
date        code  
2021-07-20  000948      NaN
2021-07-21  000948    12.03
2021-07-22  000948    12.11
2021-07-23  000948    12.11
2021-07-26  000948    11.69
2021-07-27  000948    11.11
2021-07-28  000948    11.08
2021-07-29  000948    10.90
2021-07-30  000948    11.20
2021-08-02  000948    11.41
2021-08-03  000948    11.68
2021-08-04  000948    11.68
2021-08-05  000948    11.68
2021-08-06  000948    11.61
2021-08-09  000948    11.67
2021-08-10  000948    11.67
2021-08-11  000948    11.62
2021-08-12  000948    11.87
2021-08-13  000948    12.08
2021-08-16  000948    12.54
2021-08-17  000948    12.54
2021-08-18  000948    12.38
2021-08-19  000948    12.38
2021-08-20  000948    12.24
2021-08-23  000948    12.22
2021-08-24  000948    12.22
2021-08-25  000948    12.00
2021-08-26  000948    11.92
2021-08-27  000948    12.46
2021-08-30  000948    12.61
2021-08-31  000948    13.04
2021-09-01  000948    13.24
Name: close, dtype: float64

QA.LLV(Series, N)

In [55]:
# rolling表示滑动窗口,即滑动N个位置,作为窗口,计算 min()
def LLV(Series, N):
    return pd.Series(Series).rolling(N).min()
In [119]:
LLV(t,3)
Out[119]:
date        code  
2021-07-20  000948      NaN
2021-07-21  000948      NaN
2021-07-22  000948    11.98
2021-07-23  000948    11.69
2021-07-26  000948    11.11
2021-07-27  000948    11.08
2021-07-28  000948    10.73
2021-07-29  000948    10.73
2021-07-30  000948    10.73
2021-08-02  000948    10.90
2021-08-03  000948    11.20
2021-08-04  000948    11.41
2021-08-05  000948    11.47
2021-08-06  000948    11.47
2021-08-09  000948    11.47
2021-08-10  000948    11.61
2021-08-11  000948    11.58
2021-08-12  000948    11.58
2021-08-13  000948    11.58
2021-08-16  000948    11.87
2021-08-17  000948    12.08
2021-08-18  000948    12.09
2021-08-19  000948    12.09
2021-08-20  000948    12.19
2021-08-23  000948    12.19
2021-08-24  000948    12.00
2021-08-25  000948    11.92
2021-08-26  000948    11.83
2021-08-27  000948    11.83
2021-08-30  000948    11.83
2021-08-31  000948    12.46
2021-09-01  000948    12.61
Name: close, dtype: float64

QA.SUM(Series, N)

In [117]:
# rolling表示滑动窗口,即滑动N个位置,作为窗口,计算 sum()
def SUM(Series, N):
    return pd.Series.rolling(Series, N).sum()
In [116]:
SUM(t,3)
Out[116]:
date        code  
2021-07-20  000948      NaN
2021-07-21  000948      NaN
2021-07-22  000948    36.12
2021-07-23  000948    35.83
2021-07-26  000948    34.91
2021-07-27  000948    33.88
2021-07-28  000948    32.92
2021-07-29  000948    32.71
2021-07-30  000948    32.83
2021-08-02  000948    33.51
2021-08-03  000948    34.29
2021-08-04  000948    34.77
2021-08-05  000948    34.83
2021-08-06  000948    34.76
2021-08-09  000948    34.75
2021-08-10  000948    34.90
2021-08-11  000948    34.87
2021-08-12  000948    35.07
2021-08-13  000948    35.53
2021-08-16  000948    36.49
2021-08-17  000948    36.71
2021-08-18  000948    37.01
2021-08-19  000948    36.71
2021-08-20  000948    36.81
2021-08-23  000948    36.65
2021-08-24  000948    36.41
2021-08-25  000948    36.14
2021-08-26  000948    35.75
2021-08-27  000948    36.21
2021-08-30  000948    36.90
2021-08-31  000948    38.11
2021-09-01  000948    38.89
Name: close, dtype: float64

QA.ABS(Series)

In [121]:
# 取绝对值,消除方向性带来的误差
def ABS(Series):
    return abs(Series)
In [120]:
t2=DIFF(t,N=1)
print(t2)
ABS(t2)
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948   -0.42
2021-07-26  000948   -0.58
2021-07-27  000948   -0.03
2021-07-28  000948   -0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948   -0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948   -0.05
2021-08-11  000948   -0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948   -0.45
2021-08-18  000948    0.29
2021-08-19  000948   -0.14
2021-08-20  000948   -0.05
2021-08-23  000948    0.03
2021-08-24  000948   -0.22
2021-08-25  000948   -0.08
2021-08-26  000948   -0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
Name: close, dtype: float64
Out[120]:
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948    0.42
2021-07-26  000948    0.58
2021-07-27  000948    0.03
2021-07-28  000948    0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948    0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948    0.05
2021-08-11  000948    0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948    0.45
2021-08-18  000948    0.29
2021-08-19  000948    0.14
2021-08-20  000948    0.05
2021-08-23  000948    0.03
2021-08-24  000948    0.22
2021-08-25  000948    0.08
2021-08-26  000948    0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
Name: close, dtype: float64

QA.MAX(A, B)

In [123]:
# 对 Series 的值逐一比较
def MAX(A, B):
    var = IF(A > B, A, B)
    return var
In [124]:
t2=DIFF(t,N=1)
t3=ABS(t2)
MAX(t2,t3)
Out[124]:
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948    0.42
2021-07-26  000948    0.58
2021-07-27  000948    0.03
2021-07-28  000948    0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948    0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948    0.05
2021-08-11  000948    0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948    0.45
2021-08-18  000948    0.29
2021-08-19  000948    0.14
2021-08-20  000948    0.05
2021-08-23  000948    0.03
2021-08-24  000948    0.22
2021-08-25  000948    0.08
2021-08-26  000948    0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
dtype: float64

QA.MIN(A, B)

In [61]:
def MIN(A, B):
    var = IF(A < B, A, B)
    return var
In [125]:
t2=DIFF(t,N=1)
t3=ABS(t2)
MIN(t2,t3)
Out[125]:
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948   -0.42
2021-07-26  000948   -0.58
2021-07-27  000948   -0.03
2021-07-28  000948   -0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948   -0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948   -0.05
2021-08-11  000948   -0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948   -0.45
2021-08-18  000948    0.29
2021-08-19  000948   -0.14
2021-08-20  000948   -0.05
2021-08-23  000948    0.03
2021-08-24  000948   -0.22
2021-08-25  000948   -0.08
2021-08-26  000948   -0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
dtype: float64

QA.CROSS(A, B)

In [145]:
# diff() 缺省 N=1,计算前后 1 个位置的差。
def CROSS(A, B):
    """A<B then A>B  A上穿B B下穿A
    Arguments:
        A {[type]} -- [description]
        B {[type]} -- [description]
    Returns:
        [type] -- [description]
    """

    var = np.where(A < B, 1, 0)
    print('var is: ', var)
    try:
        index = A.index
    except:
        index = B.index
    # 按照 var 以及 1 个位移的差值,如果小于 0 ,返回 1,否则返回 0,以 int 形式呈现
    return (pd.Series(var, index=index).diff() < 0).apply(int)
    # return pd.Series(var, index=index).diff()
In [146]:
t2=DIFF(t,N=1)
#print(t2)
t3=ABS(t2)
#print(t3)
CROSS(t2,t3)
var is:  [0 0 0 1 1 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 1 0 1 1 1 0 0 0 0]
Out[146]:
date        code  
2021-07-20  000948    0
2021-07-21  000948    0
2021-07-22  000948    0
2021-07-23  000948    0
2021-07-26  000948    0
2021-07-27  000948    0
2021-07-28  000948    0
2021-07-29  000948    1
2021-07-30  000948    0
2021-08-02  000948    0
2021-08-03  000948    0
2021-08-04  000948    0
2021-08-05  000948    0
2021-08-06  000948    1
2021-08-09  000948    0
2021-08-10  000948    0
2021-08-11  000948    0
2021-08-12  000948    1
2021-08-13  000948    0
2021-08-16  000948    0
2021-08-17  000948    0
2021-08-18  000948    1
2021-08-19  000948    0
2021-08-20  000948    0
2021-08-23  000948    1
2021-08-24  000948    0
2021-08-25  000948    0
2021-08-26  000948    0
2021-08-27  000948    1
2021-08-30  000948    0
2021-08-31  000948    0
2021-09-01  000948    0
dtype: int64

QA.COUNT(COND, N)

In [153]:
def COUNT(COND, N):
    """
    2018/05/23 修改
    参考https://github.com/QUANTAXIS/QUANTAXIS/issues/429
    现在返回的是series
    """
    # COND 是序列 A 与序列 B 的比较
    # 满足条件时,返回 1 ,否则返回 0
    # 然后计算前 N 个位置的位移窗口,并加总
    return pd.Series(np.where(COND, 1, 0), index=COND.index).rolling(N).sum()
In [154]:
t2=DIFF(t,N=1)
t3=ABS(t2)
COUNT(t2<t3, 2)
Out[154]:
date        code  
2021-07-20  000948    NaN
2021-07-21  000948    0.0
2021-07-22  000948    0.0
2021-07-23  000948    1.0
2021-07-26  000948    2.0
2021-07-27  000948    2.0
2021-07-28  000948    2.0
2021-07-29  000948    1.0
2021-07-30  000948    0.0
2021-08-02  000948    0.0
2021-08-03  000948    0.0
2021-08-04  000948    0.0
2021-08-05  000948    1.0
2021-08-06  000948    1.0
2021-08-09  000948    0.0
2021-08-10  000948    1.0
2021-08-11  000948    2.0
2021-08-12  000948    1.0
2021-08-13  000948    0.0
2021-08-16  000948    0.0
2021-08-17  000948    1.0
2021-08-18  000948    1.0
2021-08-19  000948    1.0
2021-08-20  000948    2.0
2021-08-23  000948    1.0
2021-08-24  000948    1.0
2021-08-25  000948    2.0
2021-08-26  000948    2.0
2021-08-27  000948    1.0
2021-08-30  000948    0.0
2021-08-31  000948    0.0
2021-09-01  000948    0.0
dtype: float64

QA.IF(COND, V1, V2)

In [295]:
# 对于 序列的 IF 判断,有一个隐含条件:
"""
and:
  T and T = T
  T and F = F
  F and T = F
  F and F = F
or : 
  T or T = T
  T or F = T
  F or T = T
  F or F = F
"""
def IF(COND, V1, V2):
    # 此处 COND 的序列 比较。属于 and ...
    var = np.where(COND, V1, V2)
#     print('=----------> var is: \n', var)
    try:
        try:
            index = V1.index
        except:
            index = COND.index
    except:
        index = V2.index
    return pd.Series(var, index=index)
In [296]:
t2=DIFF(t,N=1)
t3=ABS(t2)
print('>>>>>>>>>> COND is: \n', t2>t3)
IF(t2>t3, t2, t3)
>>>>>>>>>> COND is: 
 date        code  
2021-07-20  000948    False
2021-07-21  000948    False
2021-07-22  000948    False
2021-07-23  000948    False
2021-07-26  000948    False
2021-07-27  000948    False
2021-07-28  000948    False
2021-07-29  000948    False
2021-07-30  000948    False
2021-08-02  000948    False
2021-08-03  000948    False
2021-08-04  000948    False
2021-08-05  000948    False
2021-08-06  000948    False
2021-08-09  000948    False
2021-08-10  000948    False
2021-08-11  000948    False
2021-08-12  000948    False
2021-08-13  000948    False
2021-08-16  000948    False
2021-08-17  000948    False
2021-08-18  000948    False
2021-08-19  000948    False
2021-08-20  000948    False
2021-08-23  000948    False
2021-08-24  000948    False
2021-08-25  000948    False
2021-08-26  000948    False
2021-08-27  000948    False
2021-08-30  000948    False
2021-08-31  000948    False
2021-09-01  000948    False
Name: close, dtype: bool
Out[296]:
date        code  
2021-07-20  000948     NaN
2021-07-21  000948    0.05
2021-07-22  000948    0.08
2021-07-23  000948    0.42
2021-07-26  000948    0.58
2021-07-27  000948    0.03
2021-07-28  000948    0.35
2021-07-29  000948    0.17
2021-07-30  000948    0.30
2021-08-02  000948    0.21
2021-08-03  000948    0.27
2021-08-04  000948    0.00
2021-08-05  000948    0.21
2021-08-06  000948    0.14
2021-08-09  000948    0.06
2021-08-10  000948    0.05
2021-08-11  000948    0.04
2021-08-12  000948    0.29
2021-08-13  000948    0.21
2021-08-16  000948    0.46
2021-08-17  000948    0.45
2021-08-18  000948    0.29
2021-08-19  000948    0.14
2021-08-20  000948    0.05
2021-08-23  000948    0.03
2021-08-24  000948    0.22
2021-08-25  000948    0.08
2021-08-26  000948    0.09
2021-08-27  000948    0.63
2021-08-30  000948    0.15
2021-08-31  000948    0.43
2021-09-01  000948    0.20
dtype: float64

QA.REF(Series, N)

In [168]:
# 对数据进行移动 N 个位置
def REF(Series, N):
    return Series.shift(N)
In [169]:
REF(t,3)
Out[169]:
date        code  
2021-07-20  000948      NaN
2021-07-21  000948      NaN
2021-07-22  000948      NaN
2021-07-23  000948    11.98
2021-07-26  000948    12.03
2021-07-27  000948    12.11
2021-07-28  000948    11.69
2021-07-29  000948    11.11
2021-07-30  000948    11.08
2021-08-02  000948    10.73
2021-08-03  000948    10.90
2021-08-04  000948    11.20
2021-08-05  000948    11.41
2021-08-06  000948    11.68
2021-08-09  000948    11.68
2021-08-10  000948    11.47
2021-08-11  000948    11.61
2021-08-12  000948    11.67
2021-08-13  000948    11.62
2021-08-16  000948    11.58
2021-08-17  000948    11.87
2021-08-18  000948    12.08
2021-08-19  000948    12.54
2021-08-20  000948    12.09
2021-08-23  000948    12.38
2021-08-24  000948    12.24
2021-08-25  000948    12.19
2021-08-26  000948    12.22
2021-08-27  000948    12.00
2021-08-30  000948    11.92
2021-08-31  000948    11.83
2021-09-01  000948    12.46
Name: close, dtype: float64

QA.STD(Series, N)

In [66]:
def STD(Series, N):
    return pd.Series.rolling(Series, N).std()
In [171]:
STD(t,3)
Out[171]:
date        code  
2021-07-20  000948         NaN
2021-07-21  000948         NaN
2021-07-22  000948    0.065574
2021-07-23  000948    0.223010
2021-07-26  000948    0.502129
2021-07-27  000948    0.343851
2021-07-28  000948    0.211266
2021-07-29  000948    0.175024
2021-07-30  000948    0.237978
2021-08-02  000948    0.256320
2021-08-03  000948    0.240624
2021-08-04  000948    0.155885
2021-08-05  000948    0.121244
2021-08-06  000948    0.106927
2021-08-09  000948    0.102632
2021-08-10  000948    0.032146
2021-08-11  000948    0.045092
2021-08-12  000948    0.157162
2021-08-13  000948    0.251064
2021-08-16  000948    0.342685
2021-08-17  000948    0.262742
2021-08-18  000948    0.228108
2021-08-19  000948    0.145029
2021-08-20  000948    0.098489
2021-08-23  000948    0.025166
2021-08-24  000948    0.119304
2021-08-25  000948    0.155349
2021-08-26  000948    0.085049
2021-08-27  000948    0.340735
2021-08-30  000948    0.413884
2021-08-31  000948    0.301054
2021-09-01  000948    0.321921
Name: close, dtype: float64

QA.AVEDEV(Series, N)

In [67]:
def AVEDEV(Series, N):
    """
    平均绝对偏差 mean absolute deviation
    修正: 2018-05-25 
    之前用mad的计算模式依然返回的是单值
    """
    return Series.rolling(N).apply(lambda x: (np.abs(x - x.mean())).mean(), raw=True)
In [173]:
AVEDEV(t,5)
Out[173]:
date        code  
2021-07-20  000948       NaN
2021-07-21  000948       NaN
2021-07-22  000948       NaN
2021-07-23  000948       NaN
2021-07-26  000948    0.3072
2021-07-27  000948    0.4072
2021-07-28  000948    0.4448
2021-07-29  000948    0.2384
2021-07-30  000948    0.1512
2021-08-02  000948    0.1992
2021-08-03  000948    0.2952
2021-08-04  000948    0.2592
2021-08-05  000948    0.1536
2021-08-06  000948    0.1040
2021-08-09  000948    0.0656
2021-08-10  000948    0.0560
2021-08-11  000948    0.0520
2021-08-12  000948    0.0800
2021-08-13  000948    0.1688
2021-08-16  000948    0.2976
2021-08-17  000948    0.2456
2021-08-18  000948    0.2144
2021-08-19  000948    0.1552
2021-08-20  000948    0.1376
2021-08-23  000948    0.0688
2021-08-24  000948    0.0888
2021-08-25  000948    0.1232
2021-08-26  000948    0.1384
2021-08-27  000948    0.2032
2021-08-30  000948    0.2968
2021-08-31  000948    0.3976
2021-09-01  000948    0.4032
Name: close, dtype: float64

QA.BBIBOLL(Series, N1, N2, N3, N4, N, M)

In [290]:
def BBI(Series, N1, N2, N3, N4):
    '多空指标'
    bbi = (MA(Series, N1) + MA(Series, N2) +
           MA(Series, N3) + MA(Series, N4)) / 4
    DICT = {'BBI': bbi}
    VAR = pd.DataFrame(DICT)
#     print('=----------> VAR is: \n', VAR)
    return VAR
def BBIBOLL(Series, N1, N2, N3, N4, N, M):  # 多空布林线
    bbiboll = BBI(Series, N1, N2, N3, N4)
#     print('=----------> bbiboll is: \n', bbiboll)
    UPER = bbiboll + M * STD(bbiboll, N)
    DOWN = bbiboll - M * STD(bbiboll, N)
    DICT = {'BBIBOLL': bbiboll, 'UPER': UPER, 'DOWN': DOWN}
#     print('=----------> type(DICT) is: \n', type(DICT), '\n OVER')
    VAR = pd.DataFrame(DICT, index=[0])
#     VAR = pd.DataFrame(DICT)
#     print('=----------> VAR is: \n', VAR)
    return VAR
  • BBI,Bull And Bear lndex,多空指标
  • 是一种将不同日数移动平均线加权平均之后的综合指标,属于均线型指标,一般选用3日、6日、12日、24日等4条平均线
  • 在使用移动平均线时,投资者往往对参数值选择有不同的偏好,而多空指标恰好解决了中短期移动平均线的期间长短合理性问题
  • 很明显,在BBI指标中,近期数据较多,远期数据利用次数较少,因而是一种变相的加权计算
  • 由于多空指标是一条混合平均线,所以既有短期移动平均线的灵敏,又有明显的中期趋势特征,适于稳健的投资者
In [291]:
BBIBOLL(t, 3, 6, 12, 24, 20, 3)
Out[291]:
BBIBOLL UPER DOWN
0 (B, B, I) (B, B, I) (B, B, I)
  • 源码目录:QUANTAXIS/QUANTAXIS/QAIndicator/indicators.py

应用级指标 add_func(func)

  • 趋向指标
    • 又叫趋势跟踪类指标,主要用于跟踪并预测股价的发展趋势
    • 包含的主要指标
      • 移动平均线 $MA$
      • 指数平滑移动平均线 $MACD$
      • 趋向指标 $DMI$
      • 瀑布线 $PBX$
      • 平均线差 $DMA$
      • 动力指标(动量线) $MTM$
      • 指数平均线 $EXPMA$
      • 佳庆指标 $CHO$
  • 反趋向指标
    • 主要捕捉趋势的转折点
      • 随机指标 $KDJ$
      • 乖离率 $BIAS$
      • 变动速率 $ROC$
      • 顺势指标 $CCI$
      • 威廉指标 $W\&R$
      • 震荡量(变动速率) $OSC$
      • 相对强弱指标 $RSI$
      • 动态买卖指标 $ADTM$
  • 量能指标
    • 通过成交量的大小和变化研判趋势变化
      • 容量指标 $VR$
      • 量相对强弱 $VRSI$
      • 能量指标 $CR$
      • 人气意愿指标 $ARBR$
      • 成交量标准差 $VSTD$
  • 量价指标
    • 通过成交量和股价变动关系分析未来趋势
      • 震荡升降指标 $ASI$
      • 价量趋势 $PVT$
      • 能量潮 $OBV$
      • 量价趋势 $VPT$
  • 压力支撑指标
    • 主要用于分析股价目前收到的压力和支撑
      • 布林带 $BOLL$
      • 麦克指标 $MIKE$
  • 大盘指标
    • 通过涨跌家数研究大盘指数的走势
      • 涨跌比率 $ADR$
      • 绝对幅度指标 $ABI$
      • 新三价率 $TBR$
      • 腾落指数 $ADL$
      • 广量冲力指标
      • 指数平滑广量 $STIX$
In [266]:
# 演示数据
tt = QA.QA_fetch_stock_day_adv('000948','2021-05-01','2021-09-12').to_qfq()
print('type(tt) is: \n', type(tt))
print('type(tt.data) is: \n', type(tt.data))
tt.data
type(tt) is: 
 <class 'QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day'>
type(tt.data) is: 
 <class 'pandas.core.frame.DataFrame'>
Out[266]:
open high low close volume amount adj
date code
2021-05-06 000948 10.109367 10.886245 10.039648 10.607366 141847.0 149029600.0 0.995997
2021-05-07 000948 10.457966 11.005765 10.398207 10.657166 165143.0 178363680.0 0.995997
2021-05-10 000948 10.806565 11.025685 10.567526 10.955965 141743.0 154681312.0 0.995997
2021-05-11 000948 11.234844 12.051561 11.075484 12.051561 122497.0 145266912.0 0.995997
2021-05-12 000948 13.177038 13.256717 12.459920 13.256717 419228.0 544840768.0 0.995997
... ... ... ... ... ... ... ... ...
2021-09-06 000948 12.830000 13.000000 12.630000 12.900000 67129.0 86278872.0 1.000000
2021-09-07 000948 12.890000 13.050000 12.720000 12.880000 54472.0 70141112.0 1.000000
2021-09-08 000948 12.880000 13.190000 12.800000 13.190000 94864.0 123549176.0 1.000000
2021-09-09 000948 13.160000 13.160000 12.840000 12.860000 72507.0 93970832.0 1.000000
2021-09-10 000948 12.810000 12.960000 12.650000 12.840000 56355.0 72116784.0 1.000000

91 rows × 7 columns

QA.QA_indicator_OSC(DataFrame, N, M)

  • $Oscillator 振荡器$
  • $OSC = 当日收盘价 ÷ (n-1)日的收盘价 × 100$
In [271]:
def QA_indicator_OSC(DataFrame, N=20, M=6):
    """变动速率线
    震荡量指标OSC,也叫变动速率线。属于超买超卖类指标,是从移动平均线原理派生出来的一种分析指标。
    它反应当日收盘价与一段时间内平均收盘价的差离值,从而测出股价的震荡幅度。
    按照移动平均线原理,根据OSC的值可推断价格的趋势,如果远离平均线,就很可能向平均线回归。
    """
    C = DataFrame['close']
    # 两个序列(当日收盘价序列,收盘价的N日收盘价平均价序列)的差值
    OS = (C - MA(C, N)) * 100
    # 再计算 M 日的指数移动平均价
    # 指数移动平均指标,是一种移动平均指标,它给予最近的数据以更大的权重和重要性
    MAOSC = EMA(OS, M)
    DICT = {'OSC': OS, 'MAOSC': MAOSC}
    
    return pd.DataFrame(DICT)
In [269]:
QA_indicator_OSC(tt,20,6)
Out[269]:
OSC MAOSC
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 NaN NaN
2021-05-10 000948 NaN NaN
2021-05-11 000948 NaN NaN
2021-05-12 000948 NaN NaN
... ... ... ...
2021-09-06 000948 57.00 64.916544
2021-09-07 000948 48.70 60.283246
2021-09-08 000948 71.65 63.530890
2021-09-09 000948 33.70 55.007779
2021-09-10 000948 27.90 47.262699

91 rows × 2 columns

QA.QA_indicator_BBI(DataFrame, N1, N2, N3, N4)

  • BBI,Bull And Bear lndex,多空指标
In [272]:
def QA_indicator_BBI(DataFrame, N1=3, N2=6, N3=12, N4=24):
    '多空指标'
    C = DataFrame['close']
    # 分别计算四个窗口的均值,在计算四个值得平均数
    bbi = (MA(C, N1) + MA(C, N2) + MA(C, N3) + MA(C, N4)) / 4
    DICT = {'BBI': bbi}

    return pd.DataFrame(DICT)
In [273]:
QA_indicator_BBI(tt, 3, 6, 12, 24)
Out[273]:
BBI
date code
2021-05-06 000948 NaN
2021-05-07 000948 NaN
2021-05-10 000948 NaN
2021-05-11 000948 NaN
2021-05-12 000948 NaN
... ... ...
2021-09-06 000948 12.638229
2021-09-07 000948 12.666354
2021-09-08 000948 12.744062
2021-09-09 000948 12.755833
2021-09-10 000948 12.777187

91 rows × 1 columns

QA.QA_indicator_PBX(DataFrame, N1, N2, N3, N4, N5, N6)

In [250]:
def QA_indicator_PBX(DataFrame, N1=3, N2=5, N3=8, N4=13, N5=18, N6=24):
    '瀑布线'
    C = DataFrame['close']
    PBX1 = (EMA(C, N1) + EMA(C, 2 * N1) + EMA(C, 4 * N1)) / 3
    PBX2 = (EMA(C, N2) + EMA(C, 2 * N2) + EMA(C, 4 * N2)) / 3
    PBX3 = (EMA(C, N3) + EMA(C, 2 * N3) + EMA(C, 4 * N3)) / 3
    PBX4 = (EMA(C, N4) + EMA(C, 2 * N4) + EMA(C, 4 * N4)) / 3
    PBX5 = (EMA(C, N5) + EMA(C, 2 * N5) + EMA(C, 4 * N5)) / 3
    PBX6 = (EMA(C, N6) + EMA(C, 2 * N6) + EMA(C, 4 * N6)) / 3
    DICT = {'PBX1': PBX1, 'PBX2': PBX2, 'PBX3': PBX3,
            'PBX4': PBX4, 'PBX5': PBX5, 'PBX6': PBX6}

    return pd.DataFrame(DICT)
  • 瀑布线
    • 是一种研判股价运行趋势的一种主要分析手段
    • 因为单边走势类似瀑布直上直下,所以被称为瀑布线,又称为是非线性加权移动平均线
    • 瀑布线有六条组合而成,每条瀑布线代表着不用时间和周期股价的成本状况
    • 与普通均线系统相比较,它具有反应速度快,给出的买卖点明确的特点,并能过滤掉盘中主力震仓洗盘或下跌行情中的小幅反弹,可直观有效地把握住大盘和个股的运动趋势
  • 瀑布线的计算公式
    • 瀑布线 N = (收盘价的 N1 日指数移动平均 + 收盘价的 N1*2 日简单移动平均 + 收盘价的 N1*4 日简单移动平均) / 3
  • 瀑布线使用技巧
    • 瀑布线在单边行情中有效度最高,当六根线呈现多头排列,即可逢低买入,当六根线呈现空头排列,可逢高减仓;
    • 瀑布线在震荡行情中尝尝会出现金叉或死叉,但是由于瀑布线一般都比较滞后,所以当我们发现了金叉或死叉的时候,可能就已经错过了行情,因此,在股价横盘震荡整理过程中,我们可以对瀑布线的金叉或死叉进行逆向操作;
    • A4线是瀑布线的移动中轴线,是从小周期转向大周期的第四根线,如果股价是在上升趋势中出现下跌并触碰到A4线,就可能会出现反弹行情,反之,如果在下跌趋势中反弹触及A4线,股价将会再次回探;
    • 在市场窄幅波动所形成的单边趋势中,瀑布线的六根线距离会比较近,在上升的趋势中如果下跌触及A6线或者是跌破A6线,会出现背离,可抢反弹,而在下降趋势中如果出现反弹并触及或突破A6线,也会出现背离,可做空,因为股价会再次回落;
    • 如果瀑布线出现在震荡横盘的时候并且多跟线贴在一起,不管是金叉还是死叉的信号都不明显,这个时候可以不操作或者是通过其他指标来进行研判;
    • 在市场进行多空切换的是时候,瀑布线指标所指示的金叉或死叉会很明显,但是滞后性比较严重,只有在单边行情中,瀑布线才具备一定的价值;
    • 在瀑布线排列非常整齐的时候,不管是多头排列还是空头排列,单边趋势都很明显,如果市场价格偏离瀑布线的幅度较大,可获利了结;
    • 在六根瀑布线呈发散型排列的时候,说明股价要出现回调,这时候需要我们注意规避风险。
In [274]:
QA_indicator_PBX(tt, 3, 5, 8, 13, 18, 24)
Out[274]:
PBX1 PBX2 PBX3 PBX4 PBX5 PBX6
date code
2021-05-06 000948 NaN NaN NaN NaN NaN NaN
2021-05-07 000948 NaN NaN NaN NaN NaN NaN
2021-05-10 000948 NaN NaN NaN NaN NaN NaN
2021-05-11 000948 NaN NaN NaN NaN NaN NaN
2021-05-12 000948 NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ...
2021-09-06 000948 12.776237 12.650646 12.513450 12.386669 12.322828 NaN
2021-09-07 000948 12.793078 12.680380 12.549969 12.422569 12.355105 NaN
2021-09-08 000948 12.904537 12.768609 12.623257 12.481572 12.404603 NaN
2021-09-09 000948 12.873619 12.770139 12.641646 12.506602 12.429530 NaN
2021-09-10 000948 12.852490 12.770102 12.655826 12.527814 12.451452 NaN

91 rows × 6 columns

QA.QA_indicator_BOLL(DataFrame, N)

In [276]:
def QA_indicator_BOLL(DataFrame, N=20, P=2):
    '布林线'
    C = DataFrame['close']
    # 均线
    boll = MA(C, N)
    # 上轨
    UB = boll + P * STD(C, N)
    # 下轨
    LB = boll - P * STD(C, N)
    DICT = {'BOLL': boll, 'UB': UB, 'LB': LB}

    return pd.DataFrame(DICT)
  • 使用技巧
    • 当价格往下跌到下轨线也就是支撑线的时候,表示后面有一个拉升,可以买入一个多单(买涨)
    • 当价格上涨触碰到上轨线也就是阻力线的时候,表示有一个下跌,可以做一个空单(买跌)
    • 当三线合并的时候,就表示市场会选择一个价格方向,这时主要看BOLL的开口
      • 一旦出现一个开口,价格(K线)在什么位置就往什么方向去
      • 当三线靠拢,距离收窄时,上轨线和下轨线出现一个明显的开口
      • K 线位于下轨线(上轨线),价格就会下跌(上涨)
In [275]:
QA_indicator_BOLL(tt, N=20, P=2)
Out[275]:
BOLL UB LB
date code
2021-05-06 000948 NaN NaN NaN
2021-05-07 000948 NaN NaN NaN
2021-05-10 000948 NaN NaN NaN
2021-05-11 000948 NaN NaN NaN
2021-05-12 000948 NaN NaN NaN
... ... ... ... ...
2021-09-06 000948 12.3300 13.295140 11.364860
2021-09-07 000948 12.3930 13.326992 11.459008
2021-09-08 000948 12.4735 13.389815 11.557185
2021-09-09 000948 12.5230 13.408488 11.637512
2021-09-10 000948 12.5610 13.431545 11.690455

91 rows × 3 columns

QA.QA_indicator_ROC(DataFrame, N, M)

In [278]:
def QA_indicator_ROC(DataFrame, N=12, M=6):
    '变动率指标'
    C = DataFrame['close']
    # REF(N) 是对数据进行移动 N 个位置
    # 当前价格与前N的位置的价格之差,再除以前N位置的价格,计算出比率
    roc = 100 * (C - REF(C, N)) / REF(C, N)
    # 计算 M 日 该比率的均值
    ROCMA = MA(roc, M)
    DICT = {'ROC': roc, 'ROCMA': ROCMA}

    return pd.DataFrame(DICT)
  • 变动率指标(ROC)
    • 是以当日的收盘价N天前的收盘价比较
    • 通过计算股价某一段时间内收盘价变动的比例,应用价格的移动比较来测量价位动量,达到事先探测股价买卖供需力量的强弱,进而分析股价的趋势及其是否有转势的意愿,属于反趋势指标之一
    • MACDRSIKDJ 等指标一样,ROC 也是技术分析最常见的参考指标之一
In [279]:
QA_indicator_ROC(tt, N=12, M=6)
Out[279]:
ROC ROCMA
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 NaN NaN
2021-05-10 000948 NaN NaN
2021-05-11 000948 NaN NaN
2021-05-12 000948 NaN NaN
... ... ... ...
2021-09-06 000948 5.392157 5.999032
2021-09-07 000948 5.660377 5.903394
2021-09-08 000948 7.937807 5.901859
2021-09-09 000948 7.166667 6.165947
2021-09-10 000948 7.718121 6.197820

91 rows × 2 columns

QA.QA_indicator_MTM(DataFrame, N, M)

In [281]:
def QA_indicator_MTM(DataFrame, N=12, M=6):
    '动量线'
    C = DataFrame.close
    # REF(N) 是对数据进行移动 N 个位置
    # 先计算当前价格与前 N 个位移价格的差
    mtm = C - REF(C, N)
    # 再计算 M 个该差的平均值
    MTMMA = MA(mtm, M)
    DICT = {'MTM': mtm, 'MTMMA': MTMMA}

    return pd.DataFrame(DICT)
  • 动量指标 Momentom Index
    • MTM指标,是一种专门研究股价波动的中短期技术分析工具
    • 动量指数以分析股价波动的速度为目的,研究股价在波动过程中各种加速,减速,惯性作用以及股价由静到动由动转静的现象
  • 动量指数的理论基础价格和供需量的关系
    • 股价的涨幅随着时间,必须日渐缩小,变化的速度力量慢慢减缓,行情则可反转
    • 反之,下跌亦然
  • 理论上,一波健全的股价趋势,其上涨或下跌的过程,应该维持着一定的行进速度。如果行进的速度逐渐减缓,股价很容易转变成整理的格局,甚至于反转
In [282]:
QA_indicator_MTM(tt, N=12, M=6)
Out[282]:
MTM MTMMA
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 NaN NaN
2021-05-10 000948 NaN NaN
2021-05-11 000948 NaN NaN
2021-05-12 000948 NaN NaN
... ... ... ...
2021-09-06 000948 0.66 0.730000
2021-09-07 000948 0.69 0.721667
2021-09-08 000948 0.97 0.723333
2021-09-09 000948 0.86 0.750000
2021-09-10 000948 0.92 0.751667

91 rows × 2 columns

QA.QA_indicator_KDJ(DataFrame, N=9, M1=3, M2=3)

In [284]:
def QA_indicator_KDJ(DataFrame, N=9, M1=3, M2=3):
    C = DataFrame['close']
    H = DataFrame['high']
    L = DataFrame['low']

    RSV = ((C - LLV(L, N)) / (HHV(H, N) - LLV(L, N)) * 100).groupby('code').fillna(method='ffill')
    K = SMA(RSV, M1)
    D = SMA(K, M2)
    J = 3 * K - 2 * D
    DICT = {'KDJ_K': K, 'KDJ_D': D, 'KDJ_J': J}
    return pd.DataFrame(DICT)
  • $KDJ$ 指标的中文名称又叫随机指标
    • $K$ D指标是在威廉指标的基础上发展起来的。不过KD指标只判断股票的超买超卖的现象,在KDJ指标中则融合了移动平均线速度上的观念,形成比较准确的买卖信号依据
    • $KDJ$ 指标在设计过程中主要是研究最高价、最低价和收盘价之间的关系,同时也融合了动量观念、强弱指标和移动平均线的一些优点
    • $KDJ$ 的计算
      • 首先选择周期($n$ 日、$n$ 周等)
      • 再计算当天的未成熟随机值(即 $RSV$ 值)
        • $RSV = \frac{C - L_{n}}{H_{n} - L_{n}} \times 100$
          • $C$ 为当天的收盘价
          • $Ln$ 为之前 $n$ 日内的最低价
          • $Hn$ 为之前 $n$ 日内的最高价
      • 然后再计算 $K$ 值、$D$ 值、$J$ 值
        • $K$
          • 某一天当天的$K$值 = 2/3×前一日$K$值+1/3×当日$RSV$,即:$K_{i}=\frac{2}{3} K_{i-1} + \frac{1}{3} RSV_{i}$
          • $K_{i}$ 和 $RSV_{i}$ 分别表示某一天当天的$K$值和$RSV$值
          • $K_{i-1}$表示前一天的$K$值,若无前一天的$K$值,则用$50$来代替
        • $D$
          • 某一天当天的$D$值 = 2/3×前一日$D$值+1/3×当日$K$值,即:$D_{i}=\frac{2}{3} D_{i-1} + \frac{1}{3} K_{i}$
          • $D_{i}$和$K_{i}$分别表示当天的$D$值和$K$值;
          • $D_{i-1}$表示前一天的$D$值,若无前一天的$D$值,则用$50$来代替
        • $J$
          • $J$值 = 3×当日$K$值-2×当日$D$值,即:$J_{i}= 3K_{i} - 2D_{i}$
In [285]:
QA_indicator_KDJ(tt, N=9, M1=3, M2=3)
Out[285]:
KDJ_K KDJ_D KDJ_J
date code
2021-05-17 000948 72.149123 72.149123 72.149123
2021-05-18 000948 72.149123 72.149123 72.149123
2021-05-19 000948 66.115288 70.137845 58.070175
2021-05-20 000948 56.401094 65.558928 38.085426
2021-05-21 000948 49.248456 60.122104 27.501161
... ... ... ... ...
2021-09-06 000948 75.068895 71.351839 82.503007
2021-09-07 000948 75.045930 72.583203 79.971385
2021-09-08 000948 80.646562 75.270989 91.397708
2021-09-09 000948 66.318487 72.286822 54.381818
2021-09-10 000948 55.900637 66.824760 34.052389

84 rows × 3 columns

QA.QA_indicator_MFI(DataFrame, N)

In [297]:
def QA_indicator_MFI(DataFrame, N=14):
    """
    资金指标
    TYP := (HIGH + LOW + CLOSE)/3;
    V1:=SUM(IF(TYP>REF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYP<REF(TYP,1),TYP*VOL,0),N);  # “:=”表示定义为是编程语言里的赋值语句的符号,用来定义一个新出现的符号
    MFI:100-(100/(1+V1));
    赋值: (最高价 + 最低价 + 收盘价)/3
    V1赋值: 如果 TYP > 1日前的TYP, 返回 TYP*成交量(手), 否则返回 0 的 N 日累和 / 如果 TYP < 1日前的 TYP, 返回TYP*成交量(手), 否则返回0 的 N日累和
    输出资金流量指标:100-(100/(1+V1))
    """
    C = DataFrame['close']
    H = DataFrame['high']
    L = DataFrame['low']
    VOL = DataFrame['volume']
    TYP = (C + H + L) / 3
    V1 = SUM(IF(TYP > REF(TYP, 1), TYP * VOL, 0), N) / \
        SUM(IF(TYP < REF(TYP, 1), TYP * VOL, 0), N)
    mfi = 100 - (100 / (1 + V1))
    DICT = {'MFI': mfi}

    return pd.DataFrame(DICT)
  • 资金流量指标 $MFI$ $Money\ Flow\ Index$
    • 是相对强弱指标($RSI$)和人气指标($OBV$)两者的结合
    • $MFI$ 指标可以用于测度交易量的动量投资兴趣
    • 而交易量的变化为股价未来的变化提供了线索,所以MFI指标可以帮助判断股票价格变化的趋势
    • 计算方法
      • 典型价格($TYP$)= 当日最高价最低价收盘价算术平均值
      • 货币流量($MF$)= 典型价格($TYP$)$\times$ $N$ 日内成交量
      • 如果当日 $MF$ > 昨日$MF$,则将当日的$MF$值视为正货币流量($PMF$)
      • 如果当日 $MF$ < 昨日$MF$,则将当日的$MF$值视为负货币流量($NMF$)
      • $V1 = \frac{PMF}{NMF}$
      • $MFI = 100-\frac{100}{1+V1}$
      • 参数 $N$ 一般设为 $14$ 日。
    • 应用法则
      • 显示超买超卖是 $MFI$ 指标最基本的功能
      • 当$MFI>80$时为超买,在其回头向下跌破80时,为短线卖出时机。
      • 当$MFI<20$时为超卖,当其回头向上突破20时,为短线买进时机。
      • 当$MFI>80$,而产生背离现象时,视为卖出信号。
      • 当$MFI<20$,而产生背离现象时,视为买进信号。
    • 注意要点
      • 经过长期测试,$MFI$ 指标的背离讯号更能忠实的反应股价的反转现象
      • 一次完整的波段行情,至少都会维持一定相当的时间,反转点出现的次数并不会太多。
      • 将 $MFI$ 指标的参数设定为 $14$ 天时,其背离讯号产生的时机,大致上都能和股价的顶点吻合
      • 因此在使用 $MFI$ 指标时,参数设定方面应尽量维持 $14$ 日的原则
In [298]:
QA_indicator_MFI(tt, N=14)
Out[298]:
MFI
date code
2021-05-06 000948 NaN
2021-05-07 000948 NaN
2021-05-10 000948 NaN
2021-05-11 000948 NaN
2021-05-12 000948 NaN
... ... ...
2021-09-06 000948 64.738401
2021-09-07 000948 64.100740
2021-09-08 000948 64.218227
2021-09-09 000948 62.977418
2021-09-10 000948 58.826554

91 rows × 1 columns

QA.QA_indicator_ATR(DataFrame, N)

In [314]:
def QA_indicator_ATR(DataFrame, N=14):
    """
    输出TR: (最高价-最低价) 和 昨收-最高价 的绝对值的较大值 和 昨收-最低价 的绝对值的较大值
    输出真实波幅: TR 的 N 日简单移动平均
    算法:今日振幅、今日最高与昨收差价、今日最低与昨收差价中的最大值,为真实波幅,求真实波幅的N日移动平均
    参数:N 天数,一般取14
    """
    C = DataFrame['close']
    H = DataFrame['high']
    L = DataFrame['low']
    TR = MAX(MAX((H - L), ABS(REF(C, 1) - H)), ABS(REF(C, 1) - L))
    atr = MA(TR, N)
    return pd.DataFrame({'TR': TR, 'ATR': atr})
  • 均幅指标(ATR)是取一定时间周期内的股价波动幅度的移动平均值,主要用于研判买卖时机
  • 较高的ATR值常发生在市场底部,并伴随恐慌性抛盘
  • 当其值较低时,则往往发生在合并以后的市场顶部
  • 根据这个指标来进行预测的原则可以表达
    • 该指标价值越高,趋势改变的可能性就越高
    • 该指标的价值越低,趋势的移动性就越弱
In [315]:
QA_indicator_ATR(tt, N=14)
Out[315]:
TR ATR
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 0.607558 NaN
2021-05-10 000948 0.458159 NaN
2021-05-11 000948 1.095596 NaN
2021-05-12 000948 1.205156 NaN
... ... ... ...
2021-09-06 000948 0.370000 0.450000
2021-09-07 000948 0.330000 0.432857
2021-09-08 000948 0.390000 0.430714
2021-09-09 000948 0.350000 0.435714
2021-09-10 000948 0.310000 0.445714

91 rows × 2 columns

QA.QA_indicator_SKDJ(DataFrame, N, M)

In [316]:
def QA_indicator_SKDJ(DataFrame, N=9, M=3):
    """
    1.指标>80 时,回档机率大;指标<20 时,反弹机率大;
    2.K在20左右向上交叉D时,视为买进信号参考; 
    3.K在80左右向下交叉D时,视为卖出信号参考;
    4.SKDJ波动于50左右的任何讯号,其作用不大。
    """
    CLOSE = DataFrame['close']
    # N 个单位窗口的最小值
    LOWV = LLV(DataFrame['low'], N)
    # N 个单位窗口的最大值
    HIGHV = HHV(DataFrame['high'], N)
    # 计算 收盘价与最低价、最高价与收盘价的差,的比率,的 M 日指数移动平均值
    RSV = EMA((CLOSE - LOWV) / (HIGHV - LOWV) * 100, M)
    # 再次计算 上述指数移动均值的 M 日指数移动均值
    K = EMA(RSV, M)
    # 再次计算 上述 指数移动均值 的 均值
    D = MA(K, M)
    DICT = {'RSV': RSV, 'SKDJ_K': K, 'SKDJ_D': D}

    return pd.DataFrame(DICT)
  • 慢速随机指标(SLOWKD或SKD)
    • 通过当日或最近几日的最高价、最低价以及收盘价等价格的波动幅度来反映价格趋势的强弱
    • 这个指标中有价值的形态,与其它指标是一样的,即粘合金叉死叉
In [317]:
QA_indicator_SKDJ(tt, N=9, M=3)
Out[317]:
RSV SKDJ_K SKDJ_D
date code
2021-05-06 000948 NaN NaN NaN
2021-05-07 000948 NaN NaN NaN
2021-05-10 000948 NaN NaN NaN
2021-05-11 000948 NaN NaN NaN
2021-05-12 000948 NaN NaN NaN
... ... ... ... ...
2021-09-06 000948 76.131731 76.386125 76.710391
2021-09-07 000948 75.565866 75.975995 76.334213
2021-09-08 000948 83.706846 79.841421 77.401180
2021-09-09 000948 60.684592 70.263006 75.360141
2021-09-10 000948 47.874763 59.068885 69.724437

91 rows × 3 columns

QA.QA_indicator_WR(DataFrame, N, N1)

In [304]:
def QA_indicator_WR(DataFrame, N, N1):
    '威廉指标'
    HIGH = DataFrame['high']
    LOW = DataFrame['low']
    CLOSE = DataFrame['close']
    # 天线
    WR1 = 100 * (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N))
    # 地线
    WR2 = 100 * (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1))
    DICT = {'WR1': WR1, 'WR2': WR2}

    return pd.DataFrame(DICT)
  • WR威廉指标是一种兼具超买超卖和强弱分界的指标,同KDJ指标有相似之处
    • 分别有一条天线和地线,以及一条以50为分隔的中界线,并且也波动于0-100之间
    • 但是,其与RSI指标和KDJ指标有一点重要分别是,其以0为顶部,以100为底
In [320]:
QA_indicator_WR(tt, 5, 15)
Out[320]:
WR1 WR2
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 NaN NaN
2021-05-10 000948 NaN NaN
2021-05-11 000948 NaN NaN
2021-05-12 000948 0.000000 NaN
... ... ... ...
2021-09-06 000948 57.142857 23.913043
2021-09-07 000948 64.788732 25.000000
2021-09-08 000948 1.754386 8.152174
2021-09-09 000948 58.928571 26.086957
2021-09-10 000948 62.500000 27.173913

91 rows × 2 columns

QA.QA_indicator_BIAS(DataFrame, N1, N2, N3)

In [321]:
def QA_indicator_BIAS(DataFrame, N1, N2, N3):
    '乖离率'
    # 先取收盘价
    CLOSE = DataFrame['close']
    # 计算 收盘价,与 N1 日的均线的差,除以 N1 日的收盘价均值 后的比率
    BIAS1 = (CLOSE - MA(CLOSE, N1)) / MA(CLOSE, N1) * 100
    BIAS2 = (CLOSE - MA(CLOSE, N2)) / MA(CLOSE, N2) * 100
    BIAS3 = (CLOSE - MA(CLOSE, N3)) / MA(CLOSE, N3) * 100
    DICT = {'BIAS1': BIAS1, 'BIAS2': BIAS2, 'BIAS3': BIAS3}

    return pd.DataFrame(DICT)
  • 乖离率(BIAS)
    • 又称偏离率,简称Y值
    • 是通过计算市场指数或收盘价与某条移动平均线之间的差距百分比,以反映一定时期内价格与其MA偏离程度的指标,从而得出价格在剧烈波动时因偏离移动平均趋势而造成回档或反弹的可能性,以及价格在正常波动范围内移动而形成继续原有势的可信度
    • 乖离率,是用百分比来表示价格与MA间的偏离程度(差距率)
    • 乖离率曲线(BIAS),是将各BIAS值连成线,得到的一条以0值为横向中轴之波动伸延的曲线
In [322]:
QA_indicator_BIAS(tt, 3, 6, 12)
Out[322]:
BIAS1 BIAS2 BIAS3
date code
2021-05-06 000948 NaN NaN NaN
2021-05-07 000948 NaN NaN NaN
2021-05-10 000948 2.009274 NaN NaN
2021-05-11 000948 7.396450 NaN NaN
2021-05-12 000948 9.667674 NaN NaN
... ... ... ... ...
2021-09-06 000948 0.025846 -0.232019 3.062583
2021-09-07 000948 0.181488 -0.732177 2.432235
2021-09-08 000948 1.539646 1.461538 4.227578
2021-09-09 000948 -0.899050 -0.592631 1.047669
2021-09-10 000948 -0.951401 -0.542215 0.286384

91 rows × 3 columns

QA.QA_indicator_RSI(DataFrame, N1, N2, N3)

In [325]:
def QA_indicator_RSI(DataFrame, N1=12, N2=26, N3=9):
    '相对强弱指标RSI1:SMA(MAX(CLOSE-LC,0),N1,1)/SMA(ABS(CLOSE-LC),N1,1)*100;'
    CLOSE = DataFrame['close']
    LC = REF(CLOSE, 1)
    RSI1 = SMA(MAX(CLOSE - LC, 0), N1) / SMA(ABS(CLOSE - LC), N1) * 100
    RSI2 = SMA(MAX(CLOSE - LC, 0), N2) / SMA(ABS(CLOSE - LC), N2) * 100
    RSI3 = SMA(MAX(CLOSE - LC, 0), N3) / SMA(ABS(CLOSE - LC), N3) * 100
    DICT = {'RSI1': RSI1, 'RSI2': RSI2, 'RSI3': RSI3}

    return pd.DataFrame(DICT)
  • $Relative\ Strength\ Index$
    • 相对强弱指标 $RSI$ 是根据一定时期内上涨点数和下跌点数之和的比率制作出的一种技术曲线
    • 能够反映出市场在一定时期内的景气程度
    • 由威尔斯.威尔德(Welles Wilder)最早应用于期货买卖
    • 后来人们发现在众多的图表技术分析中,强弱指标的理论和实践极其适合于股票市场的短线投资,于是被用于股票升跌的测量和分析中
    • 该分析指标的设计是以三条线来反映价格走势的强弱
    • 这种图形可以为投资者提供操作依据,非常适合做短线差价操作
In [326]:
QA_indicator_RSI(tt, N1=12, N2=26, N3=9)
Out[326]:
RSI1 RSI2 RSI3
date code
2021-05-06 000948 100.000000 100.000000 100.000000
2021-05-07 000948 100.000000 100.000000 100.000000
2021-05-10 000948 100.000000 100.000000 100.000000
2021-05-11 000948 100.000000 100.000000 100.000000
2021-05-12 000948 100.000000 100.000000 100.000000
... ... ... ... ...
2021-09-06 000948 60.852967 56.376790 61.975583
2021-09-07 000948 60.357020 56.187162 61.277191
2021-09-08 000948 65.158455 58.440559 67.636600
2021-09-09 000948 57.123874 55.292189 56.520325
2021-09-10 000948 56.661931 55.105073 55.893983

91 rows × 3 columns

QA.QA_indicator_ADTM(DataFrame, N, M)

In [328]:
def QA_indicator_ADTM(DataFrame, N=23, M=8):
    '动态买卖气指标'
    HIGH = DataFrame.high
    LOW = DataFrame.low
    OPEN = DataFrame.open
    # 如果开盘价大于昨日开盘价,取 今日最高价与开盘价之差,与今日开盘价与昨日开盘价之差,中的最大值
    DTM = IF(OPEN > REF(OPEN, 1), MAX((HIGH - OPEN), (OPEN - REF(OPEN, 1))), 0)
    # 如果开盘价小于昨日开盘价,取 今日开盘价与最低价之差,与今日开盘价与昨日开盘价之差,中的最大值
    DBM = IF(OPEN < REF(OPEN, 1), MAX((OPEN - LOW), (OPEN - REF(OPEN, 1))), 0)
    # 计算的到 N 的合计数
    STM = SUM(DTM, N)
    SBM = SUM(DBM, N)
    # 考虑三种情况:大于、不等于、等于,来分别计算差值率,以更大的值为分母
    # 如若等于,取 0
    ADTM1 = IF(STM > SBM, (STM - SBM) / STM,
               IF(STM != SBM, (STM - SBM) / SBM, 0))
    # 上述值 的 M 日均值
    MAADTM = MA(ADTM1, M)
    DICT = {'ADTM': ADTM1, 'MAADTM': MAADTM}

    return pd.DataFrame(DICT)
  • 动态买卖气指标(ADTM)
    • 用开盘价的向上波动幅度和向下波动幅度的距离差值来描述人气高低的指标
In [329]:
QA_indicator_ADTM(tt, N=23, M=8)
Out[329]:
ADTM MAADTM
date code
2021-05-06 000948 NaN NaN
2021-05-07 000948 NaN NaN
2021-05-10 000948 NaN NaN
2021-05-11 000948 NaN NaN
2021-05-12 000948 NaN NaN
... ... ... ...
2021-09-06 000948 0.473684 0.593123
2021-09-07 000948 0.542929 0.593792
2021-09-08 000948 0.547980 0.604486
2021-09-09 000948 0.567633 0.587508
2021-09-10 000948 0.514925 0.567728

91 rows × 2 columns

QA.QA_indicator_DDI(DataFrame, N, N1, M, M1)

In [332]:
def QA_indicator_DDI(DataFrame, N=13, N1=26, M=1, M1=5):
    """
    '方向标准离差指数'
    分析DDI柱状线,由红变绿(正变负),卖出信号参考;由绿变红,买入信号参考。
    """

    H = DataFrame['high']
    L = DataFrame['low']
    DMZ = IF((H + L) > (REF(H, 1) + REF(L, 1)), MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1))), 0)
    DMF = IF((H + L) < (REF(H, 1) + REF(L, 1)), MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1))), 0)
    DIZ = SUM(DMZ, N) / (SUM(DMZ, N) + SUM(DMF, N))
    DIF = SUM(DMF, N) / (SUM(DMF, N) + SUM(DMZ, N))
    ddi = DIZ - DIF
    ADDI = SMA(ddi, N1, M)
    AD = MA(ADDI, M1)
    DICT = {'DDI': ddi, 'ADDI': ADDI, 'AD': AD}
#     DICT = {'DMZ': DMZ, 'DMF': DMF, 'AD': AD} # 虽然公式相同,值却不同

    return pd.DataFrame(DICT)
  • $Direction\ standard\ Deviation\ Index$
  • 原理
    • $TR$ =(最高价-昨日最高价)的绝对值与(最低价-昨日最低价)的绝对值两者之间较大者
      • 如果(最高价+最低价)<=(昨日最高价+昨日最低价),$DMZ$ = 0
      • 如果(最高价+最低价)>(昨日最高价+昨日最低价),$DMZ$ =(最高价-昨日最低价)的绝对值与(最低价-昨日最低价)的绝对值中较大值
      • 如果(最高价+最低价)>=(昨日最高价+昨日最低价),$DMF$ = 0
      • 如果(最高价+最低价)<(昨日最高价+昨日最低价),$DMF$ =(最高价-昨日最低价)的绝对值与(最低价-昨日最低价)的绝对值中较大值
    • $DIZ$ = N个周期DMZ的和 /(N个周期DMZ的和 + N个周期DMF的和)
    • $DIF$ = N个周期DMF的和 /(N个周期DMF的和 + N个周期DMZ的和)
    • $DDI$ = DIZ - DIF
    • $ADDI$ = DDI 在一定周期内的加权平均
    • $AD$ = ADDI 在一定周期内的简单移动平均
  • 公式
    • $TR := MAX(ABS(H-REF(H,1)),ABS(L-REF(L,1)))$
    • $DMZ := IF((H+L)<=(REF(H,1)+REF(L,1)),0,MAX(ABS(H-REF(H,1)),ABS(L-REF(L,1))))$
    • $DMF := IF((H+L)>=(REF(H,1)+REF(L,1)),0,MAX(ABS(H-REF(H,1)),ABS(L-REF(L,1))))$
    • $DIZ := SUM(DMZ,N)/(SUM(DMZ,N)+SUM(DMF,N))$
    • $DIF := SUM(DMF,N)/(SUM(DMF,N)+SUM(DMZ,N))$
    • $DDI : DIZ-DIF,COLORSTICK$
    • $ADDI : SMA(DDI,N1,M)$
    • $AD : MA(ADDI,M1)$
  • 用法
    • 分析 $DDI$ 柱状线,由红变绿(正变负),卖出信号;由绿变红,买入信号
    • $ADDI$ 与 $AD$ 的交叉情况以及背离情况
In [333]:
QA_indicator_DDI(tt, N=13, N1=26, M=1, M1=5)
Out[333]:
DDI ADDI AD
date code
2021-05-06 000948 NaN NaN NaN
2021-05-07 000948 NaN NaN NaN
2021-05-10 000948 NaN NaN NaN
2021-05-11 000948 NaN NaN NaN
2021-05-12 000948 NaN NaN NaN
... ... ... ... ...
2021-09-06 000948 0.231183 0.126901 0.116204
2021-09-07 000948 0.161290 0.128223 0.121645
2021-09-08 000948 0.320872 0.135633 0.126269
2021-09-09 000948 0.294498 0.141743 0.131046
2021-09-10 000948 0.290323 0.147458 0.135992

91 rows × 3 columns

QA.QA_indicator_CCI(DataFrame, N=14)

In [334]:
def QA_indicator_CCI(DataFrame, N=14):
    """
    TYP:=(HIGH+LOW+CLOSE)/3;
    CCI:(TYP-MA(TYP,N))/(0.015*AVEDEV(TYP,N));
    """
    typ = (DataFrame['high'] + DataFrame['low'] + DataFrame['close']) / 3
    ## 此处AVEDEV可能为0值  因此导致出错 +0.0000000000001
    cci = ((typ - MA(typ, N)) / (0.015 * AVEDEV(typ, N) + 0.00000001))
    a = 100
    b = -100

    return pd.DataFrame({
        'CCI': cci, 'a': a, 'b': b
    })
  • 顺势指标CCI
    • 原用于测量股价、外汇或者贵金属交易是否已超出常态分布范围
    • 属于超买超卖类指标中较特殊的一种
    • 波动于正无穷大和负无穷大之间
    • 但是,又不需要以0为中轴线,这一点也和波动于正无穷大和负无穷大的指标不同
  • 与大多数单一利用股票的收盘价开盘价最高价最低价而发明出的各种技术分析指标不同
    • CCI指标是根据统计学原理
    • 引进价格与固定期间的股价平均区间偏离程度的概念
    • 强调股价平均绝对偏差在股市技术分析中的重要性,是一种比较独特的技术指标
In [335]:
QA_indicator_CCI(tt, N=14)
Out[335]:
CCI a b
date code
2021-05-06 000948 NaN 100 -100
2021-05-07 000948 NaN 100 -100
2021-05-10 000948 NaN 100 -100
2021-05-11 000948 NaN 100 -100
2021-05-12 000948 NaN 100 -100
... ... ... ... ...
2021-09-06 000948 60.965186 100 -100
2021-09-07 000948 58.200962 100 -100
2021-09-08 000948 75.557219 100 -100
2021-09-09 000948 52.277850 100 -100
2021-09-10 000948 25.142535 100 -100

91 rows × 3 columns

自定义指标

绝路航标

  • JLHB,即绝路航标(趋势型),为反趋势类选股指标
    • 综合了动量观念、强弱指标与移动平均线的优点
    • 在计算过程中主要研究高低价位收市价的关系
    • 反映价格走势的强弱和超买超卖现象
    • 在市场短期超买超卖的预测方面又较敏感
In [336]:
def JLHB(data, m=7, n=5):
    """
    通达信定义
    VAR1:=(CLOSE-LLV(LOW,60))/(HHV(HIGH,60)-LLV(LOW,60))*80; 
    B:SMA(VAR1,N,1); 
    VAR2:SMA(B,M,1); 
    绝路航标:IF(CROSS(B,VAR2) AND B<40,50,0);
    """
    var1 = (data['close'] - QA.LLV(data['low'], 60)) / \
        (QA.HHV(data['high'], 60) - QA.LLV(data['low'], 60)) * 80
    B = QA.SMA(var1, m)
    var2 = QA.SMA(B, n)
    return pd.DataFrame({'JLHB':QA.CROSS(B,var2)*(B<40)})
In [337]:
QA.QA_fetch_stock_day_adv('000001','2017-01-01','2017-05-31').to_qfq()
Out[337]:
< QA_DataStruct_Stock_day with 1 securities >
In [338]:
QA.QA_fetch_stock_day_adv('000001','2017-01-01','2017-05-31').to_qfq().data
Out[338]:
open high low close volume amount adj
date code
2017-01-03 000001 8.530554 8.596102 8.511826 8.577374 459840.0 4.205952e+08 0.936395
2017-01-04 000001 8.568010 8.596102 8.558646 8.577374 449329.0 4.115035e+08 0.936395
2017-01-05 000001 8.586738 8.596102 8.568010 8.586738 344372.0 3.157697e+08 0.936395
2017-01-06 000001 8.586738 8.586738 8.530554 8.549282 358154.0 3.271764e+08 0.936395
2017-01-09 000001 8.549282 8.586738 8.530554 8.568010 361081.0 3.299946e+08 0.936395
... ... ... ... ... ... ... ... ...
2017-05-23 000001 8.118540 8.277727 8.090449 8.230908 800040.0 7.021238e+08 0.936395
2017-05-24 000001 8.221544 8.268363 8.127904 8.249636 532376.0 4.665606e+08 0.936395
2017-05-25 000001 8.230908 8.558646 8.221544 8.521190 1621543.0 1.462763e+09 0.936395
2017-05-26 000001 8.502462 8.549282 8.465006 8.521190 895365.0 8.133872e+08 0.936395
2017-05-31 000001 8.521190 8.642921 8.483734 8.614829 1033210.0 9.487419e+08 0.936395

97 rows × 7 columns

In [ ]:
 
In [339]:
QA.QA_fetch_stock_day_adv('000001','2017-01-01','2017-05-31').to_qfq().add_func(JLHB)
Out[339]:
JLHB
date code
2017-03-31 000001 0
2017-04-05 000001 0
2017-04-06 000001 0
2017-04-07 000001 0
2017-04-10 000001 0
2017-04-11 000001 0
2017-04-12 000001 0
2017-04-13 000001 0
2017-04-14 000001 0
2017-04-17 000001 0
2017-04-18 000001 0
2017-04-19 000001 0
2017-04-20 000001 0
2017-04-21 000001 0
2017-04-24 000001 0
2017-04-25 000001 0
2017-04-26 000001 0
2017-04-27 000001 0
2017-04-28 000001 0
2017-05-02 000001 0
2017-05-03 000001 0
2017-05-04 000001 0
2017-05-05 000001 0
2017-05-08 000001 0
2017-05-09 000001 0
2017-05-10 000001 0
2017-05-11 000001 0
2017-05-12 000001 1
2017-05-15 000001 0
2017-05-16 000001 0
2017-05-17 000001 0
2017-05-18 000001 0
2017-05-19 000001 0
2017-05-22 000001 0
2017-05-23 000001 0
2017-05-24 000001 0
2017-05-25 000001 0
2017-05-26 000001 0
2017-05-31 000001 0

金叉死叉

In [340]:
def MACD_JCSC(dataframe, SHORT=12, LONG=26, M=9):
    """
    1.DIF向上突破DEA,买入信号参考。
    2.DIF向下跌破DEA,卖出信号参考。
    """
    CLOSE = dataframe.close
    DIFF = QA.EMA(CLOSE, SHORT) - QA.EMA(CLOSE, LONG)
    DEA = QA.EMA(DIFF, M)
    MACD = 2*(DIFF-DEA)

    CROSS_JC = QA.CROSS(DIFF, DEA)
    CROSS_SC = QA.CROSS(DEA, DIFF)
    ZERO = 0
    return pd.DataFrame({'DIFF': DIFF, 'DEA': DEA, 'MACD': MACD, 'CROSS_JC': CROSS_JC, 'CROSS_SC': CROSS_SC, 'ZERO': ZERO})
In [346]:
QA.QA_fetch_stock_day_adv('000948','2021-01-01','2021-09-10').to_qfq().add_func(MACD_JCSC)
Out[346]:
DIFF DEA MACD CROSS_JC CROSS_SC ZERO
date code
2021-01-04 000948 NaN NaN NaN 0 0 0
2021-01-05 000948 NaN NaN NaN 0 0 0
2021-01-06 000948 NaN NaN NaN 0 0 0
2021-01-07 000948 NaN NaN NaN 0 0 0
2021-01-08 000948 NaN NaN NaN 0 0 0
... ... ... ... ... ... ... ...
2021-09-06 000948 0.278406 0.190576 0.175660 0 0 0
2021-09-07 000948 0.279076 0.208276 0.141600 0 0 0
2021-09-08 000948 0.301149 0.226851 0.148598 0 0 0
2021-09-09 000948 0.288687 0.239218 0.098938 0 0 0
2021-09-10 000948 0.274038 0.246182 0.055712 0 0 0

170 rows × 6 columns

QUANTAXIS的指标类 QA_DataStruct_Indicators()

指标类可以直接加载计算出来的指标

In [349]:
ind=tt.add_func(QA.QA_indicator_WR,1,2)
inc=QA.QA_DataStruct_Indicators(ind)
inc.data
Out[349]:
WR1 WR2
date code
2021-05-06 000948 32.941176 NaN
2021-05-07 000948 57.377049 36.082474
2021-05-10 000948 15.217391 11.111111
2021-05-11 000948 0.000000 0.000000
2021-05-12 000948 0.000000 0.000000
... ... ... ...
2021-09-06 000948 27.027027 51.785714
2021-09-07 000948 51.515152 40.476190
2021-09-08 000948 0.000000 0.000000
2021-09-09 000948 93.750000 84.615385
2021-09-10 000948 38.709677 62.745098

91 rows × 2 columns

获取一段时段时间的某个股票的指标序列

In [351]:
inc.get_timerange('2021-09-07','2021-09-12','000948')
Out[351]:
WR1 WR2
date code
2021-09-07 000948 51.515152 40.476190
2021-09-08 000948 0.000000 0.000000
2021-09-09 000948 93.750000 84.615385
2021-09-10 000948 38.709677 62.745098

获取一个股票的指标序列

In [353]:
inc.get_code('000948')
Out[353]:
WR1 WR2
date code
2021-05-06 000948 32.941176 NaN
2021-05-07 000948 57.377049 36.082474
2021-05-10 000948 15.217391 11.111111
2021-05-11 000948 0.000000 0.000000
2021-05-12 000948 0.000000 0.000000
... ... ... ...
2021-09-06 000948 27.027027 51.785714
2021-09-07 000948 51.515152 40.476190
2021-09-08 000948 0.000000 0.000000
2021-09-09 000948 93.750000 84.615385
2021-09-10 000948 38.709677 62.745098

91 rows × 2 columns