<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 ABU量化系统使用文档
<center>
        <img src="./image/abu_logo.png" alt="" style="vertical-align
Step1:  下面先获取沙盒数据中美股一年的数据，为之后的分析做数据准备：
Step2:  1. 传统的双均线择时策略
双均线策略是量化策略中经典的策略之一，其属于趋势跟踪策略，基本实现思想如下
预设两条均线：比如一个ma=5，一个ma=60, 5的均线被称作快线，60的均线被称作慢线
择时买入策略中当快线上穿慢线（ma5上穿ma60）称为形成金叉买点信号，买入股票
择时卖出策略中当快线下穿慢线（ma5下穿ma60）称为形成死叉卖点信号，卖出股票
熟悉技术指标的朋友都知道比如macd，kdj等等依赖均线的技术指标，其核心思想都差不多。
下面使用abupy中的技术指标模块nd绘制一下上述文字描述，如下：
Step4:  上图中可以看到
第一次ma5(蓝线)上穿ma60(绿线)形成金叉的时候，没能够继续上升趋势，马上ma5下穿了ma60形成死叉卖出信号
第二次（红竖线）发出金叉信号的时候持续了上升趋势
下面使用abupy中内置的双均线策略进行回测示例，如下：
Step5:  通过度量对象可视化可以发现择时生效买入因子都是ma5上穿ma60的金叉信号，卖出择时因子并行了4个策略，可以看到ma5下穿ma60的死叉信号生效比例也很高，如下：
Step6:  下面从交易单中筛选出所有tsla的交易结果，如下所示：
Step7:  通过nd模块的plot_ma_from_order接口可视化tsla交易单中的第一笔交易，可以发现这笔交易就是本节开始时示例的tsla第一次ma5(蓝线)上穿ma60(绿线)形成金叉且没能够继续上升趋势，马上ma5下穿了ma60形成死叉卖出信号的那笔交易。
Step8:  继续可视化tsla交易单中的第二笔交易，可以发现这笔交易就是本节开始时示例的tsla第二次ma5上穿ma60发出金叉信号且持续了上升趋势的那笔交易。
Step9:  2. 真 • 动态自适应双均线策略
传统双均线策略当两根信号线差距比较大时，如上面ma5，ma60这种组合，属于迟钝金叉，即可能趋势以发生了很长时间甚至都快要结束的时候才能发出金叉买入信号，比如本节开始时绘制的tsla的两个金叉买入信号中的第一个信号。
那么如果调近两根均值的差距，比如使用ma5，ma20呢，下面绘制本节开始时绘制的tsla，ma参数改为5，20，如下：
Step10:  可以看到之前的金叉信号提前发出了，且死叉信号发出的也比较及时，这笔交易有一定的收益，但是注意观察其它的信号点可以发现产生了很多买卖信号，因为上面ma5，ma20这种组合，属于敏感金叉，这些信号中很多产生了失败的交易。
abupy中AbuDoubleMaBuy是动态自适应双均线策略，比如下面的参数中不传递快线值，只传递慢线值60，如下进行回测：
Step11:  下面可视化买入因子的生效分布，如下所示：
Step12:  可以看到买入因子慢线仍然使用参数中传递的60，快线有3，9，18三个值，这三个值是以慢线数值为基数，结合大盘的走势计算出来的。
策略中动态计算快线的策略主要参考了大盘最近一个月走势震荡程度，动态决策快线的值：
大盘最近一个月走势非常稳定：fast＝slow X 0.05 eg
Step13:  下面可视化买入因子的生效分布，如下所示：
Step14:  可以看到买入因子慢线的值从20到100不等，快线的值也从2到30不等。
策略中动态计算快线的策略和上述的方式相同，动态自适应慢线值主要依据重采样周期内的振幅值来确定，在第‘第10节 比特币, 莱特币的回测’中已经使用过resample_close_mean统计重采样周期内的振幅值，如下：
<ASSISTANT_TASK:>
Python Code:
# 基础库导入
from __future__ import print_function
from __future__ import division
import warnings
warnings.filterwarnings('ignore')
warnings.simplefilter('ignore')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import os
import sys
# 使用insert 0即只使用github，避免交叉使用了pip安装的abupy，导致的版本不一致问题
sys.path.insert(0, os.path.abspath('../'))
import abupy
# 使用沙盒数据，目的是和书中一样的数据环境
abupy.env.enable_example_env_ipython()
from abupy import AbuDoubleMaBuy, AbuDoubleMaSell, ABuKLUtil, ABuSymbolPd
from abupy import AbuFactorCloseAtrNStop, AbuFactorAtrNStop, AbuFactorPreAtrNStop
from abupy import abu, ABuProgress, AbuMetricsBase, EMarketTargetType, nd
Explanation: ABU量化系统使用文档
<center>
        <img src="./image/abu_logo.png" alt="" style="vertical-align:middle;padding:10px 20px;"><font size="6" color="black"><b>第28节 真 • 动态自适应双均线策略</b></font>
