简单双均线策略(Simple Moving Average)

策略介绍
简单双均线策略,通过一短一长(一快一慢)两个回看时间窗口收盘价的简单移动平均绘制两条均线,利用均线的交叉来跟踪价格的趋势。这里说的简单是指在求平均值的时候采用的是算术平均数(就是求和再除以总数),有些更为复杂的求平均值得方法,如加权移动平均,指数加权移动平均等等。我们这个策略只使用最基本的算术平均。移动平均线是股票趋势策略中最常见技术手段。

计算方法(以日频率举例)
N日移动平均(MA)的计算:
MA(N) = 最近N天的收盘价之和 / N

使用方法
我们选定一个短期一个长期两个时间窗口(如常见的5日和20日,10日和40日等等),分别绘制出短期和长期的简单移动平均线。短期均线要比长期均线更为敏感,变化更快。
(1) 当短期均线自下而上突破长期均线(或突破一定比例)时,产生买入信号
(2) 当短期均线自上而下跌破长期均线(或跌破一定比例时),产生卖出信号

优点
简单双均线策略计算很容易,看起来又一目了然,很容易帮助了解市场走势,使用效果较好,深受投资者的喜爱。

缺点
双均线对于趋势的行情跟踪的非常好,但是在震荡行情中表现较差。短均线和长均线可能会纠缠在一起,出现来回多次的假突破,甚至造成高买低卖的情况。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 策略代码总共分为三大部分,1)PARAMS变量 2)initialize函数 3)handle_data函数
# 请根据指示阅读。或者直接点击运行回测按钮,进行测试,查看策略效果。

# 策略名称:简单双均线策略
# 策略详细介绍:https://wequant.io/study/strategy.simple_moving_average.html
# 关键词:价格突破、趋势跟踪。
# 方法:
# 1)计算一长一短两个时间窗口的价格均线
# 2)利用均线的突破来决定买卖

import numpy as np

# 阅读1,首次阅读可跳过:
# PARAMS用于设定程序参数,回测的起始时间、结束时间、滑点误差、初始资金和持仓。
# 可以仿照格式修改,基本都能运行。如果想了解详情请参考新手学堂的API文档。
PARAMS = {
    "start_time": "2017-02-01 00:00:00",  # 回测起始时间
    "end_time": "2017-08-01 00:00:00",  # 回测结束时间
    "slippage": 0.003,  # 此处“slippage"包含佣金(千二)+交易滑点(千一)
    "account_initial": {"huobi_cny_cash": 100000,
                      "huobi_cny_btc": 0},  # 设置账户初始状态
}

# 阅读2,遇到不明白的变量可以跳过,需要的时候回来查阅:
# initialize函数是两大核心函数之一(另一个是handle_data),用于初始化策略变量。
# 策略变量包含:必填变量,以及非必填(用户自己方便使用)的变量
def initialize(context):
    # 设置回测频率, 可选:"1m", "5m", "15m", "30m", "60m", "4h", "1d", "1w"
    context.frequency = "15m"
    # 设置回测基准, 比特币:"huobi_cny_btc", 莱特币:"huobi_cny_ltc", 以太坊:"huobi_cny_eth"
    context.benchmark = "huobi_cny_btc"
    # 设置回测标的, 比特币:"huobi_cny_btc", 莱特币:"huobi_cny_ltc", 以太坊:"huobi_cny_eth"
    context.security = "huobi_cny_btc"

    # 设置策略参数
    # 计算短线所需的历史bar数目,用户自定义的变量,可以被handle_data使用
    context.user_data.window_short = 5
    # 计算长线所需的历史bar数目,用户自定义的变量,可以被handle_data使用
    context.user_data.window_long = 20
    # 入场线, 用户自定义的变量,可以被handle_data使用
    context.user_data.enter_threshold = 0.00
    # 出场线, 用户自定义的变量,可以被handle_data使用
    context.user_data.exit_threshold = 0.00

