『数字货币策略』-双均线策略

策略分享
标签: #<Tag:0x00007fb007af3db8>

(caoxiyang) #1

数字货币-双均线策略

策略背景

国际研究情况

Ng and Wing-Kam(2008) 对MACD和RSI两个指标的盈利性进行了实证检验,文中采用FT-30为研究对象,样本跨期为60年。检验结果发现,单纯的MACD和RSI交易策略都能够获得远高于买入并持有交易策略的收益。Shik TC(2007)以外汇市场六国主要货币为对象对相对强弱指标RSI和移动平均线MA两者的盈利性进行了实证研究,研究结果显示,两个指标下的交易策略能产生高于风险补偿的收益。

国内研究情况

Zhou and zhu(2010)在《技术分析:从资产配置的角度看移动平均线的使用》一文中,作者从理论上分析了在资产配置问题中使用技术分析的基本原理,也就是一个投资者怎样将自己的财富在风险资产和无风险资产之间达到最优分配。作者在分析从量化的角度解决了对于对数效用的投资者精确最优配置量的问题时,也分析了股价可预测性程度是如何影响配置决策的。结果表明移动平均线能很明显地提高投资者的效用。

策略介绍

今天,我们尝试在数字货币量化交易上运用最简单的均线策略,交易标的是’BTC_USDT.HBI’。

策略原理

双均线策略:指的是运用两条不同周期的移动平均线,即短周期移动平均线和长周期移动平均线的相对大小,研判买进与卖出时机的策略。当短周期的均线从长期均线的下方,向上穿越至长周期的均线,所形成的交点,称为金叉。当短周期的均线从长期均线的上方,向下穿越至长周期的均线,所形成的交点,称为死叉。当出现金叉点时,市场属于多头市场;当出现死叉点时,市场属于空头市场。

数字货币标的:BTC_USDT.HBI;

时间:2017/11/1–2018/4/1日线数据;

5周期均线与20日均线的双均线策略;

策略逻辑

空仓状态下,短周期均线上穿(大于)长周期均线形成金叉,且该数字货币可以交易,满仓买入
持仓状态下,短周期均线下穿(小于)长周期均线形成死叉,且该数字货币可以交易,满仓卖出

策略实现

  • 首先,我们选择要交易的标的以及设置一下基本参数,这里选择的是’BTC_USDT.HBI’。
  • 然后,编写策略初始化部分,initialize函数只会运行一次,在第一个日期运行,因此可以把策略一些参数放在该函数定义。
  • 下面是策略交易逻辑,handle_data函数会每个周期(日/分)运行一次,可以把行情数据理解成K线,然后handle_data函数会在每个K线上依次运行。
  • 最后启动回测,编写策略回测接口。

策略代码如下

克隆策略
In [1]:
# 回测起始时间
start_date = '2017-11-01'
# 回测结束时间
end_date = '2018-04-01'
# 策略比较参考标准
benchmark = 'BTC_USDT.HBI'
# 交易标的 
instruments = ['BTC_USDT.HBI']
# 起始资金
capital_base = 1000000
In [2]:
# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
    # context.set_commission是设置手续费,这里作演示不考虑手续费,股票的手续费设置如下,作为参考。
    # context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    #短均线参数
    context.short_period = 5
    #长均线参数
    context.long_period = 20
In [3]:
def handle_data(context, data):
    # 当前支持的K线数量还达不到长均线时直接返回
    if context.trading_day_index < context.long_period:
        return
    # 投资标的字符串格式
    instr = instruments[0]
    # 将标的转化为equity格式
    sid = context.symbol(instr)    
    # 最新价格
    price = data.current(sid, 'price')
    # 短周期均线值
    short_mavg = data.history(sid, 'price', context.short_period, '1d').mean()
    # 长周期均线值
    long_mavg = data.history(sid, 'price', context.long_period, '1d').mean()
    # 账户资金
    cash = context.portfolio.cash;
    # 账户持仓
    cur_pos = context.portfolio.positions[sid].amount
    
    # 策略逻辑部分
    # 空仓状态下,短周期均线上穿(大于)长周期均线形成金叉,且该股票可以交易,买入
    # 持仓状态下,短周期均线下穿(小于)长周期均线形成死叉,且该股票可以交易,卖出
    if (short_mavg > long_mavg and cur_pos == 0 and data.can_trade(sid)):
        context.order_target_percent(sid,1)
    elif (short_mavg < long_mavg and cur_pos > 0 and data.can_trade(sid)):
        context.order_target_percent(sid, 0)
In [4]:
history_ds=DataSource('bar1d_HBI').read(instruments,start='2017-05-01', end=end_date)
benchmark_ds = DataSource('bar1d_HBI').read([benchmark],start='2017-05-01', end=end_date)

m = M.trade.v4(
    instruments=instruments,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    # 买入的时候,假设以次日开盘价成交
    order_price_field_buy='open',
    # 卖出的时候,假设以次日开盘价成交
    order_price_field_sell='close',
    capital_base=capital_base+1,
    benchmark=benchmark_ds,
    m_deps=np.random.rand(),
    history_ds=history_ds,
)
[2018-09-10 11:55:36.780519] INFO: bigquant: backtest.v8 开始运行..
[2018-09-10 11:55:36.787081] INFO: bigquant: biglearning backtest:V8.0.8
[2018-09-10 11:55:36.788196] INFO: bigquant: product_type:stock by specified
[2018-09-10 11:55:37.740689] INFO: algo: TradingAlgorithm V1.2.8
[2018-09-10 11:55:38.870011] INFO: Performance: Simulated 152 trading days out of 152.
[2018-09-10 11:55:38.871107] INFO: Performance: first open: 2017-11-01 00:00:00+00:00
[2018-09-10 11:55:38.871906] INFO: Performance: last close: 2018-04-01 23:59:00+00:00
  • 收益率22.06%
  • 年化收益率39.16%
  • 基准收益率1.74%
  • 阿尔法0.3
  • 贝塔0.44
  • 夏普比率0.77
  • 胜率0.33
  • 盈亏比3.57
  • 收益波动率77.52%
  • 信息比率-0.01
  • 最大回撤49.23%
