美文网首页
julia分析股市的【春季躁动】(2)——集成多个指标后画图观察

julia分析股市的【春季躁动】(2)——集成多个指标后画图观察

作者: 昵称违法 | 来源:发表于2020-12-30 10:15 被阅读0次

    一、前言:

    用julia搜集了一些数据,并分析它们,最后显示在一个plot上,便于直观判断。

    以【中科曙光】为例,plot由四个部分组成
    【1】中科曙光历史上每年春季躁动的涨跌幅统计,统计的区间,用竖线画出来。
    【2】历史上每年Q3时,基金持股和较上一季报加减仓信息。
    【3】历史上每年中,各个季度的营业总收入
    【4】历史上每年中,各个季度的归母净利润

    image.png

    二、图形解析:

    【1】中科曙光自上市以来,一共经过6次春季躁动(2015-2020),其中2016年下跌,其它年份的春季躁动都是上涨,且涨幅最低8%,最高87%,近四年来的春季躁动,都是连续上涨,平均涨幅25%。
    【2】中科曙光股价最近处于低点,半年多来的低点。
    【3】2020Q3基金持仓站流通市值8.37%,其中基金加仓0.64%
    【4】今年的归母净利润预计略高于去年
    【5】今年的营业收入预计与去年持平

    结论:中科曙光可以纳入观察,春节前出现信号则买入。
    风险:关注贸易战、中美关系、科技制裁、军工、内循环需求、进口替代

    下图为【鲁北化工】:大家自己分析,我看了一眼,基金突然加仓,财务也比较靓,股价也不高,建议大家自己深挖。


    image.png

    三、julia画图代码

    我用的是julia1.4版本,GR对中文不支持,以前有版本支持,现在还没update,所以改用pyplot

    plot支持中文的设置

    pyplot对中文支持的设置如下:

    using PyCall
    
    py"""
    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.rcParams['font.sans-serif']=['SimHei'] #👈👈👈用来正常显示中文标签👈👈👈
    plt.rcParams['axes.unicode_minus']=False   #正常显示负号
    #plt.rcParams["figure.figsize"] = (20,10)  #设置图片的大小
    plt.figure(dpi = 300)  #设置分辨率
    plt.grid(True)         #添加图表网格线
    """
    
    

    把多个plot组成一个plot

    """
    画图:把四个图画到一个plot里面
    """
    function draw_plot(code,idx,path,stocks_dict,fund_df,revenue_profit_df)
        stock_df = stocks_dict[code]
        p_kline = draw_kline(stock_df,info_df,tasks_df,code)
    
        q_df = @linq fund_df |> where(:代码1 .== code)
        sort!(q_df,:躁动年份)
        p_fund = draw_fund_hoding(q_df)
    
        q_df = @linq revenue_profit_df |> where(:代码 .== code)
        p_profit = draw_profit(q_df)
        p_revenue = draw_revenue(q_df)
    
        p_all = plot(p_kline,p_fund,p_profit, p_revenue, layout = (4, 1), legend = false)
        display(p_all)
        savefig("$(path)/$(idx)-$(code).svg")
    end
    

    代码

    
    using CSV
    using DataFrames
    using DataFramesMeta
    using Dates
    using XLSX
    using Statistics
    using PyCall
    
    include("common.jl")
    
    #👉👉读取股票信息表👈👈
    info_df = DataFrame(XLSX.readtable("data/股票信息.xlsx","Sheet1")...)
    info_df[!,"stockID"] = info_df.证券代码 .|> stock -> split(stock,".")[1] |> string
    stocks = info_df.证券代码 |> unique
    info_df |> display
    
    codes = info_df.证券代码 |> unique .|> stock->split(stock,".")[1] |> string
    
    #👉👉读取开平仓的时间点👈👈
    kpc_df = DataFrame(XLSX.readtable("data/年份开平仓日期.xlsx","sheet1")...)
    kpc_df |> display
    
    kpc_dict = Dict()
    for r in eachrow(kpc_df)
        kpc_dict[r.年份] = (开仓日期 = r.开仓日期,平仓日期 = r.平仓日期)
    end
    kpc_dict |> display
    
    #👉👉读取股票的k线信息,装入dict中👈👈
    stocks_dict = Dict()
    for stock in codes
        println(stock)
        kind = "股票"
        stock = split(stock,".")[1] |> string
        if length(stock) < 6 #有港股代码,需要排除
            continue #for
        end
    
        kline_directory = "D:/juliaWorkSpace/k线"  #k线位置
        df = read_kline(kind, stock, kline_directory)
    
        #填补空值 ismissing的值,用上一个单元格的值来填补
        for idx = 1:size(df)[1]
            if idx > 1
                for col in names(df)
                    if ismissing(df[idx, col])
                        df[idx, col] = df[idx-1, col]
                    end
                end
            end
        end
    
        stocks_dict[stock] = df
    end
    
    stocks_dict
    
    """
    获取收盘价
    df:k线数据表
    """
    function get_close(df,date)
        q_df = @linq df |> where(:day .== date)
        if size(q_df,1) >0
            q_df[1,"close"]
        else
            NaN
        end
    end
    
    #get_close(stock_df,Date("2010-01-11"))
    
    using Plots
    #gr()
    pyplot()
    Plots.GRBackend()
    
    py"""
    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
    plt.rcParams['axes.unicode_minus']=False   #正常显示负号
    #plt.rcParams["figure.figsize"] = (20,10)  #设置图片的大小
    plt.figure(dpi = 300)  #设置分辨率
    plt.grid(True)         #添加图表网格线
    """
    
    """
    获取一只股票的信息
    df:股票信息表
    code:股票代码【尽量不要加市场后缀】
    
    返回值:(证券简称 = name,所属规模风格类型 = ..,行业 = ..,细分行业 = ..)
    
    get_stock_info(info_df,"600352").证券简称
    """
    function get_stock_info(df,code)
        q_df = @linq info_df |> where(occursin.(Ref(code),:证券代码))
        if size(q_df,1) > 0
            name = q_df[1,"证券简称"]
            style = q_df[1,"所属规模风格类型"]
            industry = q_df[1,"行业"]
            sub_industry = q_df[1,"细分行业"]
        else
            name = ""
            style = ""
            industry = ""
            sub_industry = ""
        end
        return(证券简称 = name,所属规模风格类型 = style,行业 = industry,细分行业 = sub_industry)
    end
    
    """
    未达到指定的长度,字符串在尾部用空值补足
    str:给定的字符串
    len:要是之达到的长度
    
    fill_string("-5.64",8)|>println
    """
    function fill_string(str,len)
        if length(str) > len
            throw("$(str)的长度超过了$(len)")
        end
    
        fill_num = len - length(str)
        final_str = str
        for i in 1:fill_num
            final_str = string(final_str," ")
        end
        final_str
    end #end fill_string
    
    
    """
    获取股票躁动的历年信息
    df:已经统计完成的春季躁动表
    code:股票代码
    """
    function get_stock_tj_info(df, code)
        q_df = @linq df |> where(occursin.(Ref(code), :证券代码))
        if size(q_df, 1) > 0
            最近x年连胜 = q_df[1,:最近x年连胜]
            最近连胜平均涨跌幅 = q_df[1,:最近连胜平均涨跌幅]
            期间x年连胜 = q_df[1,:期间x年连胜]
            期间连胜平均涨跌幅 = q_df[1,:期间连胜平均涨跌幅]
            y2011 = q_df[1,:y2011]
            y2012 = q_df[1,:y2012]
            y2013 = q_df[1,:y2013]
            y2014 = q_df[1,:y2014]
            y2015 = q_df[1,:y2015]
            y2016 = q_df[1,:y2016]
            y2017 = q_df[1,:y2017]
            y2018 = q_df[1,:y2018]
            y2019 = q_df[1,:y2019]
            y2020 = q_df[1,:y2020]
        else
        end
        return(
        最近x年连胜 = 最近x年连胜,
        最近连胜平均涨跌幅 = 最近连胜平均涨跌幅,
        期间x年连胜 = 期间x年连胜,
        期间连胜平均涨跌幅 = 期间连胜平均涨跌幅,
        y2011 = y2011,
        y2012 = y2012,
        y2013 = y2013,
        y2014 = y2014,
        y2015 = y2015,
        y2016 = y2016,
        y2017 = y2017,
        y2018 = y2018,
        y2019 = y2019,
        y2020 = y2020
        )
    end #function get_stock_tj_info
    
    """
    生成各年涨跌幅的信息
    res = get_stock_tj_info(tasks_df,"600352")
    get_year_gain_str(res) |>println
    """
    function get_year_gain_str(res)
        year_gain_str  = ""
        年份 = ""
        涨跌 = ""
        for y in 2011:2020
            value = res[Symbol("y$(y)")]
            if typeof(value) == String
                value = parse(Float64,value)
            end
            value = isnan(value) ? 0.0 : value  #有NaN的值
            value = round(value,digits = 2)
            年份 = string(年份,fill_string("$(y)",8),"|")
            涨跌 = string(涨跌,fill_string("$(value)",8),"|")
        end
    
        year_gain_str = string(year_gain_str,"\n","年份  :|",年份)
        year_gain_str = string(year_gain_str,"\n","涨跌  :|",涨跌)
    end #function get_year_gain_str
    
    """
    春季躁动画图分析
    """
    function draw_kline(df, info_df, tasks_df, code)
        #股票简要信息
        info = get_stock_info(info_df, code)
        title_text = "【$(code)】 【$(info.证券简称)】 【$(info.所属规模风格类型)】 【$(info.行业)】 【$(info.细分行业)】"
    
        res = get_stock_tj_info(tasks_df, code)
        最近x年连胜 = res.最近x年连胜
        最近连胜平均涨跌幅 = res.最近连胜平均涨跌幅
        title_text = string(title_text, "\n最近x年连胜:$(最近x年连胜),平均涨跌幅:$(最近连胜平均涨跌幅)")
        期间x年连胜 = res.期间x年连胜
        期间连胜平均涨跌幅 = res.期间连胜平均涨跌幅
        title_text = string(title_text, "\n期间x年连胜:$(期间x年连胜),平均涨跌幅:$(期间连胜平均涨跌幅)")
    
    
        res = get_stock_tj_info(tasks_df, code)
        year_gains = get_year_gain_str(res)
        title_text = string(title_text, "\n", year_gains)
    
        #画收盘价的线
        x = df.day
        y = df.close
        p1 = plot(
            x,
            y,
            w = 1,
            title = title_text,
            size = (3000, 1500),
            legend = false,
            bg = RGB(0.2, 0.2, 0.2),
        )
    
        #画各个春季躁动的起始和结束分隔线
        for year = 2011:2020
            begin_date = kpc_dict[year].开仓日期
            end_date = kpc_dict[year].平仓日期
    
            if df.day[1] <= begin_date
                x1 = [begin_date, begin_date]    #x轴刻度值
                close1 = get_close(df, begin_date)
                y1 = [0, close1]
                plot!(x1, y1, w = 1, color = :green)
    
                x2 = [end_date, end_date]
                close2 = get_close(df, end_date)
                y2 = [0, close2]
                plot!(x2, y2, w = 1, color = :red)
            end
        end
    
        #画每年第一个交易日的一个竖线,用于分隔各年的k线
        for year = 2011:2020
            start_date = "$(year)-01-01" |> Date
            end_date = "$(year)-12-31" |> Date
            q_df = @linq df |> where(start_date .<= :day .<= end_date)
            if size(q_df, 1) > 0
                date1 = q_df[1, "day"]
                x3 = [date1, date1]
                close3 = get_close(df, date1)
                y3 = [0, close3]
                plot!(x3, y3, w = 1, color = :yellow)
    
            end
        end
        #savefig(p1, "data/k线图/$(idx)_$(code).svg")
        #display(p1)
        return p1
    end
    
    #读取基金持仓的信息
    fund_df = CSV.read("data\\主流程5 增加基金持股信息到地4步的选股结果\\输入数据\\基金持仓和加仓信息.csv")
    fund_df |> names
    fund_df[!,"代码1"] = fund_df.代码 .|> code->split(code,".")[1] |>string
    
    """
    画某股票被基金持股的年度对比图
    """
    function draw_fund_hoding(q_df)
        x = [y for y in 2010:2021]    #年份
        y = begin                     #年份 - 持股占流通股比(%)
            ary = []
            for year in x
                tmp_df = @linq q_df |> where(:躁动年份 .== year )
                if size(tmp_df,1) > 0
                    push!(ary,tmp_df[1,"持股占流通股比(%)"])
                else
                    push!(ary,0.0)
                end
            end
            ary
        end
    
        holding2020q3,chg2020q3 = begin
            df2020q3 = @linq q_df |> where(:躁动年份 .== 2021)
            if size(df2020q3,1) > 0
                (df2020q3[1,"持股占流通股比(%)"],df2020q3[1,"加减仓占流通股比(%)"])
            else
                (0.0,0.0)
            end
        end
    
        title_text = "各年Q3公告时,基金持仓占流通市值百分比"
        holding_ratio = holding2020q3
        chg_ratio = chg2020q3
        title_text = string(title_text,"\n 2020 Q3 持仓占比:$(holding_ratio),相较2020 Q2持仓变化的股份占流通市值百分比:$(chg_ratio)")
    
        p1 = plot(
            x,
            y,
            w = 1,
            title = title_text,
            #color = colors,
            seriestype = bar, # :scatter,
            size = (3000, 1500),
            legend = false,
            bg = RGB(0.2, 0.2, 0.2),
        )
        #savefig("data/p1.svg")
        #display(p1)
        return p1
    end
    
    q_df = @linq fund_df |> where(:代码1 .== "002371")
    sort!(q_df,:躁动年份)
    p2 = draw_fund_hoding(q_df)
    
    
    """
    画出各个季度的财报营业总收入
    输入:q_df 包含列名
    x = q_df.report_date                 财报日期
    y = q_df.total_operating_revenue     报告的净利润
    
    不用的季度采用不同的颜色
    """
    function draw_revenue(q_df)
    
        x = q_df.report_date
        y = q_df.total_operating_revenue |> ary -> Missings.replace(ary,0.0) |> collect #替换missing值
    
        title_text = "营业总收入,每个季度累加\n hongse = q1,橙色 = q2,黄色 = q3,绿色 = q4"
    
        colors = []
        for d in q_df.report_date
            m = d |> month
            if m == 3
                push!(colors, "red")
            elseif m == 6
                push!(colors, "orange")
            elseif m == 9
                push!(colors, "yellow")
            elseif m == 12
                push!(colors, "green")   #第四季度变成绿色,用于区分各年的财报
            else
    
            end
        end
    
        p1 = plot(
            x,
            y,
            w = 1,
            title = title_text,
            color = colors,
            seriestype = bar, # :scatter,
            size = (3000, 1500),
            legend = false,
            bg = RGB(0.2, 0.2, 0.2),
        )
    
        #display(p1)
        return p1
    end
    
    
    """
    画出各个季度的财报归母净利润
    输入:q_df 包含列名
    x = q_df.report_date                   财报日期
    y = q_df.np_parent_company_owners      报告的净利润
    
    不用的季度采用不同的颜色
    """
    function draw_profit(q_df)
        x = q_df.report_date
        y = q_df.np_parent_company_owners
    
        title_text = "归母净利润,每个季度累加\n hongse = q1,橙色 = q2,黄色 = q3,绿色 = q4"
    
        colors = []
        for d in q_df.report_date
            m = d |> month
            if m == 3
                push!(colors, "red")
            elseif m == 6
                push!(colors, "orange")
            elseif m == 9
                push!(colors, "yellow")
            elseif m == 12
                push!(colors, "green")   #第四季度变成绿色,用于区分各年的财报
            else
    
            end
        end
    
        p1 = plot(
            x,
            y,
            w = 1,
            title = title_text,
            color = colors,
            seriestype = bar, # :scatter,
            size = (3000, 1500),
            legend = false,
            bg = RGB(0.2, 0.2, 0.2),
        )
    
        #display(p1)
        return p1
    end
    
    
    #需要打印的k线
    tasks_df = DataFrame(XLSX.readtable("data/需要打印k线的春季躁动列表.xlsx","Sheet1")...)
    sort!(tasks_df,[:最近x年连胜,:最近连胜平均涨跌幅],rev = true)
    task_codes = tasks_df.证券代码 .|> code -> split(code,".")[1] |> string
    
    #读取《营收和净利指标.csv》表
    revenue_profit_df = CSV.read("data/主流程-7-增加各年各季度的营收和归母净利润/输入数据/营收和净利指标.csv")
    revenue_profit_df[!, "代码"] = revenue_profit_df.code .|> code -> split(code, ".")[1] |> string
    
    #读取基金持仓的信息
    fund_df = CSV.read("data\\主流程5 增加基金持股信息到地4步的选股结果\\输入数据\\基金持仓和加仓信息.csv")
    fund_df[!,"代码1"] = fund_df.代码 .|> code->split(code,".")[1] |>string
    
    """
    画图:把四个图画到一个plot里面
    """
    function draw_plot(code,idx,path,stocks_dict,fund_df,revenue_profit_df)
        stock_df = stocks_dict[code]
        p_kline = draw_kline(stock_df,info_df,tasks_df,code)
    
        q_df = @linq fund_df |> where(:代码1 .== code)
        sort!(q_df,:躁动年份)
        p_fund = draw_fund_hoding(q_df)
    
        q_df = @linq revenue_profit_df |> where(:代码 .== code)
        p_profit = draw_profit(q_df)
        p_revenue = draw_revenue(q_df)
    
        p_all = plot(p_kline,p_fund,p_profit, p_revenue, layout = (4, 1), legend = false)
        display(p_all)
        savefig("$(path)/$(idx)-$(code).svg")
    end
    
    code = "600352"
    idx = 1
    path = "data/k线图"
    draw_plot(code,idx,path,stocks_dict,fund_df,revenue_profit_df)
    
    tasks_df = DataFrame(XLSX.readtable("data/需要打印k线的春季躁动列表.xlsx","Sheet1")...)
    sort!(tasks_df,[:最近x年连胜,:最近连胜平均涨跌幅],rev = true)
    task_codes = tasks_df.证券代码 .|> code -> split(code,".")[1] |> string
    
    code = "600603"
    idx = 1
    path = "data/k线图"
    draw_plot(code,idx,path,stocks_dict,fund_df,revenue_profit_df)
    
    codes = task_codes[1:434]
    for (idx,code) in zip(1:length(codes),codes)
        println(code)
        draw_plot(code,idx,path,stocks_dict,fund_df,revenue_profit_df)
        idx += 1
    end
    
    
    """
    todo:
    (*)增加Q3时基金持股信息:【持股家数】,【占流通比】
    (*)增加年份的notation
    (*)增加财务信息,各年的各季度的【营收】和【利润】
    (*)更新k线数据,更新到最新的k线
    """
    
    
    #读取判断条件,进行过滤
    filter_df_finaces = CSV.read("data/单独流程 - 画k线观察各个躁动年份/输入数据/2020年三个季度净利润同比增长率为正.csv")
    filter_df_fund_hold = CSV.read("data/单独流程 - 画k线观察各个躁动年份/输入数据/基金持仓筛选后的股票.csv")
    
    filter_df_fund_hold |> names |> println
    
    codes1 = filter_df_fund_hold.代码 |> unique |> Set .|> item->split(item,".")[1] |> string
    codes2 = filter_df_finaces.代码 |> unique |> Set .|> item->split(item,".")[1] |> string
    
    intersect(codes1,codes2)
    
    
    #打印k线
    tasks_df = DataFrame(CSV.read("data/单独流程 - 画k线观察各个躁动年份/截至当前-已经连续X年取胜且满足[财报]和[基金]持股的条件.csv"))
    sort!(tasks_df,[:最近x年连胜,:最近连胜平均涨跌幅],rev = true)
    task_codes = tasks_df.证券代码 .|> code -> split(code,".")[1] |> string
    
    code = "600519"
    stock_df = stocks_dict[code]
    draw(stock_df,info_df,tasks_df,code,1)
    
    codes = task_codes
    for (idx,task_code) in zip(1:length(codes),codes)
        println(task_code)
        stock_df = stocks_dict[task_code]
        draw(stock_df, info_df, tasks_df, task_code,idx)
        idx += 1
    end
    

    相关文章

      网友评论

          本文标题:julia分析股市的【春季躁动】(2)——集成多个指标后画图观察

          本文链接:https://www.haomeiwen.com/subject/wqicoktx.html