</center>
作者: 阿布
阿布量化版权所有 未经允许 禁止转载
abu量化系统github地址 (欢迎+star)
本节ipython notebook
上一节讲解了选股策略与择时策略相互配合的示例，本节的内容将讲解择时策略中的经典策略双均线策略，以及它的优化版本动态自适应双均线策略。
首先导入本节需要使用的abupy中的模块：
End of explanation
# 使用沙盒内的美股做为回测目标
us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 
                     'usGOOG', 'usWUBA', 'usVIPS']
kl_dict = {us_symbol[2:]: 
 ABuSymbolPd.make_kl_df(us_symbol, start='2014-07-26', end='2015-07-26') 
 for us_symbol in us_choice_symbols}
Explanation: 下面先获取沙盒数据中美股一年的数据，为之后的分析做数据准备：
End of explanation
nd.ma.plot_ma_from_klpd(kl_dict['TSLA'], time_period=(5, 60), 
                        with_points_ext=pd.to_datetime('2015-04-09'), 
                        with_points=pd.to_datetime('2014-11-17'))
Explanation: 1. 传统的双均线择时策略
双均线策略是量化策略中经典的策略之一，其属于趋势跟踪策略，基本实现思想如下
预设两条均线：比如一个ma=5，一个ma=60, 5的均线被称作快线，60的均线被称作慢线
择时买入策略中当快线上穿慢线（ma5上穿ma60）称为形成金叉买点信号，买入股票
择时卖出策略中当快线下穿慢线（ma5下穿ma60）称为形成死叉卖点信号，卖出股票
熟悉技术指标的朋友都知道比如macd，kdj等等依赖均线的技术指标，其核心思想都差不多。
下面使用abupy中的技术指标模块nd绘制一下上述文字描述，如下：
End of explanation
# 初始资金量
cash = 3000000
def run_loo_back(choice_symbols, ps=None, n_folds=2, start=None, end=None, only_info=False):
    封装一个回测函数，返回回测结果，以及回测度量对象
    if choice_symbols[0].startswith('us'):
        abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_US
    else:
        abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
    abu_result_tuple, _ = abu.run_loop_back(cash,
                                           buy_factors,
                                           sell_factors,
                                           ps,
                                           start=start,
                                           end=end,
                                           n_folds=n_folds,
                                           choice_symbols=choice_symbols)
    ABuProgress.clear_output()
    metrics = AbuMetricsBase.show_general(*abu_result_tuple, returns_cmp=only_info, 
                                only_info=only_info,
                                only_show_returns=True)
    return abu_result_tuple, metrics