# 阅读3,策略核心逻辑:
# handle_data函数定义了策略的执行逻辑,按照frequency生成的bar依次读取并执行策略逻辑,直至程序结束。
# handle_data和bar的详细说明,请参考新手学堂的解释文档。
def handle_data(context):
    # 获取历史数据, 取后window_long根bar
    hist = context.data.get_price(context.security, count=context.user_data.window_long, frequency=context.frequency)
    if len(hist.index) < context.user_data.window_long:
        context.log.warn("bar的数量不足, 等待下一根bar...")
        return
    # 计算短均线值
    close = np.array(hist["close"])
    short_mean = np.mean(hist["close"][-1 * context.user_data.window_short:])
    # 计算长均线值
    long_mean = np.mean(hist["close"][-1 * context.user_data.window_long:])

    # 价格上轨
    upper = long_mean + context.user_data.enter_threshold * long_mean
    # 价格下轨
    lower = long_mean - context.user_data.exit_threshold * long_mean

    context.log.info("当前 短期均线 = %s, 长期均线 = %s, 上轨 = %s, 下轨 = %s" % (short_mean, long_mean, upper, lower))

    # 短期线突破长期线一定比例,产生买入信号
    if short_mean > upper:
        context.log.info("短期均线穿越上轨,产生买入信号")
        if context.account.huobi_cny_cash >= HUOBI_CNY_BTC_MIN_ORDER_CASH_AMOUNT:
            # 有买入信号,且持有现金,则市价单全仓买入
            context.log.info("正在买入 %s" % context.security)
            context.log.info("下单金额为 %s 元" % context.account.huobi_cny_cash)
            context.order.buy_limit(context.security, quantity=str(context.account.huobi_cny_cash/close[-1]*0.98), price=str(close[-1]*1.02))
        else:
            context.log.info("现金不足,无法下单")
    # 短期线低于长期线一定比例,产生卖出信号
    elif short_mean < lower:
        context.log.info("短期均线穿越下轨,产生卖出信号")
        if context.account.huobi_cny_btc >= HUOBI_CNY_BTC_MIN_ORDER_QUANTITY:
            # 有卖出信号,且持有仓位,则市价单全仓卖出
            context.log.info("正在卖出 %s" % context.security)
            context.log.info("卖出数量为 %s" % context.account.huobi_cny_btc)
            context.order.sell_limit(context.security, quantity=str(context.account.huobi_cny_btc), price=str(close[-1]*0.98))
        else:
            context.log.info("仓位不足,无法卖出")
    else:
        context.log.info("无交易信号,进入下一根bar")

15m回测

30m

60m

4h

1d

1w

本策略采用了5小时和20小时均线来回测。
5小时均线 > 20小时均线 * (1+入场线),产生买入信号;
5小时均线 < 20小时均线 * (1-出场线),产生卖出信号。

这里入场线和出场线都设置为0,只要快线穿过慢线,就会产生交易信号。这样设置主要是因为我们采用小时为单位回测,希望抓住短期的价格波动,所以出入场线的设置要宽松一些,否则很难产生交易信号。如果以日为单位,希望捕捉大的趋势,则可以适当调大出入场线,使信号更加严格,只有当趋势确定形成时才交易,防止短期震荡产生干扰信号。
从回测结果可以看出,策略在判断行情,捕捉趋势上,十分成功,抓住了几波大幅的上涨,并且在下跌中能较早离场,锁定收益,最大回撤只有12%左右,远远好于基准。
由于虚拟货币市场波动很大,没有涨跌幅限制,所以暴涨暴跌可以在很短的时间内完成, 一天内的波动涨跌可以很大。所以本策略如果以日为单位,效果并不理想。策略没有跑赢基础,而且波动很大,在暴跌中反应迟缓,对市场变化不能及时做出反馈。

总结
简单双均线是一种简单而又有效的策略,逻辑清楚,买卖信号明确,非常适合初学者使用。在十分不稳定的虚拟货币市场,长周期(如日、周、月等)的均线滞后性明显,不适合用来产生买卖信号。

