掘金社区

【掘金使用技巧8】用掘金编写常用技术指标Pinned highlighted

四两 发表在策略研究 2021-01-15 09:21:56

策略研究
1431
4
0

掘金中缺少一些常用的技术指标函数,但在编写策略时,免不了要用到指数指标来帮助决策。因此,小编汇总了几个常用的技术指标,基于掘金的框架编写成函数,大家可以在使用时参考一下。

提示:

行情软件比如通达信的一些指标都是基于股票上市首日计算得到的,如果计算时只用小部分的时间序列,得到的结果和通达信软件是不一致的。为了保持一致,所有指标都按照上市首日计算。

前期准备

# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *
import pandas as pd
import numpy as np


set_token('请输入你的token')

KDJ指标

# KDJ指标计算
# 原理:计算N日RSV = (今日收盘 - N日最低)/(N日最高-N日最低) * 100
# K = (1-(1/M1))*前一日K值 + 1/M1 * RSV
# D = (1-(1/M1))*前一日D值 + 1/M1 * K值
# J = 3 * K - 2 * D

def KDJ(symbol, N, M1, M2,end_time):
    '''
    计算KDJ指标公式
    输入: data <- dataframe,需包含开盘、收盘、最高、最低价
          N、M1、M2 <- int
          end_time <- str   结束时间
    输出: 将K、D、J合并到data后的dataframe
    '''

    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close,low,high',
                   df=True)

    # 计算前N日最低和最高,缺失值用前n日(n<N)最小值替代
    lowList = data['low'].rolling(N).min()
    lowList.fillna(value=data['low'].expanding().min(), inplace=True)
    highList = data['high'].rolling(N).max()
    highList.fillna(value=data['high'].expanding().max(), inplace=True)
    # 计算rsv
    rsv = (data['close'] - lowList) / (highList - lowList) * 100
    # 计算k,d,j
    data['kdj_k'] = rsv.ewm(alpha=1/M1, adjust=False).mean()     # ewm是指数加权函数
    data['kdj_d'] = data['kdj_k'].ewm(alpha=1/M2, adjust=False).mean()
    data['kdj_j'] = 3.0 * data['kdj_k'] - 2.0 * data['kdj_d']
    return data

# 测试一下
d = KDJ('DCE.y2101',9,3,3,'2020-12-31')

MACD指标

# MACD指标计算
# 计算12日和26日的EMA数据
# 计算12日EMA:EMA(12) = 2/(12+1) * 今日收盘价(12) + 11/(12+1) * 昨日EMA(12)
# 计算26日EMA:EMA(26) = 2/(26+1) * 今日收盘价(26) + 25/(26+1) * 昨日EMA(26)
# 计算DEA:DEA = 2/(9+1) * 今日DIFF + 8/(9+1) * 昨日DEA
# 计算MACD:MACD = 2 * (DIFF-DEA)
# 注意:上市首日DIFF、DEA、MACD均为0,次日的EMA均按照上市首日的收盘价计算

def MACD(symbol, start_time, end_time):
    '''计算MACD指标
        输入参数:symbol <- str      标的代码 (2005年以前上市的不可用)
                start_time <- str  起始时间
                end_time <- str    结束时间
        输出数据:
                macd <- dataframe  macd指标,包括DIFF、DEA、MACD

    '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close',
                   df=True)
    # 将数据转化为dataframe格式
    data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 计算EMA(12)和EMA(16)
    data['EMA12'] = data['close'].ewm(alpha=2 / 13, adjust=False).mean()
    data['EMA26'] = data['close'].ewm(alpha=2 / 27, adjust=False).mean()

    # 计算DIFF、DEA、MACD
    data['DIFF'] = data['EMA12'] - data['EMA26']
    data['DEA'] = data['DIFF'].ewm(alpha=2 / 10, adjust=False).mean()
    data['MACD'] = 2 * (data['DIFF'] - data['DEA'])

    # 上市首日,DIFF、DEA、MACD均为0
    data['DIFF'].iloc[0] = 0
    data['DEA'].iloc[0] = 0
    data['MACD'].iloc[0] = 0

    # 按照起止时间筛选
    MACD = data[(data['bob'] >= start_time)]

    return MACD

# 测试一下
a = MACD(symbol = 'DCE.y2101',start_time = '2020-01-01',end_time = '2020-10-22')

DMA指标

# DMA指标计算
# 计算DIF: close的N1日移动平均-close的N2日移动平均
# 计算AMA: DIF的M日移动平均

def DMA(symbol, start_time, end_time, N1, N2, M):
    ''' 计算DMA
        输入参数:
            symbol <- str  标的代码
            start_time <- str  开始时间
            end_time <- 结束时间
            N1 <- 大周期均值
            N2 <- 小周期均值
        输出参数:
            DMA <- dataframe
    '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close',
                   df=True)
    data['MA1'] = data['close'].rolling(N1).mean()
    data['MA2'] = data['close'].rolling(N2).mean()
    data['DIF'] = data['MA1'] - data['MA2']
    data['AMA'] = data['DIF'].rolling(M).mean()

    # 将数据转化为dataframe格式
    data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 按起止时间筛选
    DMA = data[(data['bob'] >= start_time)]

    return DMA

# 测试一下
d1 = DMA(symbol = 'DCE.y2101',start_time = '2020-01-01',end_time = '2020-10-22',N1 = 10,N2 = 50,M = 6)

BIAS指标

