IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 惊呆了探究如果机器用KDJ法对股票进行做套的胜率竟高达%80 -> 正文阅读

[Python知识库]惊呆了探究如果机器用KDJ法对股票进行做套的胜率竟高达%80

做套:惊呆了!探究如果机器用KDJ法对股票进行做套的胜率,竟高达%80。

前言:

接上一篇:惊呆了,探究如果机器用MACD法对股票进行做套的胜率,竟高达%80

今天在整理自研量化系统的代码屎山时,也无意间想记录一下如果仅仅严格按照KDJ法对买入的股票进行做套,胜率将会是多少呢?

接下来就来尝试一下,首先得简单了解一下什么是KDJ,这个我也不多解释了,“dddd”,所以简单百度百科一下:随机指标KDJ一般是用于股票分析的统计体系,根据统计学原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV,然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。

简单了解完之后就可以开始实现了:

  • 第一步导入数据:
    df = pd.read_csv("2021-11-19.csv")
    

    这里用一下2021年11月19号的上证A股所有股票的日分钟数据

    在这里插入图片描述

    忽略’code’列股票代码显示不全的问题,从数据库备份转csv时没注意code特征列数值的属性,但对这次实验不造成影响,后期把“0”补回去就好了,就是csv保存时把前面的“0”都去掉了,数据量有54w条,足够大了。

  • 构造计算KDJ的函数

    这里就需要用到kdj的公式了

    • 自己查,很简单的

    完整的计算kdj函数的代码为:

    def CalculateKDJ(price_list, _kdj):
        """
        :param price_list: 
        :param _kdj: 列表 例如 [0, 0, 0]
        :return:
        """
        RSV = 0
        if max(price_list) - min(price_list) != 0:
            RSV = (price_list[-1] - min(price_list)) / (max(price_list) - min(price_list)) * 100
        K = 2 / 3 * _kdj[0] + 1 / 3 * RSV
        D = 2 / 3 * _kdj[1] + 1 / 3 * K
        J = 3 * K - 2 * D
        return [round(K, 2), round(D, 2), round(J, 2)]
    
  • 此外,还利用sklearn的线性模型库linear_model构造一个可以计算一段时间内价格变动趋势的函数,其实就是分析线性方程组的斜率,从而得知在这段时间,价格变动的趋势

    def CalculateTrend(price_list):
        """
        :param price_list: 
        :return:
        """
        regr = linear_model.LinearRegression()
        X = list()
        for x in range(1, len(price_list) + 1):
            X.append([x])
        regr.fit(X, price_list)
        return regr.coef_.tolist()[0]
    
  • 重头戏来了,函数都备好了,万事俱备只欠东风,得构造一个逻辑函数或称为步骤函数去利用数据然后作出决策,然后再判断决策是否正确

    • 做套的两件大事(不要做反套):

      • 卖的时候比原本持仓价格要高
      • 买的时候比原本持仓价格要低

      因此在函数中设置一个阈值"threshold"来从当这个原本持仓价格

    • 初始值设立:

      • Ki-1表示前一天的K值,若无前一天的K值,则用50来代替。Di-1表示前一天的D值,若无前一天的D值,则用50来代替。所以初始KDJ设为[50,50,0]。
      • 原本持仓价格我们不可能每一个股票都输入一个持仓价格,因此我将持仓价格设置为当天开盘的数据,其实原本持仓价格只是从当一个阈值效果,帮助我们不要做反套,所以这样设立也确实没多大问题。
      • 不设立买入和卖出限制的股数,因为要尽可能的多测试样例,但这在现时中是不合理的,因为我们买入卖出的股份不可能是无限多。所以在想要使用的时候,可以添加一个限制操作股数的值,当买或卖达到了这个值,就不能也不用再操作这只股票了

      但KDJ就是遵循多种操作方式:

      # K与D值永远介于0到100之间。D大于80时,行情呈现超买现象。D小于20时,行情呈现超卖现象。
      
      # J指标取值超过100和低于0,都属于价格的非正常区域,大于100为超买,小0为超卖。
      # 当K值由较小逐渐大于D值,在图形上显示K线从下方上穿D线,所以在图形上K线向上突破D线时,俗称金叉,即为买进的讯号
      # 当K值由较大逐渐小于D值,在图形上显示K线从上方下穿D线,所以在图形上K线向下突破D线时,俗称死叉,即为卖出的讯号
      

      为了探究其中哪个更适合用于"做套",可以把它看成超短期交易,所以可视化一下KDJ的分布规律:

      • 首先获取到全部的股票的日KDJ全部数据
        data = {'K':list(),'D':list(),'J':list()}
        for code in set(df['code'].to_list()):
        price_list = df[df['code'] == code]['最新价'].to_list()
        
        threshold = price_list[0]
        # Ki-1表示前一天的K值,若无前一天的K值,则用50来代替。
        # Di-1表示前一天的D值,若无前一天的D值,则用50来代替。
        _KDJ = [50, 50, 0]
        for i in range(9, len(price_list), 9):
            KDJ = CalculateKDJ(price_list[i - 9:i], _kdj=_KDJ)
            data['K'].append(KDJ[0])
            data['D'].append(KDJ[1])
            data['J'].append(KDJ[2])
            _KDJ = KDJ
        data = pd.DataFrame(data)
        

      在这里插入图片描述

      随随便便看看吧,会的也不是很多,看一下每列分布吧:

      从左往右依次为K,D,J的分布情况:

      在这里插入图片描述

      • 符合:K与D值永远介于0到100之间,J指标可超过100和低于0

        但对于D大于80时,行情呈现超买现象。D小于20时,行情呈现超卖现象。根据数据列分布情况,我觉得这个可能对于超短期帮助不大,因此待会实验,也添加一个条件试验一下就好了。

      D值和J值的变化曲线:

    在这里插入图片描述

    然后我叠加了一个用于判断趋势的函数:

    • 当判断到买时趋势是向下的(<0),则放弃购买

    • 当判断到卖时趋势是向上的(>0),则放弃售卖

    判断胜负的方式用,买入(卖出)时的价格低于(高于)接下来10分钟的平均价,则判为胜。

        for code in tqdm(set(df['code'].to_list())):
            price_list = df[df['code'] == code]['最新价'].to_list()
            r = 0
            t = 0
            threshold = price_list[0]
            # Ki-1表示前一天的K值,若无前一天的K值,则用50来代替。
            # Di-1表示前一天的D值,若无前一天的D值,则用50来代替。
            _KDJ = [50, 50, 0]
            for i in range(5, len(price_list), 5):
                KDJ = CalculateKDJ(price_list[i - 5:i], _kdj=_KDJ)
                if price_list[i] < threshold:
                    if KDJ[2] >= 100:
                        if CalculateTrend(price_list[i - 5:i]) > 0:
                            buy['code'].append(code)
                            buy['买入价'].append(price_list[i])
                            buy['买入后十分钟平均价:'].append(np.mean(price_list[i + 1:i + 11]))
                            r += 1 if price_list[i] <= np.mean(price_list[i + 1:i + 11]) else -1
                            t += 1
                if price_list[i] > threshold:
                    if KDJ[2] <= 0:
                        if CalculateTrend(price_list[i - 5:i]) < 0:
                            sell['code'].append(code)
                            sell['卖出价'].append(price_list[i])
                            sell['卖出后十分钟平均价:'].append(np.mean(price_list[i + 1:i + 11]))
                            r += 1 if price_list[i] >= np.mean(price_list[i + 1:i + 11]) else -1
                            t += 1
                _KDJ = KDJ
            if t != 0:
                rate['code'].append(code)
                rate['胜率'].append(r / t)
    

    一通捣鼓下来,观看实验效果:

    • 仅用“J指标取值超过100和低于0,都属于价格的非正常区域,大于100为超买,小0为超卖。”

      胜率为在这里插入图片描述

    • 用“J指标取值超过100和低于0,都属于价格的非正常区域,大于100为超买,小0为超卖。”和

      D大于80时,行情呈现超买现象。D小于20时,行情呈现超卖现象。“胜率为在这里插入图片描述

      ,反而降低了

    • 用“当K值由较小逐渐大于D值,在图形上显示K线从下方上穿D线,所以在图形上K线向上突破D线时,俗称金叉,即为买进的讯号”和“当K值由较大逐渐小于D值,在图形上显示K线从上方下穿D线,所以在图形上K线向下突破D线时,俗称死叉,即为卖出的讯号”胜率为在这里插入图片描述
      可见J值更敏感,对于这种“日内做套”的手段,胜率显得更高一点。