WeQuant交易策略—简单均线的更多相关文章

  1. WeQuant交易策略—网格交易

    网格交易策略(Grid Trading) 策略介绍 网格策略本质上是一种低吸高抛的策略.标的物价格越低,吸纳的头寸越多:标的物价格越高,卖出的头寸越多.网格策略巧妙地借鉴了日常生活中渔翁撒网扑鱼的思路 ...

  2. WeQuant交易策略—5日均线

    简单的价格突破策略.当前价格超过最近5个收盘价的均价,则全仓买入:低于均价,则全仓卖出 代码 # 简单的价格突破策略.当前价格超过最近5个收盘价的均价,则全仓买入:低于均价,则全仓卖出 # PARAM ...

  3. WeQuant交易策略—BOLL

    BOLL(布林线指标)策略 简介 BOLL(布林线)指标是技术分析的常用工具之一,由美国股市分析家约翰•布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标.一般而言,价格的运动总是围 ...

  4. WeQuant交易策略—EMV

    EMV指标策略 简介 EMV(Ease of Movement Value, 简易波动指标),它是由RichardW.ArmJr.根据等量图和压缩图的原理设计而成, 目的是将价格与成交量的变化结合成一 ...

  5. WeQuant交易策略—Dual Thrust

    Dual Thrust策略 策略介绍 Dual Thrust是一个趋势跟踪系统,由Michael Chalek在20世纪80年代开发,曾被Future Thruth杂志评为最赚钱的策略之一. Dual ...

  6. WeQuant交易策略—ATR

    ATR(真实波幅均值)策略 策略介绍 ATR(average true range,真实波幅均值),是用来衡量一段时间内价格的真实的平均波动范围,ATR不是一个领先指标,但是它测量最重要的市场参数之一 ...

  7. WeQuant交易策略—RSI

    RSI指标策略 策略介绍 RSI(相对强弱指标),是通过一段时期内的平均收盘上涨和下跌数,计算价格上涨所产生的波动占整个波动的百分比,来分析市场买卖盘的意向和实力. 计算公式(以日为单位举例) RSI ...

  8. WeQuant交易策略—KDJ

    KDJ随机指标策略策略介绍KDJ指标又叫随机指标,是一种相当新颖.实用的技术分析指标,它起先用于期货市场的分析,后被广泛用于股市的中短期趋势分析,是期货和股票市场上最常用的技术分析工具.随机指标KDJ ...

  9. WeQuant交易策略—MACD

    MACD(指数平滑异同平均线)策略简介MACD指标应该是大家最常见的技术指标,在很多股票.比特币的软件中都是默认显示的.MACD是从双指数移动平均线发展而来的.意义和双移动平均线基本相同,即由快.慢均 ...

随机推荐

  1. 使用jersey 注解包扫描类PackageNamesScanner

    Jersey 中自带一个包扫描,可以是包,或者具体类名 ,扫描的类型是自己定注解类型,实现功能更加大,可以是jar 包 可以是虚拟地址下的 Jersey 主要用来扫描Path Provider 类中同 ...

  2. Liunx上传下载和压缩问题分享

    昨天紧急需求需要测试,开发远程发了个包需要部署到生产环境.我通过FileZila连接到服务器,然后把补丁包发送到服务器对应路径,通过CRT操作,进行包的解压.重启. 同时,为了配合开发定位问题,需要从 ...

  3. MongoDB 安装和配置

    [前言] Mongodb是一款nosql数据库,关于nosql 以及 mongodb本文不进行介绍,在数据库的选型方面,本人说是在机缘巧合之下选择了mongodb,并且拟使用mongodb搭建日志系统 ...

  4. Memcache+cookie实现模拟session

    上一片讲到Memcached在Windows上的安装,和用Telnet工具进行命令操作,在稍微了解了原理之后,我也就开始尝试着用程序来对Memcached进行操作.这一篇分为两个部分,第一部分是用.n ...

  5. Palindrome 回文数

    回文数,从前到后,从后到前都一样 把数字转成字符串来处理 package com.rust.cal; public class Palindrome { public static boolean i ...

  6. html5 01 随记

    一  HTML 是一种制作网站的标记语言 二.HTML基本语法 HTML 标签 html标签是html中的最基本单位 也是最重要的部分 通常使用尖角号 开始"<"和结束&qu ...

  7. jquery 禁止herf跳转,并执行相应的js代码

    <a class="oh_btn bg_3" href="javascript:void(0);" onclick="myfun(this)&q ...

  8. 初识RabbitMQ系列之一:简单介绍

    一:RabbitMQ是什么? 众所周知,MQ是Message  Queue(消息队列)的意思,RabbitMQ就是众多MQ框架其中的一款,开源实现了AMQP协议(官网:http://www.amqp. ...

  9. [补档][NOI 2008]假面舞会

    [NOI 2008]假面舞会 题目 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一个自己喜欢的面具. 每个面具都有一 ...

  10. Mybatis 调用存储过程,使用Map进行输入输出参数的传递

    做个记录,以备后用 java代码: public String texuChange() throws Exception {        try {                         ...