<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:  到目前为止已经示例了很多买入因子，abupy中一个特点即是可以在交易中使用多个买入，卖出因子并行执行生效。
在回测交易中可以组织多个买入因子构建序列，如：
自适应动态双均线买入金叉策略
海龟42天周期向上突破买入策略
大盘拟合稳定21天突破买入策略
亦可以组织多个卖出策略构建序列，如：
双均线卖出死叉策略
海龟21天周期向下突破卖出策略
基本止盈止损策略：止损1.0，止盈3.0
风险控制止损策略：参数1.5
利润保护止盈策略：参数1.5
下面代码按照上述进行买入，卖出因子序列构建，如下：
Step4:  构建完策略后，下面使用沙盒数据美股数据，示例并行执行上述策略进行回测，如下：
Step5:  下面可视化各个买入因子的生效数量以及比例，如下：
Step6:  下面可视化各个卖出因子的生效数量比例，可以发现双均线卖出死叉策略(AbuDoubleMaSell)和海龟21天周期向下突破卖出策略(AbuFactorSellBreak)生效的比例和数量都很多：
Step7:  虽然上面的回测没有出错，但是本示例中多因子策略的设计组织本来是想要如下效果的：
即理想的多因子策略组织为：
基础卖出因子（止盈止损&风险控制&利润保护）对应所有买入因子生效
海龟21天周期向下卖出只对应海龟42天周期向上买入生效
双均线卖出死叉只对应买入动态双均线金叉生效
这个问题在有些特殊的卖出因子组合下还会导致整体策略组合配合出错，如下
买入因子组合中添加在‘第26节 星期几是这个股票的好日子’中示例的周期短线均值回复买入策略AbuFactorBuyWD
卖出因子组合中添加AbuFactorSellNDay，sell_n=1配合AbuFactorBuyWD短线买入策略持有一天就卖出股票
添加后进行回测，代码如下所示：
Step8:  由上回测结果可以看到效果很差，统计交易单中个买入因子所对应的卖出因子，可以发现卖出因子全部都使用了AbuFactorSellNDay，即所有的交易都只持有了一天就在第二天卖出了股票，如下所示：
Step10:  这肯定不是整体策略设计的意愿，实际上只是想要短线均值回复买入策略AbuFactorBuyWD使用持有一天就卖出的策略，其它的买入策略不应该使用。
要解决上述问题，只需要在买入因子字典中单独配置卖出因子策略，在全局的卖出因子策略序列中只配置适应全局卖出的策略，如下所示：
Step11:  上面代码的买入，卖出因子策略组织即完成了理想的因子配合方式，如下：
基础卖出因子（止盈止损&风险控制&利润保护）对应所有买入因子生效
海龟21天周期向下卖出只对应海龟42天周期向上买入生效
双均线卖出死叉只对应买入动态双均线金叉生效
持有一天就卖出策略AbuFactorSellNDay只对应短线均值回复买入策略AbuFactorBuyWD
更进一步从下面回测单子中买入因子所对应的卖出因子可看到：
AbuDoubleMaSell只对应AbuDoubleMaBuy
AbuFactorSellBreak只对应AbuFactorBuyBreak
AbuFactorSellNDay只对应AbuFactorBuyWD
如下所示：
<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, AbuSDBreak, AbuFactorBuyBreak
from abupy import AbuFactorCloseAtrNStop, AbuFactorAtrNStop, AbuFactorPreAtrNStop
from abupy import abu, ABuProgress, AbuMetricsBase, EMarketTargetType
from abupy import AbuFactorSellNDay, AbuFactorBuyWD, AbuFactorSellBreak
Explanation: ABU量化系统使用文档
<center>
        <img src="./image/abu_logo.png" alt="" style="vertical-align:middle;padding:10px 20px;"><font size="6" color="black"><b>第29节 多因子策略并行执行配合</b></font>
</center>
作者: 阿布
阿布量化版权所有 未经允许 禁止转载
abu量化系统github地址 (欢迎+star)
本节ipython notebook
上一节讲解了经典择时策略双均线的示例，本节讲解多因子策略并行执行配合。
首先导入本节需要使用的abupy中的模块：
End of explanation
buy_factors = [{'class': AbuDoubleMaBuy},
               {'xd': 42, 'class': AbuFactorBuyBreak}, 
               {'xd': 21, 'class': AbuSDBreak}]
sell_factors = [
    {'class': AbuDoubleMaSell},
    {'xd': 21, 'class': AbuFactorSellBreak},
    {'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}
]
Explanation: 到目前为止已经示例了很多买入因子，abupy中一个特点即是可以在交易中使用多个买入，卖出因子并行执行生效。
在回测交易中可以组织多个买入因子构建序列，如：
自适应动态双均线买入金叉策略
海龟42天周期向上突破买入策略
大盘拟合稳定21天突破买入策略
亦可以组织多个卖出策略构建序列，如：
双均线卖出死叉策略
海龟21天周期向下突破卖出策略
基本止盈止损策略：止损1.0，止盈3.0
风险控制止损策略：参数1.5
利润保护止盈策略：参数1.5
下面代码按照上述进行买入，卖出因子序列构建，如下：
End of explanation
# 使用沙盒内的美股做为回测目标
us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 
                     'usGOOG', 'usWUBA', 'usVIPS']
