merge: 合并 wikillm 与 wikillm-git,全部内容入库(abuquant-src/OCR产物/images/IDEA.md)
This commit is contained in:
@@ -0,0 +1,405 @@
|
||||
# -*- encoding:utf-8 -*-
|
||||
from __future__ import print_function
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import warnings
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
import abu_local_env
|
||||
|
||||
import abupy
|
||||
from abupy import AbuFactorBuyBreak
|
||||
from abupy import AbuFactorSellBreak
|
||||
from abupy import AbuFactorAtrNStop
|
||||
from abupy import AbuFactorPreAtrNStop
|
||||
from abupy import AbuFactorCloseAtrNStop
|
||||
from abupy import AbuBenchmark
|
||||
from abupy import AbuPickTimeWorker
|
||||
from abupy import AbuCapital
|
||||
from abupy import AbuKLManager
|
||||
from abupy import ABuTradeProxy
|
||||
from abupy import ABuTradeExecute
|
||||
from abupy import ABuPickTimeExecute
|
||||
from abupy import AbuMetricsBase
|
||||
from abupy import ABuMarket
|
||||
from abupy import AbuPickTimeMaster
|
||||
from abupy import ABuRegUtil
|
||||
from abupy import AbuPickRegressAngMinMax
|
||||
from abupy import AbuPickStockWorker
|
||||
from abupy import ABuPickStockExecute
|
||||
from abupy import AbuPickStockPriceMinMax
|
||||
from abupy import AbuPickStockMaster
|
||||
|
||||
warnings.filterwarnings('ignore')
|
||||
sns.set_context(rc={'figure.figsize': (14, 7)})
|
||||
# 使用沙盒数据,目的是和书中一样的数据环境
|
||||
abupy.env.enable_example_env_ipython()
|
||||
|
||||
|
||||
"""
|
||||
第八章 量化系统——开发
|
||||
|
||||
abu量化系统github地址:https://github.com/bbfamily/abu (您的star是我的动力!)
|
||||
abu量化文档教程ipython notebook:https://github.com/bbfamily/abu/tree/master/abupy_lecture
|
||||
"""
|
||||
|
||||
|
||||
def sample_811():
|
||||
"""
|
||||
8.1.1 买入因子的实现
|
||||
:return:
|
||||
"""
|
||||
# buy_factors 60日向上突破,42日向上突破两个因子
|
||||
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
kl_pd_manager = AbuKLManager(benchmark, capital)
|
||||
# 获取TSLA的交易数据
|
||||
kl_pd = kl_pd_manager.get_pick_time_kl_pd('usTSLA')
|
||||
abu_worker = AbuPickTimeWorker(capital, kl_pd, benchmark, buy_factors, None)
|
||||
abu_worker.fit()
|
||||
|
||||
orders_pd, action_pd, _ = ABuTradeProxy.trade_summary(abu_worker.orders, kl_pd, draw=True)
|
||||
|
||||
ABuTradeExecute.apply_action_to_capital(capital, action_pd, kl_pd_manager)
|
||||
capital.capital_pd.capital_blance.plot()
|
||||
plt.show()
|
||||
|
||||
|
||||
def sample_812():
|
||||
"""
|
||||
8.1.2 卖出因子的实现
|
||||
:return:
|
||||
"""
|
||||
# 120天向下突破为卖出信号
|
||||
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
|
||||
# 趋势跟踪策略止盈要大于止损设置值,这里0.5,3.0
|
||||
sell_factor2 = {'stop_loss_n': 0.5, 'stop_win_n': 3.0, 'class': AbuFactorAtrNStop}
|
||||
# 暴跌止损卖出因子形成dict
|
||||
sell_factor3 = {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.0}
|
||||
# 保护止盈卖出因子组成dict
|
||||
sell_factor4 = {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
|
||||
# 四个卖出因子同时生效,组成sell_factors
|
||||
sell_factors = [sell_factor1, sell_factor2, sell_factor3, sell_factor4]
|
||||
# buy_factors 60日向上突破,42日向上突破两个因子
|
||||
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
benchmark = AbuBenchmark()
|
||||
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(
|
||||
['usTSLA'], benchmark, buy_factors, sell_factors, capital, show=True)
|
||||
|
||||
|
||||
def sample_813():
|
||||
"""
|
||||
8.1.3 滑点买入卖出价格确定及策略实现
|
||||
:return:
|
||||
"""
|
||||
from abupy import AbuSlippageBuyBase
|
||||
|
||||
# 修改g_open_down_rate的值为0.02
|
||||
g_open_down_rate = 0.02
|
||||
|
||||
# noinspection PyClassHasNoInit
|
||||
class AbuSlippageBuyMean2(AbuSlippageBuyBase):
|
||||
def fit_price(self):
|
||||
if (self.kl_pd_buy.open / self.kl_pd_buy.pre_close) < (
|
||||
1 - g_open_down_rate):
|
||||
# 开盘下跌K_OPEN_DOWN_RATE以上,单子失效
|
||||
print(self.factor_name + 'open down threshold')
|
||||
return np.inf
|
||||
# 买入价格为当天均价
|
||||
self.buy_price = np.mean(
|
||||
[self.kl_pd_buy['high'], self.kl_pd_buy['low']])
|
||||
return self.buy_price
|
||||
|
||||
# 只针对60使用AbuSlippageBuyMean2
|
||||
buy_factors2 = [{'slippage': AbuSlippageBuyMean2, 'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
|
||||
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
|
||||
sell_factor2 = {'stop_loss_n': 0.5, 'stop_win_n': 3.0, 'class': AbuFactorAtrNStop}
|
||||
sell_factor3 = {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.0}
|
||||
sell_factor4 = {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
|
||||
sell_factors = [sell_factor1, sell_factor2, sell_factor3, sell_factor4]
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(
|
||||
['usTSLA'], benchmark, buy_factors2, sell_factors, capital, show=True)
|
||||
|
||||
|
||||
def sample_814(show=True):
|
||||
"""
|
||||
8.1.4 对多支股票进行择时
|
||||
:return:
|
||||
"""
|
||||
|
||||
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
|
||||
sell_factor2 = {'stop_loss_n': 0.5, 'stop_win_n': 3.0, 'class': AbuFactorAtrNStop}
|
||||
sell_factor3 = {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.0}
|
||||
sell_factor4 = {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
|
||||
sell_factors = [sell_factor1, sell_factor2, sell_factor3, sell_factor4]
|
||||
benchmark = AbuBenchmark()
|
||||
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
|
||||
choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS']
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
orders_pd, action_pd, all_fit_symbols_cnt = ABuPickTimeExecute.do_symbols_with_same_factors(choice_symbols,
|
||||
benchmark, buy_factors,
|
||||
sell_factors, capital,
|
||||
show=False)
|
||||
|
||||
metrics = AbuMetricsBase(orders_pd, action_pd, capital, benchmark)
|
||||
metrics.fit_metrics()
|
||||
if show:
|
||||
print('orders_pd[:10]:\n', orders_pd[:10].filter(
|
||||
['symbol', 'buy_price', 'buy_cnt', 'buy_factor', 'buy_pos', 'sell_date', 'sell_type_extra', 'sell_type',
|
||||
'profit']))
|
||||
print('action_pd[:10]:\n', action_pd[:10])
|
||||
metrics.plot_returns_cmp(only_show_returns=True)
|
||||
return metrics
|
||||
|
||||
|
||||
def sample_815():
|
||||
"""
|
||||
8.1.5 自定义仓位管理策略的实现
|
||||
:return:
|
||||
"""
|
||||
metrics = sample_814(False)
|
||||
print('\nmetrics.gains_mean:{}, -metrics.losses_mean:{}'.format(metrics.gains_mean, -metrics.losses_mean))
|
||||
|
||||
from abupy import AbuKellyPosition
|
||||
# 42d使用AbuKellyPosition,60d仍然使用默认仓位管理类
|
||||
buy_factors2 = [{'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'position': AbuKellyPosition, 'win_rate': metrics.win_rate,
|
||||
'gains_mean': metrics.gains_mean, 'losses_mean': -metrics.losses_mean,
|
||||
'class': AbuFactorBuyBreak}]
|
||||
|
||||
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
|
||||
sell_factor2 = {'stop_loss_n': 0.5, 'stop_win_n': 3.0, 'class': AbuFactorAtrNStop}
|
||||
sell_factor3 = {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.0}
|
||||
sell_factor4 = {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
|
||||
sell_factors = [sell_factor1, sell_factor2, sell_factor3, sell_factor4]
|
||||
benchmark = AbuBenchmark()
|
||||
choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS']
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
orders_pd, action_pd, all_fit_symbols_cnt = ABuPickTimeExecute.do_symbols_with_same_factors(choice_symbols,
|
||||
benchmark, buy_factors2,
|
||||
sell_factors, capital,
|
||||
show=False)
|
||||
print(orders_pd[:10].filter(['symbol', 'buy_cnt', 'buy_factor', 'buy_pos']))
|
||||
|
||||
|
||||
def sample_816():
|
||||
"""
|
||||
8.1.6 多支股票使用不同的因子进行择时
|
||||
:return:
|
||||
"""
|
||||
# 选定noah和sfun
|
||||
target_symbols = ['usSFUN', 'usNOAH']
|
||||
# 针对sfun只使用42d向上突破作为买入因子
|
||||
buy_factors_sfun = [{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
# 针对sfun只使用60d向下突破作为卖出因子
|
||||
sell_factors_sfun = [{'xd': 60, 'class': AbuFactorSellBreak}]
|
||||
|
||||
# 针对noah只使用21d向上突破作为买入因子
|
||||
buy_factors_noah = [{'xd': 21, 'class': AbuFactorBuyBreak}]
|
||||
# 针对noah只使用42d向下突破作为卖出因子
|
||||
sell_factors_noah = [{'xd': 42, 'class': AbuFactorSellBreak}]
|
||||
|
||||
factor_dict = dict()
|
||||
# 构建SFUN独立的buy_factors,sell_factors的dict
|
||||
factor_dict['usSFUN'] = {'buy_factors': buy_factors_sfun, 'sell_factors': sell_factors_sfun}
|
||||
# 构建NOAH独立的buy_factors,sell_factors的dict
|
||||
factor_dict['usNOAH'] = {'buy_factors': buy_factors_noah, 'sell_factors': sell_factors_noah}
|
||||
# 初始化资金
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
# 使用do_symbols_with_diff_factors执行
|
||||
orders_pd, action_pd, all_fit_symbols = ABuPickTimeExecute.do_symbols_with_diff_factors(
|
||||
target_symbols, benchmark, factor_dict, capital)
|
||||
print('pd.crosstab(orders_pd.buy_factor, orders_pd.symbol):\n', pd.crosstab(orders_pd.buy_factor, orders_pd.symbol))
|
||||
|
||||
|
||||
def sample_817():
|
||||
"""
|
||||
8.1.7 使用并行来提升择时运行效率
|
||||
:return:
|
||||
"""
|
||||
# 要关闭沙盒数据环境,因为沙盒里就那几个股票的历史数据, 下面要随机做50个股票
|
||||
from abupy import EMarketSourceType
|
||||
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_tx
|
||||
|
||||
abupy.env.disable_example_env_ipython()
|
||||
|
||||
# 关闭沙盒后,首先基准要从非沙盒环境换取,否则数据对不齐,无法正常运行
|
||||
benchmark = AbuBenchmark()
|
||||
# 当传入choice_symbols为None时代表对整个市场的所有股票进行回测
|
||||
# noinspection PyUnusedLocal
|
||||
choice_symbols = None
|
||||
# 顺序获取市场后300支股票
|
||||
# noinspection PyUnusedLocal
|
||||
choice_symbols = ABuMarket.all_symbol()[-50:]
|
||||
# 随机获取300支股票
|
||||
choice_symbols = ABuMarket.choice_symbols(50)
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
|
||||
sell_factor1 = {'xd': 120, 'class': AbuFactorSellBreak}
|
||||
sell_factor2 = {'stop_loss_n': 0.5, 'stop_win_n': 3.0, 'class': AbuFactorAtrNStop}
|
||||
sell_factor3 = {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.0}
|
||||
sell_factor4 = {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
|
||||
sell_factors = [sell_factor1, sell_factor2, sell_factor3, sell_factor4]
|
||||
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
|
||||
{'xd': 42, 'class': AbuFactorBuyBreak}]
|
||||
|
||||
orders_pd, action_pd, _ = AbuPickTimeMaster.do_symbols_with_same_factors_process(
|
||||
choice_symbols, benchmark, buy_factors, sell_factors,
|
||||
capital)
|
||||
|
||||
metrics = AbuMetricsBase(orders_pd, action_pd, capital, benchmark)
|
||||
metrics.fit_metrics()
|
||||
metrics.plot_returns_cmp(only_show_returns=True)
|
||||
|
||||
abupy.env.enable_example_env_ipython()
|
||||
|
||||
|
||||
"""
|
||||
注意所有选股结果等等与书中的结果不一致,因为要控制沙盒数据体积小于50mb, 所以沙盒数据有些symbol只有两年多一点,与原始环境不一致,
|
||||
直接达不到选股的min_xd,所以这里其实可以`abupy.env.disable_example_env_ipython()`关闭沙盒环境,直接上真实数据。
|
||||
"""
|
||||
|
||||
|
||||
def sample_821_1():
|
||||
"""
|
||||
8.2.1_1 选股使用示例
|
||||
:return:
|
||||
"""
|
||||
# 选股条件threshold_ang_min=0.0, 即要求股票走势为向上上升趋势
|
||||
stock_pickers = [{'class': AbuPickRegressAngMinMax,
|
||||
'threshold_ang_min': 0.0, 'reversed': False}]
|
||||
|
||||
# 从这几个股票里进行选股,只是为了演示方便
|
||||
# 一般的选股都会是数量比较多的情况比如全市场股票
|
||||
choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG',
|
||||
'usTSLA', 'usWUBA', 'usVIPS']
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
kl_pd_manager = AbuKLManager(benchmark, capital)
|
||||
stock_pick = AbuPickStockWorker(capital, benchmark, kl_pd_manager,
|
||||
choice_symbols=choice_symbols,
|
||||
stock_pickers=stock_pickers)
|
||||
stock_pick.fit()
|
||||
# 打印最后的选股结果
|
||||
print('stock_pick.choice_symbols:', stock_pick.choice_symbols)
|
||||
|
||||
# 从kl_pd_manager缓存中获取选股走势数据,注意get_pick_stock_kl_pd为选股数据,get_pick_time_kl_pd为择时
|
||||
kl_pd_noah = kl_pd_manager.get_pick_stock_kl_pd('usNOAH')
|
||||
# 绘制并计算角度
|
||||
deg = ABuRegUtil.calc_regress_deg(kl_pd_noah.close)
|
||||
print('noah 选股周期内角度={}'.format(round(deg, 3)))
|
||||
|
||||
|
||||
def sample_821_2():
|
||||
"""
|
||||
8.2.1_2 ABuPickStockExecute
|
||||
:return:
|
||||
"""
|
||||
stock_pickers = [{'class': AbuPickRegressAngMinMax,
|
||||
'threshold_ang_min': 0.0, 'threshold_ang_max': 10.0,
|
||||
'reversed': False}]
|
||||
|
||||
choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG',
|
||||
'usTSLA', 'usWUBA', 'usVIPS']
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
kl_pd_manager = AbuKLManager(benchmark, capital)
|
||||
|
||||
print('ABuPickStockExecute.do_pick_stock_work:\n', ABuPickStockExecute.do_pick_stock_work(choice_symbols, benchmark,
|
||||
capital, stock_pickers))
|
||||
|
||||
kl_pd_sfun = kl_pd_manager.get_pick_stock_kl_pd('usSFUN')
|
||||
print('sfun 选股周期内角度={}'.format(round(ABuRegUtil.calc_regress_deg(kl_pd_sfun.close), 3)))
|
||||
|
||||
|
||||
def sample_821_3():
|
||||
"""
|
||||
8.2.1_3 reversed
|
||||
:return:
|
||||
"""
|
||||
# 和上面的代码唯一的区别就是reversed=True
|
||||
stock_pickers = [{'class': AbuPickRegressAngMinMax,
|
||||
'threshold_ang_min': 0.0, 'threshold_ang_max': 10.0, 'reversed': True}]
|
||||
|
||||
choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG',
|
||||
'usTSLA', 'usWUBA', 'usVIPS']
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
|
||||
print('ABuPickStockExecute.do_pick_stock_work:\n',
|
||||
ABuPickStockExecute.do_pick_stock_work(choice_symbols, benchmark, capital, stock_pickers))
|
||||
|
||||
|
||||
def sample_822():
|
||||
"""
|
||||
8.2.2 多个选股因子并行执行
|
||||
:return:
|
||||
"""
|
||||
# 选股list使用两个不同的选股因子组合,并行同时生效
|
||||
stock_pickers = [{'class': AbuPickRegressAngMinMax,
|
||||
'threshold_ang_min': 0.0, 'reversed': False},
|
||||
{'class': AbuPickStockPriceMinMax, 'threshold_price_min': 50.0,
|
||||
'reversed': False}]
|
||||
|
||||
choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG',
|
||||
'usTSLA', 'usWUBA', 'usVIPS']
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
|
||||
print('ABuPickStockExecute.do_pick_stock_work:\n',
|
||||
ABuPickStockExecute.do_pick_stock_work(choice_symbols, benchmark, capital, stock_pickers))
|
||||
|
||||
|
||||
def sample_823():
|
||||
"""
|
||||
8.2.3 使用并行来提升回测运行效率
|
||||
:return:
|
||||
"""
|
||||
from abupy import EMarketSourceType
|
||||
abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_tx
|
||||
abupy.env.disable_example_env_ipython()
|
||||
|
||||
benchmark = AbuBenchmark()
|
||||
capital = AbuCapital(1000000, benchmark)
|
||||
|
||||
# 首先随抽取50支股票
|
||||
choice_symbols = ABuMarket.choice_symbols(50)
|
||||
# 股价在15-50之间
|
||||
stock_pickers = [
|
||||
{'class': AbuPickStockPriceMinMax, 'threshold_price_min': 15.0,
|
||||
'threshold_price_max': 50.0, 'reversed': False}]
|
||||
cs = AbuPickStockMaster.do_pick_stock_with_process(capital, benchmark,
|
||||
stock_pickers,
|
||||
choice_symbols)
|
||||
print('len(cs):', len(cs))
|
||||
print('cs:\n', cs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sample_811()
|
||||
# sample_812()
|
||||
# sample_813()
|
||||
# sample_814()
|
||||
# sample_815()
|
||||
# sample_816()
|
||||
# sample_817()
|
||||
|
||||
# sample_821_1()
|
||||
# sample_821_2()
|
||||
# sample_821_3()
|
||||
# sample_822()
|
||||
# sample_823()
|
||||
Reference in New Issue
Block a user