zoukankan      html  css  js  c++  java
  • Dresdon简介

      很久没有写文章了。这几年经历了很多事情:离开VMware的不舍,拿到融资的开心,重回VMware的亲切,以及不再争强好胜,只做自己喜欢事情的平和。

      可以说,我是幸运的:我这一辈子都在选择,而不是被迫接受。高中通过数学和化学双科竞赛拿到了保送资格,并在大三选择了喜欢的计算机系。在毕业之后的第二年我开通了第一个证券账户,进而发现自己其实是非常喜欢交易的。在创业工作告一段落之后,我便开始构思自己的指标和量化引擎,以期望能够找到一系列更准确表现市场的先行指标,同时验证自己的操作逻辑,完善自己的交易系统。

      于是Dresdon便在我的闲暇时间内诞生了。现在它每天帮我评估市场情绪,并为我筛选出次日需要观察的股票。也让我从选股,复盘等一系列耗时的工作中解脱了出来。

      而本文则将对Dresdon里面包含的一些情绪指数以及量化系统进行简单的介绍。

     

    筹码学基础

      在介绍Dresdon之前,我们先讲解一些筹码学的基础知识。

      筹码学中最为本质的组成就是参与交易的人对于该股的买卖,也即是筹码的买入和卖出。而决定买卖行为的则常常是交易者的既定策略和交易时的心理。股票大涨,通常是买的人多,卖的人少,或者称为多方力量大于空方力量。而大跌则正好相反。

      与此同时,股票价格的波动也会导致人们对于股票价格的看法发生改变。例如看涨的人会随着股价的上涨而开始逐渐转为看跌,又或者是原本看多的人会随着股票的大跌而转为空方。反之空方也可能会由于股票的价格波动而转换为多方。这也是导致买卖力量发生变化的最根本原因。

      如果参与一只股票交易的人对于股票的后期走势具有较为一致的预期,那么该股票的价格就很可能会出现非常猛烈的涨跌。这种一致预期常常具有特定形态的表现,例如最明显的揉搓线,仙人指路,大阳之后的缩量阴等等都可以通过筹码学的角度得到较为完美的解释。

      估计有人会说,那我是不是就盯着具有这些特征线型的股票买入即可了呢?其实不是的。这些线型常常是买卖力量在当时市场的瞬时特征。而且由于这些特征出现后股价已经发生了较大幅度的变化,因此根据这些单一特征做出的决策平均收益率并不高,甚至可能会连手续费都无法覆盖。

      为了提高成功率和平均收益率,我们常常需要在模型中加入一些辅助判断依据。这也导致了一个模型常常分为几部分逻辑:提示买入的特征线型,存在于近端及远端的一些辅助判断依据。由于距离当前交易日越远股价离散程度越高,因此这三部分组成中,买入的特征线型要明显,近端的辅助判断逻辑要严格,而远端的辅助判断逻辑要具有较高的容错性。

      让我们以海普瑞(sz002399)在2018年5月初的拉升为例:

     

     

      从上图中可以看到,在18年5月的上涨之前,该股呈现出一段非常完美的形态:首先缓慢上涨收取了足够的筹码。接下来经过两个月的盘整将筹码稳定住,并在五月通过两根倍量阳线开启主升浪。

      那是不是只要走出类似的形态就可以放心的买入了呢?不是的。例如万里石(sz002785)在相似形态下的拉升就遭遇了失败:

     

     

      也就是说,一个形态的拉升成功与否不仅仅取决于自身的形态,更和市场的整体情绪及市场偏好密切相关。因此在参与交易时的市场情绪是一个非常重要的考量因素。

     

    交易指数

      在买入一只股票之前,我们常常需要通过一系列指标来决定是否参与交易,以及股票的交易策略。市场上存在着一系列常见的指标,如创业板指,上证综指,MACD等。这些指标多多少少都存在着一系列问题:如上证综指由于指数编制的原因失真,或者MACD提供的信息并不特别直观,需要通过分析背离才能有效的进行防守等。因此市场上需要一系列准确直观的指标来辅助用户决策。

      在本节中,我们就将对Dresdon当前版本所提供的一部分指标进行介绍。

     

    平均价指标

      平均价指标主要用来评估当前市场到底是指数行情还是题材股行情。

      相信很多股民都知道一系列和指数背离相关的俗语,如“只赚指数不赚钱”,“沪强深弱”等。这实际上都是在描述一个事实:由于上证指数,深证成指,创业板指等指数所选取的成分股以及各成分股所对应的权重不尽相同,因此这些指数并不能完全地描述整个市场的行情。例如上证指数中占比最大的一类就是各家银行,保险以及券商这些金融类股票。在2016年1月到2018年1月这段时间内,这些金融类股票不断上涨,甚至很多都超过了2015年股灾时期的最高价。但期间个股跌幅常常是20%甚至更多。因此对于大多数持有成长股的股民而言,这便是一段长时间的“只赚指数不赚钱”的行情。所以说,一名股民是否能在某段时间内赚到钱和指数关系不大,而是和自己的投资风格关联更为密切:若股民投资的是稳健的金融类股票,或者是具有高成长性的白马股,那么他将在2016年1月到2018年1月这段时间内取得不错的收益;若股民对中国的科技发展看好而投资的是科技类股票,那么他很可能在这段时间内的收益欠佳。

      相较于上证指数,深证成指以及创业板指中所包含的成长股的比重更大,因此市场也常常通过比较这些不同指数的涨跌幅来判断市场行情。但这仍然不够:深证成指中金融地产等行业所占的权重仍然较大,而创业板指中温氏股份的比重也远超于其它成分股。如果地产行业受到政策利好的驱动而大幅上涨,或者温氏股份的股价由于猪肉价格波动而产生大幅波动,那么此时深证成指及创业板指也会失真。因此深证成指和创业板指也只能在一定程度上反映当前市场的投资偏好,而不具有普适性。

      而常见的下一个粒度的指数就是板块指数了。其能较好地表现板块内部各支股票的运行趋势。但其也有自身的局限性:其忽略了其它板块行情与当前板块的联动。例如在弱势行情下,板块行情的持续性可能只有几天;而在强势行情下,板块行情可能持续一个月甚至更久。

      为了能够更好地衡量市场的整体投资情绪,我们在我们自用的量化系统中抽取了一个新的指标:平均价指标。该指标通过计算去噪后的股价涨跌幅的平均值来衡量市场的整体投资情绪。用户可以通过比较三大指数和该指标的差异来较为准确地判断当前市场的投资偏好。

      该指数的查看页面如下所示:

     

     

      最上面的是用来展示指数和指标之间相对关系的指标区。在该区域中,指数的收盘价以蓝色线表示,指标由红色线表示,而鼠标当前位置所指向的交易日则被称为游标。在默认情况下,两者将以游标作为展示的基准,即令当日的指数与指标重合。此时游标右侧的图形就能表现相应交易日后的到底是指数行情还是个股行情。例如在上面所展示的指数中,表示指标的红线远低于表示指数的蓝线。这也就表示当时市场整体的赚钱效应非常差。除此之外,用户还可以通过鼠标的左键点击暂时将游标固定,或通过再次点击取消游标固定。

      该页面的中间区域用来展示各个交易日的指标变动和指数变动的差值,也即是个股相对于指数的单日相对强度。例如上图中游标所在交易日的指数上涨了0.05%,而平均价指标的涨幅为-0.65%,因此当日的差值即为-0.7%,进而在该区域中显示为一条绿线。反之若平均价指标表现强于指数,那么在该区域中显示为一条红线。无论红线还是绿线,其长度越长,表示平均价指标和指数之间的差值就越大。

      而最下方的则是指标和指数之间差值的累计值。其能够更好地表现出一段趋势性行情中两者的差值,也将行情到底是指数行情还是题材行情这一特征表现得更为明显。

    多空力量指标

      相信很多投资者每天都在问自己这样一系列问题:什么时候牛市会来?现在是进场的时机么?我现在的仓位合适么?而这一切问题的答案都基于他对市场多空力量的判断:若他觉得后市将会走强,那么他就会增加自己的持仓,反之则降低仓位。由于每个人对后市都有不同的判断,因此市场形成了动态的多空平衡:在每个空头卖出自己持仓的同时,一个多头就增加了自己的仓位。

      而大多数投资者都想做到的一件事就是:买在低点,卖在高点。而从市场整体氛围的角度来讲,那就是买在多头力量逐渐增长的时间点,而卖在多头力量开始衰竭的那一刻。因此如何较为准确地衡量市场的多空力量变化也能够帮助投资者较好地衡量市场的多空力量对比,进而对自己的仓位,持股类型进行调整,做到攻守自如。

      为了能够更好地衡量市场的整体投资情绪,我们抽取出了多空力量指标。该指标内部通过统计一系列股价波动特征来衡量整个市场中所有股票的多空力量。其主要分为三个子指标:

    • 高低值数据。该指标通过统计具有显著做多/做空情绪的股票数量来展示市场中的多空力量之比。

    • 标准数据。该指标通过统计所有股票的多空力度来展示市场中的多空力量之比。

    • 锐化数据。该指标同样通过统计所有股票的多空力度来展示市场中的多空力量之比。不同的是,其增大了具有较强多空力量的股票的权重,使得指标更为灵敏。

      除此之外,用户还可以通过勾选差值数据这一选项来获得更明显的表观特征。该选项将会计算多空力量之差并将其展示在界面中。需要注意的是,该选项会将指标的两个分量归结为一个分量,从而可能导致部分信息不再在页面中可见。

      下面就是该指标的操作页面:

     

     

      该页面的上半部分是用来展示指数的指数区。用户可以通过点击右上角的齿轮按钮打开设置页面。在该设置页面中,用户可以指定需要展示的指数,需要在页面下部的指标区展示哪一个子指标等信息。

      而该页面的下半部分则是指标区。其通过红柱和绿柱来展示当前市场的多空力量。若用户选择查看差值数据,那么红柱表示多方力量大于空方力量,而绿柱则表示空方力量大于多方力量。多空力量之差则由红柱和绿柱的高度表示。

      该指标的使用方法其实非常简单,那就是看整个市场的多空力量数据就能估计出市场的赚钱效应。例如在2018年全年锐化后的多空力量指标均不乐观:

     

     

      再比如在2015年6月及2019年4月高低值数据显示做多情绪持续乏力:

     

     

    持股指标

      相信投资者常常听到“仓位控制”这样一个词,并在实际的操作中尝试找到一种最优的仓位控制准则。但在实际操作中,投资者常常由于不能全面地评估整个市场的多空力量而无法有效地执行自己的准则,进而无法良好地执行自己的交易系统。为此我们提供了持股指数这一指标来辅助用户决定自己应该持有的仓位。

      持股指数是一个非常灵敏的指标,其通过分析市场中典型个股的多空情绪来预判用户在短线操作中所应持有的仓位。该指数主要分为两个子指标:三日指标和五日指标。两者的区别仅仅是分析时间跨度的不同。但相较而言,三日指标较五日指标更为灵敏,五日指标则相较于三日指标更为稳健。

      下面就是该指标的操作页面:

     

     

      该页面的上半部分是用来展示指数的指数区。用户可以通过点击右上角的齿轮按钮打开设置页面。在该设置页面中,用户可以指定需要展示的指数,以及在页面下部指标区中所展示数据的类型等。该页面的下半部分则是指数的展示区。该指数提供了三部分信息:红色的做多情绪线,绿色的做空情绪线,以及通过计算两者之差所得到的总体情绪。

      用户可以参考总体情绪线来设置自己的仓位:如果总体情绪线显示为指数区上方的红色线,那么此时用户的仓位应高于半仓,并且情绪线越长仓位应当越高;如果总体情绪线显示为指数区下方的绿色线,那么此时用户的仓位应低于半仓,并且情绪线越长仓位应当越低。

    其它指标

      除了上面所提到的三个指标之外,我们还提供了其它一系列指标。如指示短线多空力量的领先股情绪指标等。只是限于文章篇幅,我们将不再对它们进行介绍。

    量化引擎

      现在我们已经有了一系列情绪指标的帮助。下一步就要开始添加模型了。

      让我们仍然以海普瑞(sz002399)在2018年5月初所展示的拉升形态为例:

     

     

      该股首先缓慢上涨收取了足够的筹码。接下来经过两个月的盘整将筹码稳定住,并在五月通过两根倍量阳线开启主升浪。我们可以通过下面的脚本来描述该模型的买入条件:

    // 当日和前日股价上涨
    $isRaisingUp = growth(close()) > 0 && growth(close(), 1) > 0
    
    // 5日前存在着一个长度至少为30,震荡幅度小于5%的平台
    $isPlatform = platform_exists(0.05, 30, 5)
    
    // 在平台前存在长度至少为20日,最大上涨幅度为12%的缓慢增长
    $isSlowRaiseBeforePlatform = is_slow_raise(0.12, 20, platform_start(0.05, 30, 5))

      同时我们将卖出条件设定为股价低于五日线:

    $sellCondition = close(0) < ma5(0)

      这样我们就定义了一个最简单的模型。接下来,我们就可以扫描所有股票,以得到所有匹配以及这些匹配的平均收益率,最高收益率等一系列信息:

    {
        "averageBenefit" : 0.007549979051232566,
        "maxBenefit" : 74.86122362293308,
        "minBenefit" : -4.13,
        "totalCount" : 2281,
        "averageDayCount" : 8.197412099662129,
        "successRatio" : 0.4194188255527758
    }

      可以看到,我们刚刚创建的模型只有0.7%的平均收益率,但在十余年中匹配了2281次。这表示我们的模型的匹配条件过于宽松。我们应该添加更为严格的匹配条件,以提高模型的准确度,提高平均收益率。例如我们可以要求当日和前一日的股价上涨均超过1%并再次扫描:

    $isRaisingUp = growth(close()) > 0.01 && growth(close(), 1) > 0.01

      可以看到,该模型的各方面表现都有了显著提高:

    {
        "averageBenefit" : 0.00878939386175436,
        "maxBenefit" : 74.86122362293308,
        "minBenefit" : -4.13,
        "totalCount" : 1913,
        "averageDayCount" : 8.12565445026178,
        "successRatio" : 0.4273821989528796
    }

      在经过多轮迭代细化模型的买入卖出条件之后,该模型将能达到令人满意的收益率:

    {
        "averageBenefit" : 0.049035519980520418,
        "maxBenefit" : 74.86122362293308,
        "minBenefit" : -4.000000000000014,
        "totalCount" : 313,
        "averageDayCount" : 11.875656742556918,
        "successRatio" : 0.46059544658493873
    }

      在当前引擎版本中,我们的脚本支持了几乎全部的常见K线数据,并提供了一系列更高层次的K线分析函数:

    类别 

    描述 示例
    K线 基本K线信息

    open(0), close(1, 4), upper_shadow(0), ma5(0)

    指数

    常见基本指数及引擎的自定义指数

    macd(0), buy_stength(0)

    运算符 常见运算符

    close(0) - open(0), close(0) > ma5(0)

    函数

    常见函数及高级拟合函数等

    max(close(0), open(0)), platform_exists(0.05, 30, 5)

      除了使用脚本之外,用户还可以通过自行编写Java插件的方式来描述模型:

    // 当日和前日股价上涨
    BooleanHolder isRaisingUp = and(greaterThan(growth(close()), 0), greaterThan(growth(close(), 1), 0));
    
    // 5日前存在着一个长度至少为30,震荡幅度小于5%的平台
    BooleanHolder platformExists = platformExists(0.05, 30, 5)
    
    // 在平台前存在长度至少为20日,最大上涨幅度为12%的缓慢增长
    IntHolder platformStart = platformStart(0.05, 30, 5);
    BooleanHolder isSlowRaiseBeforePlatform = isSlowRaise(0.12, 20, platformStart);
    
    BooleanHolder condition = and(isRaisingUp, platformExists, isSlowRaiseBeforePlatform);

      在插件中,我们不仅仅可以定义模型,更可以添加自定义指数,运算符,函数:

    public static Value.Shrink shrink(int index) {
        return new Value.Shrink(index);
    }
    
    @Operation(key = KEY_SHRINK, resultType = DOUBLE, arguments = {
            @Arguments(paramTypes = { INT })
    })
    public static class Shrink extends IndexedVariable<Double> implements DoubleHolder {
    
        public Shrink(int index) {
            this(new IntValue(index));
        }
    
        public Shrink(IntHolder index) {
            super(KEY_SHRINK, index);
        }
    
        @Override
        protected Double recalculate(QuantContext context) {
            indexValue = index.getValue(context);
            if (indexValue == null) {
                return null;
            }
    
            DailyTrading dailyTrading = context.getTradings().get(indexValue);
            double blockSize = Math.abs(dailyTrading.getClose() - dailyTrading.getOpen());
            double totalVariation = dailyTrading.getHigh() - dailyTrading.getLow();
            this.value = blockSize > SMALL_DOUBLE_VALUE ? totalVariation / blockSize : Double.MAX_VALUE;
            return value;
        }
    }

      而在当前版本中,我们已经有了十余个模型,并在持续添加中:

    转载请注明原文地址并标明转载:https://www.cnblogs.com/loveis715/p/13302884.html

    商业转载请事先与我联系:silverfox715@sina.com

    公众号一定帮忙别标成原创,因为协调起来太麻烦了。。。

  • 相关阅读:
    zoj 2972
    图像切割之(五)活动轮廓模型之Snake模型简单介绍
    使用和制作patch文件
    一步一步写算法(之洗牌算法)
    第3讲 数码管显示
    Oracle 11g client的安装和配置。
    StringTokenizer类的使用
    BDB (Berkeley DB)数据库简单介绍(转载)
    关于MSHTML
    C语言sizeofkeyword
  • 原文地址:https://www.cnblogs.com/loveis715/p/13302884.html
Copyright © 2011-2022 走看看