# 初始资金量
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)
    
        这里把所有因子的唯一名称只取类名称，不要参数了:
        eg：AbuDoubleMaBuy:fast=5,slow=60->AbuDoubleMaBuy
    
    abu_result_tuple.orders_pd['buy_factor'] = abu_result_tuple.orders_pd[
        'buy_factor'].apply(lambda bf: bf.split(':')[0])
    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
abu_result_tuple, metrics = run_loo_back(us_choice_symbols)
Explanation: 构建完策略后，下面使用沙盒数据美股数据，示例并行执行上述策略进行回测，如下：
End of explanation
metrics.plot_buy_factors()
Explanation: 下面可视化各个买入因子的生效数量以及比例，如下：
End of explanation
metrics.plot_sell_factors()
Explanation: 下面可视化各个卖出因子的生效数量比例，可以发现双均线卖出死叉策略(AbuDoubleMaSell)和海龟21天周期向下突破卖出策略(AbuFactorSellBreak)生效的比例和数量都很多：
End of explanation
# 添加AbuFactorBuyWD
buy_factors = [
               {'class': AbuFactorBuyWD},
               {'class': AbuDoubleMaBuy},
               {'xd': 42, 'class': AbuFactorBuyBreak}, 
               {'xd': 21, 'class': AbuSDBreak}]
# 添加AbuFactorSellNDay
sell_factors = [
    {'class': AbuFactorSellNDay, 'sell_n': 1, 'is_sell_today': True},
    {'class': AbuDoubleMaSell},
    {'xd': 21, 'class': AbuFactorSellBreak},
    {'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: 虽然上面的回测没有出错，但是本示例中多因子策略的设计组织本来是想要如下效果的：
即理想的多因子策略组织为：
基础卖出因子（止盈止损&风险控制&利润保护）对应所有买入因子生效
海龟21天周期向下卖出只对应海龟42天周期向上买入生效
双均线卖出死叉只对应买入动态双均线金叉生效
这个问题在有些特殊的卖出因子组合下还会导致整体策略组合配合出错，如下
买入因子组合中添加在‘第26节 星期几是这个股票的好日子’中示例的周期短线均值回复买入策略AbuFactorBuyWD
卖出因子组合中添加AbuFactorSellNDay，sell_n=1配合AbuFactorBuyWD短线买入策略持有一天就卖出股票
添加后进行回测，代码如下所示：
End of explanation
abu_result_tuple.orders_pd.groupby('buy_factor')['sell_type_extra'].value_counts()
Explanation: 由上回测结果可以看到效果很差，统计交易单中个买入因子所对应的卖出因子，可以发现卖出因子全部都使用了AbuFactorSellNDay，即所有的交易都只持有了一天就在第二天卖出了股票，如下所示：
End of explanation
    持有一天卖出策略AbuFactorSellNDay只对应AbuFactorBuyWD生效
    双均线卖出死叉只对应买入动态双均线金叉生效
    海龟21天周期向下卖出只对应海龟42天周期向上买入生效
buy_factors = [
               {'class': AbuFactorBuyWD, 
                'sell_factors': [{'class': AbuFactorSellNDay, 
                                  'sell_n': 1, 'is_sell_today': True}]},
               {'class': AbuDoubleMaBuy, 
                'sell_factors': [{'fast': 5, 'slow': 60, 
                                  'class': AbuDoubleMaSell}]},
               {'xd': 42, 'class': AbuFactorBuyBreak, 
                'sell_factors': [{'xd': 21, 
                                  'class': AbuFactorSellBreak}]}, 
               {'xd': 21, 'class': AbuSDBreak}]
# 基础卖出因子（止盈止损&风险控制&利润保护）对应所有买入因子生效
sell_factors = [
    {'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: 这肯定不是整体策略设计的意愿，实际上只是想要短线均值回复买入策略AbuFactorBuyWD使用持有一天就卖出的策略，其它的买入策略不应该使用。
要解决上述问题，只需要在买入因子字典中单独配置卖出因子策略，在全局的卖出因子策略序列中只配置适应全局卖出的策略，如下所示：
End of explanation
abu_result_tuple.orders_pd.groupby('buy_factor')['sell_type_extra'].value_counts()
Explanation: 上面代码的买入，卖出因子策略组织即完成了理想的因子配合方式，如下：
基础卖出因子（止盈止损&风险控制&利润保护）对应所有买入因子生效
海龟21天周期向下卖出只对应海龟42天周期向上买入生效
双均线卖出死叉只对应买入动态双均线金叉生效
持有一天就卖出策略AbuFactorSellNDay只对应短线均值回复买入策略AbuFactorBuyWD
更进一步从下面回测单子中买入因子所对应的卖出因子可看到：
AbuDoubleMaSell只对应AbuDoubleMaBuy
AbuFactorSellBreak只对应AbuFactorBuyBreak
AbuFactorSellNDay只对应AbuFactorBuyWD
如下所示：
End of explanation
<END_TASK>