# 买入双均线策略AbuDoubleMaBuy寻找金叉买入信号：ma快线＝5，ma慢线＝60
buy_factors = [{'fast': 5, 'slow': 60, 'class': AbuDoubleMaBuy}]
# 卖出双均线策略AbuDoubleMaSell寻找死叉卖出信号：ma快线＝5，ma慢线＝60，并行继续使用止盈止损基础策略
sell_factors = [{'fast': 5, 'slow': 60, 'class': AbuDoubleMaSell},
                {'stop_loss_n': 1.0, 'stop_win_n': 3.0,
                 'class': AbuFactorAtrNStop},
                {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},
                {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]
# 开始回测
abu_result_tuple, metrics = run_loo_back(us_choice_symbols)
Explanation: 上图中可以看到
第一次ma5(蓝线)上穿ma60(绿线)形成金叉的时候，没能够继续上升趋势，马上ma5下穿了ma60形成死叉卖出信号
第二次（红竖线）发出金叉信号的时候持续了上升趋势
下面使用abupy中内置的双均线策略进行回测示例，如下：
End of explanation
metrics.plot_buy_factors()
metrics.plot_sell_factors()
Explanation: 通过度量对象可视化可以发现择时生效买入因子都是ma5上穿ma60的金叉信号，卖出择时因子并行了4个策略，可以看到ma5下穿ma60的死叉信号生效比例也很高，如下：
End of explanation
tsla_orders = abu_result_tuple.orders_pd[abu_result_tuple.orders_pd.symbol=='usTSLA']
tsla_orders
Explanation: 下面从交易单中筛选出所有tsla的交易结果，如下所示：
End of explanation
nd.ma.plot_ma_from_order(tsla_orders.iloc[0], time_period=(5, 60))
Explanation: 通过nd模块的plot_ma_from_order接口可视化tsla交易单中的第一笔交易，可以发现这笔交易就是本节开始时示例的tsla第一次ma5(蓝线)上穿ma60(绿线)形成金叉且没能够继续上升趋势，马上ma5下穿了ma60形成死叉卖出信号的那笔交易。
End of explanation
nd.ma.plot_ma_from_order(tsla_orders.iloc[1], time_period=(5, 60))
Explanation: 继续可视化tsla交易单中的第二笔交易，可以发现这笔交易就是本节开始时示例的tsla第二次ma5上穿ma60发出金叉信号且持续了上升趋势的那笔交易。
End of explanation
nd.ma.plot_ma_from_klpd(kl_dict['TSLA'], time_period=(5, 20), 
                        with_points_ext=pd.to_datetime('2014-11-25'), 
                        with_points=pd.to_datetime('2014-10-31'))
Explanation: 2. 真 • 动态自适应双均线策略
传统双均线策略当两根信号线差距比较大时，如上面ma5，ma60这种组合，属于迟钝金叉，即可能趋势以发生了很长时间甚至都快要结束的时候才能发出金叉买入信号，比如本节开始时绘制的tsla的两个金叉买入信号中的第一个信号。
那么如果调近两根均值的差距，比如使用ma5，ma20呢，下面绘制本节开始时绘制的tsla，ma参数改为5，20，如下：
End of explanation
# 只传递慢线60，不传递快线参数为动态自适应快线值
buy_factors = [{'slow': 60, 'class': AbuDoubleMaBuy}]
abu_result_tuple, metrics = run_loo_back(us_choice_symbols)
Explanation: 可以看到之前的金叉信号提前发出了，且死叉信号发出的也比较及时，这笔交易有一定的收益，但是注意观察其它的信号点可以发现产生了很多买卖信号，因为上面ma5，ma20这种组合，属于敏感金叉，这些信号中很多产生了失败的交易。
abupy中AbuDoubleMaBuy是动态自适应双均线策略，比如下面的参数中不传递快线值，只传递慢线值60，如下进行回测：
End of explanation
metrics.plot_buy_factors()
Explanation: 下面可视化买入因子的生效分布，如下所示：
End of explanation
# 不传递任何参数，快线， 慢线都动态自适应
buy_factors = [{'class': AbuDoubleMaBuy}]
abu_result_tuple, metrics = run_loo_back(us_choice_symbols)
Explanation: 可以看到买入因子慢线仍然使用参数中传递的60，快线有3，9，18三个值，这三个值是以慢线数值为基数，结合大盘的走势计算出来的。
策略中动态计算快线的策略主要参考了大盘最近一个月走势震荡程度，动态决策快线的值：
大盘最近一个月走势非常稳定：fast＝slow X 0.05 eg: slow=60->fast=60 X 0.05=3
大盘最近一个月走势比较稳定：fast＝slow X 0.15 eg: slow=60->fast=60 X 0.15=9
大盘最近一个月走势比较震荡：fast＝slow X 0.3 eg: slow=60->fast=60 X 0.3=18
大盘最近一个月走势非常震荡：fast＝slow X 0.5 eg: slow=60->fast=60 X0.5=30
择时周期内每一个月重新计算一次
具体实现以及如何判定大盘的震荡程度请自行阅读源代码
上面的双均线策略中的慢线依然是通过参数传递，下面示例慢线参数也动态自适应计算的回测，如下：
End of explanation
metrics.plot_buy_factors()
Explanation: 下面可视化买入因子的生效分布，如下所示：
End of explanation
ABuKLUtil.resample_close_mean(kl_dict)
Explanation: 可以看到买入因子慢线的值从20到100不等，快线的值也从2到30不等。
策略中动态计算快线的策略和上述的方式相同，动态自适应慢线值主要依据重采样周期内的振幅值来确定，在第‘第10节 比特币, 莱特币的回测’中已经使用过resample_close_mean统计重采样周期内的振幅值，如下：
End of explanation
<END_TASK>