# BIAS:乖离率指标计算
# BIAS1 : (CLOSE-N1日的平均值CLOSE)/N1日的平均值CLOSE*100
# BIAS2 : (CLOSE-N2日的平均值CLOSE)/N2日的平均值CLOSE*100
# BIAS3 : (CLOSE-N3日的平均值CLOSE)/N3日的平均值CLOSE*100

def BIAS(symbol, start_time, end_time, N1, N2, N3):
    '''计算乖离率指标
        输入值:symbol <- str 标的代码
              start_time <- str 开始时间
              end_time <- str 结束时间
              N1、N2、N3 <- 移动平均数
        输出值:
            BIAS <- dataframe
    '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close',
                   df=True)

    # 将数据转化为dataframe格式
    data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 计算指标
    data['BIAS1'] = (data['close'] - data['close'].rolling(N1).mean())/data['close'].rolling(N1).mean() * 100
    data['BIAS2'] = (data['close'] - data['close'].rolling(N2).mean())/data['close'].rolling(N2).mean() * 100
    data['BIAS3'] = (data['close'] - data['close'].rolling(N3).mean())/data['close'].rolling(N3).mean() * 100

    # 按时间筛选
    BIAS = data[(data['bob'] >= start_time)]

    return BIAS

# 测试一下
d2 = BIAS(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1=6, N2=12, N3=24)

BOLL指标

# BOLL:BOLL带指标计算
# 中轨线 = N日收盘价平均值
# 上轨线 = 中轨线 + N日收盘价标准差
# 下轨线 = 中轨线 - N日收盘价标准差
def BOLL(symbol, start_time, end_time, N):
    ''' 计算布林带
        输入参数:symbol <- str 标的代码
                start_time <- str 开始日期
                end_time <- str 结束日期
                N <- N日移动平均线
        输出参数:
               BOLL <- dataframe
    '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close',
                   adjust=ADJUST_PREV, adjust_end_time=end_time, df=True)

    # 将数据转化为dataframe格式
    data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 计算指标
    data['BOLL'] = data['close'].rolling(N).mean()
    data['UB'] = data['BOLL'] + 2 * data['close'].rolling(N).std()
    data['LB'] = data['BOLL'] - 2 * data['close'].rolling(N).std()

    # 按时间筛选
    BOLL = data[(data['bob'] >= start_time)]

    return BOLL

# 测试一下
d3 = BOLL(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N=20)

RSI指标

# RSI指标计算
# RSI = N日内收盘价涨数和的均值/N日内收盘价涨和跌的均值*100
def RSI(symbol, start_time, end_time, N1, N2, N3):
    ''' 计算RSI相对强弱指数
        输入参数:symbol <- str 标的代码
                start_time <- str 开始日期
                end_time <- str 结束日期
                N <- N日移动平均线
        输出参数:
               RSI <- dataframe
    '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time, fields='symbol,bob,close,pre_close',
                   adjust=ADJUST_PREV, adjust_end_time=end_time, df=True)

    # 将数据转化为dataframe格式
    data['bob'] = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 计算指标
    data['change'] = data['close'] - data['pre_close']          # 计算涨跌幅
    data.loc[(data['pre_close'] == 0), 'change'] = 0            # 如果是首日,change记为0
    data['x'] = data['change'].apply(lambda x: max(x, 0))       # 涨跌幅<0换为0
    data['RSI1'] = data['x'].ewm(alpha=1 / N1, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1/N1, adjust=False).mean()) * 100
    data['RSI2'] = data['x'].ewm(alpha=1 / N2, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1 / N2, adjust=False).mean()) * 100
    data['RSI3'] = data['x'].ewm(alpha=1 / N3, adjust=False).mean() / (np.abs(data['change']).ewm(alpha=1 / N3, adjust=False).mean()) * 100


    # 输出
    RSI = data[(data['bob'] >= start_time)]

    return RSI

# 测试一下
d4 = RSI(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1=6, N2=12, N3=24)

威廉指标WR

# WR威廉指标计算
# WR(N) = 100 * [HIGH(N)-C] / [HIGH(N)-LOW(N)]
def WR(symbol, start_time, end_time, N1, N2):
    ''' 计算威廉指数
        输入:symbol <- str 标的代码
             start_time <- str 开始时间
             end_time <- 结束时间
             N <- 周期数
        输出:WR <- dataframe
        '''
    # 取历史数据,取到上市首日
    data = history(symbol=symbol, frequency='1d', start_time='2005-01-01', end_time=end_time,
                   fields='symbol,bob,close,high,low',
                   adjust=ADJUST_PREV, adjust_end_time=end_time, df=True)
    # 计算指标
    data['WR1'] = 100 * (data['high'].rolling(N1).max() - data['close']) / (data['high'].rolling(N1).max() - data['low'].rolling(N1).min())
    data['WR2'] = 100 * (data['high'].rolling(N2).max() - data['close']) / (data['high'].rolling(N2).max() - data['low'].rolling(N2).min())

    # 缺失值填充
    data['WR1'].fillna(value=100 * (data['high'].expanding().max() - data['close']) / (data['high'].expanding().max() - data['low'].expanding().min()), inplace=True)
    data['WR2'].fillna(value=100 * (data['high'].expanding().max() - data['close']) / (data['high'].expanding().max() - data['low'].expanding().min()), inplace=True)
    # 输出
    WR = data[(data['bob'] >= start_time)]

    return WR

# 测试一下
d5 = WR(symbol='DCE.y2101', start_time='2020-01-01', end_time='2020-10-22', N1 = 10,N2 = 6)

评论: 4

Looks like your connection to 掘金量化社区 - 量化交易者的交流社区 was lost, please wait while we try to reconnect.