[2018-09-10 11:55:39.447003] INFO: bigquant: backtest.v8 运行完成[2.66651s].

(feynman0825) #2

搜噶~~


(koolaysun) #3

BTC_USDT.HBI 这个标的数据是哪里来的,为什么只有2017.10.27到2018.7.10的数据?


(scalaview) #4

从交易详情来看只有17年11月到12月是赚的,后面的交易都是亏的交易,请问有没有优化策略


(caoxiyang) #5

只是想在数字货币上试试经典的策略哈,提供一种思路,并没有优化过。


(studyquant) #6

数字货币量化策略定制,实盘交易接口定制


(monk) #7

你好,8月2日运行次策略报错:
SyntaxError Traceback (most recent call last)
SyntaxError: invalid syntax (init.py, line 164)

During handling of the above exception, another exception occurred:

ImportError Traceback (most recent call last)
in ()
95 m_deps=np.random.rand(),
96 history_ds=history_ds,
—> 97 benchmark_ds=benchmark_ds
98 )

ImportError: No module named ‘custom_modules.backtest’

请问一下是什么原因?多谢!


(iQuant) #8

您好 这个问题现在已经解决 您可以再试一下


(sunxuetao2010) #9

ValueError Traceback (most recent call last)
in ()
15 benchmark=benchmark_ds,
16 m_deps=np.random.rand(),
—> 17 history_ds=history_ds,
18 )

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

history_ds=DataSource(‘bar1d_HBI’).read(instruments,start=‘2017-010-01’, end=end_date)

交易标的

instruments = [‘BTC_USDT.HBI’]

怀疑交易标的拿不到数据,这个instruments 又说明吗


(iQuant) #10

您好,数字货币目前只支持部分数据且近期没有更新,之后我们会不断支持完善。


(kissmenet) #11

复制过去的代码,

ValueError Traceback (most recent call last)
in ()
15 benchmark=benchmark_ds,
16 m_deps=np.random.rand(),
—> 17 history_ds=history_dss,
18 )

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

怎么解决


(达达) #12
克隆策略
In [1]:
# 回测起始时间
start_date = '2017-11-01'
# 回测结束时间
end_date = '2018-04-01'
# 策略比较参考标准
benchmark = 'BTC_USDT.HBI'
# 交易标的 
instruments = ['BTC_USDT.HBI']
# 起始资金
capital_base = 1000000
In [2]:
# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
    # context.set_commission是设置手续费,这里作演示不考虑手续费,股票的手续费设置如下,作为参考。
    # context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    #短均线参数
    context.short_period = 5
    #长均线参数
    context.long_period = 20
In [3]:
def handle_data(context, data):
    # 当前支持的K线数量还达不到长均线时直接返回
    if context.trading_day_index < context.long_period:
        return
    # 投资标的字符串格式
    instr = instruments[0]
    # 将标的转化为equity格式
    sid = context.symbol(instr)    
    # 最新价格
    price = data.current(sid, 'price')
    # 短周期均线值
    short_mavg = data.history(sid, 'price', context.short_period, '1d').mean()
    # 长周期均线值
    long_mavg = data.history(sid, 'price', context.long_period, '1d').mean()
    # 账户资金
    cash = context.portfolio.cash;
    # 账户持仓
    cur_pos = context.portfolio.positions[sid].amount
    
    # 策略逻辑部分
    # 空仓状态下,短周期均线上穿(大于)长周期均线形成金叉,且该股票可以交易,买入
    # 持仓状态下,短周期均线下穿(小于)长周期均线形成死叉,且该股票可以交易,卖出
    if (short_mavg > long_mavg and cur_pos == 0 and data.can_trade(sid)):
        context.order_target_percent(sid,1)
    elif (short_mavg < long_mavg and cur_pos > 0 and data.can_trade(sid)):
        context.order_target_percent(sid, 0)
In [4]:
history_ds=DataSource.write_df(DataSource('bar1d_HBI').read(instruments,start='2017-05-01', end=end_date))
benchmark_ds = DataSource.write_df(DataSource('bar1d_HBI').read([benchmark],start='2017-05-01', end=end_date))

m = M.trade.v4(
    instruments=instruments,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    # 买入的时候,假设以次日开盘价成交
    order_price_field_buy='open',
    # 卖出的时候,假设以次日开盘价成交
    order_price_field_sell='close',
    capital_base=capital_base+2,
    benchmark=benchmark_ds,
    m_deps=np.random.rand(),
    history_ds=history_ds,
    data_frequency='daily'
)
  • 收益率22.06%
  • 年化收益率39.16%
  • 基准收益率1.74%
  • 阿尔法0.3
  • 贝塔0.44
  • 夏普比率0.77
  • 胜率0.33
  • 盈亏比3.57
  • 收益波动率77.52%
  • 信息比率-0.01
  • 最大回撤49.23%
bigcharts-data-start/{"__type":"tabs","__id":"bigchart-da2ce7f49b2b4bcf83c55ad0dda8854e"}/bigcharts-data-end