完整代码:

import pandas as pd
from sklearn import linear_model
from tqdm import tqdm
import numpy as np


def CalculateKDJ(price_list, _kdj):
    """
    :param price_list: 
    :param _kdj: 列表 例如 [0, 0, 0]
    :return:
    """

    RSV = 0
    if max(price_list) - min(price_list) != 0:
        RSV = (price_list[-1] - min(price_list)) / (max(price_list) - min(price_list)) * 100

    K = 2 / 3 * _kdj[0] + 1 / 3 * RSV

    D = 2 / 3 * _kdj[1] + 1 / 3 * K

    J = 3 * K - 2 * D

    return [round(K, 2), round(D, 2), round(J, 2)]


def CalculateTrend(price_list):
    """
    :param price_list: 
    :return:
    """
    regr = linear_model.LinearRegression()
    X = list()
    for x in range(1, len(price_list) + 1):
        X.append([x])
    regr.fit(X, price_list)
    return regr.coef_.tolist()[0]


if __name__ == '__main__':

    # K与D值永远介于0到100之间。D大于80时,行情呈现超买现象。D小于20时,行情呈现超卖现象。

    # J指标取值超过100和低于0,都属于价格的非正常区域,大于100为超买,小0为超卖。
    # 当K值由较小逐渐大于D值,在图形上显示K线从下方上穿D线,所以在图形上K线向上突破D线时,俗称金叉,即为买进的讯号
    # 当K值由较大逐渐小于D值,在图形上显示K线从上方下穿D线,所以在图形上K线向下突破D线时,俗称死叉,即为卖出的讯号
    df = pd.read_csv("min_test_data.csv")

    buy = {'code': list(), '买入价': list(), '买入后十分钟平均价:': list()}
    sell = {'code': list(), '卖出价': list(), '卖出后十分钟平均价:': list()}
    rate = {'code': list(), '胜率': list()}
    for code in tqdm(set(df['code'].to_list())):

        price_list = df[df['code'] == code]['最新价'].to_list()

        r = 0
        t = 0

        threshold = price_list[0]
        # Ki-1表示前一天的K值,若无前一天的K值,则用50来代替。
        # Di-1表示前一天的D值,若无前一天的D值,则用50来代替。
        _KDJ = [50, 50, 0]

        for i in range(5, len(price_list), 5):
            KDJ = CalculateKDJ(price_list[i - 5:i], _kdj=_KDJ)
            if price_list[i] < threshold:

                if KDJ[2] >= 100:

                    if CalculateTrend(price_list[i - 5:i]) > 0:
                        buy['code'].append(code)
                        buy['买入价'].append(price_list[i])
                        buy['买入后十分钟平均价:'].append(np.mean(price_list[i + 1:i + 11]))
                        r += 1 if price_list[i] <= np.mean(price_list[i + 1:i + 11]) else -1
                        t += 1

            if price_list[i] > threshold:
                if KDJ[2] <= 0:

                    if CalculateTrend(price_list[i - 5:i]) < 0:
                        sell['code'].append(code)
                        sell['卖出价'].append(price_list[i])
                        sell['卖出后十分钟平均价:'].append(np.mean(price_list[i + 1:i + 11]))
                        r += 1 if price_list[i] >= np.mean(price_list[i + 1:i + 11]) else -1
                        t += 1

            _KDJ = KDJ

        if t != 0:
            rate['code'].append(code)
            rate['胜率'].append(r / t)

    buy = pd.DataFrame(buy)
    print(buy.head())
    sell = pd.DataFrame(sell)
    print(sell.head())
    rate = pd.DataFrame(rate)
    print(rate.head())
    print(rate['胜率'].sum() / len(rate))
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 17:37:39  更:2021-12-16 17:37:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:53:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码