# 安装必须的库
# 这里是在web浏览器中运行的jupyter lab, "!" 后面紧接着shell command
! pip install abupy -i "https://mirrors.aliyun.com/pypi/simple/"
! pip install tushare -i "https://mirrors.aliyun.com/pypi/simple/"
! pip install mplfinance -i "https://mirrors.aliyun.com/pypi/simple/"
#
import os
import sys
# 使用insert 0即只使用github,避免交叉使用了pip安装的abupy,导致的版本不一致问题
sys.path.insert(0, os.path.abspath('../'))
import abupy
from abupy import env
abupy.env.disable_example_env_ipython()
量化交易可以简单的理解为“用计算机程式代码分析行情和执行交易”。 so,你得先有行情数据。
import tushare as ts
from config import tushare_config
ts.set_token(tushare_config.get_token())
pro = ts.pro_api()
# kl_df: KLine pandas dataFrame
# 600519是贵州茅台哈
kl_df = ts.pro_bar(ts_code= '600519.sh', adj='qfq', asset='E',
start_date='2018-08-08', end_date='2020-02-22')
kl_df
对,就是这些数据。我们在炒股app看到的各种花狸狐哨/huā lí hú shào/(胡里花俏/胡里花哨)的图表基本都是用这样包含了 open(开盘价)、high(最高价)、low(最低价)、close(收盘价)、vol(成交量)、 amount(成交额)的数据计算出来的。
不过数据是给计算机读的,人类一般看行情图。
from abupy import abu, ABuSymbolPd
# from abupy.MarketBu import ABuMarketDrawing
import mplfinance as mpf
from wz.TushareKlineDs import TushareKlineDs
abupy.env.g_private_data_source = TushareKlineDs
kl_pd = ABuSymbolPd.make_kl_df('600519', start='2016-06-06', end='2020-02-22')
kl_pd = kl_pd[['open', 'close', 'high', 'low', 'volume', 'date']]
kl_pd.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'Date']
# 最近100天K线图,现在是夜间,不想亮瞎眼就用夜间主题了
mpf.plot(kl_pd[:100], type='candle', style='nightclouds')
是简陋了点, 不过可以加上均线和成交量。
By the way,这种简单画法叫“调包侠(自己不懂太多知识,也不做太多活,工作全靠调用别人懂得开发包完成)”。 故作高深一步一步学习画图请查看 数据科学实战的《手把手教你使用Matplotlib绘图|实战》
# 最近200个交易日K线、成交量和10,20,60日简单移动均线(SMA)
mpf.plot(kl_pd[:200], type='candle', style='nightclouds', mav=(10,20,60), volume=True)
还可以继续加各种技术指标等花狸狐哨/huā lí hú shào/(胡里花俏/胡里花哨)的,就像各类炒股app看起来的样子,不过这不是这里的重点,就不举例了。我们进入下一个主题。
假如在书上/网上看到“大师”说:“x日均线上穿y日均线买入,z日均线下穿y日均线卖出(或者金叉/死叉理论)能赚钱。”, 信还是不信呢? 这是个问题。对于很多人,这个得靠信仰!!
对于程序员,这个当然得靠代码了。试一下:
from abupy import AbuDoubleMaBuy, AbuDoubleMaSell
from abupy import AbuFactorCloseAtrNStop, AbuFactorAtrNStop, AbuFactorPreAtrNStop
from abupy import abu, ABuProgress, AbuMetricsBase, EMarketDataFetchMode, EMarketTargetType, nd
from abupy import slippage
# 开启针对非集合竞价阶段的涨停,滑点买入价格以高概率在接近涨停的价格买入
slippage.sbb.g_enable_limit_up = True
# 将集合竞价阶段的涨停买入成功概率设置为0,如果设置为0.2即20%概率成功买入
slippage.sbb.g_pre_limit_up_rate = 0
# 开启针对非集合竞价阶段的跌停,滑点卖出价格以高概率在接近跌停的价格卖出
slippage.ssb.g_enable_limit_down = True
# 将集合竞价阶段的跌停卖出成功概率设置为0, 如果设置为0.2即20%概率成功卖出
slippage.ssb.g_pre_limit_down_rate = 0
abupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_FORCE_LOCAL
abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN
# 总资金
cash = 200000
# 单次买入最大仓位
o_pos_base =0.1
abupy.beta.atr.g_atr_pos_base = o_pos_base * 8
def run_loo_back(choice_symbols, ps=None, n_folds=2, start='2012-12-12', end='2020-01-20', only_info=False):
"""封装一个回测函数,返回回测结果,以及回测度量对象"""
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,
n_process_kl = 1,
n_process_pick= 1,
)
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
# 买入卖出因子
buy_factors = [{'fast': 20, 'slow': 60, 'class': AbuDoubleMaBuy}]
sell_factors = [{'fast': 20, 'slow': 60, 'class': AbuDoubleMaSell},
{'stop_loss_n': 2.2, #'stop_win_n': 3.0,
'class': AbuFactorAtrNStop},
{'class': AbuFactorCloseAtrNStop, 'close_atr_n': 2.2}]
abu_result_tuple, metrics = run_loo_back(['601318'])
上面只是测试了使用20日/60日均线金叉/死叉策略买卖601318(中国平安)这只股票,看起来好像能赚钱。但是单只不能说明什么问题。 以下从市场随机选择66只股试一下。
import random
from stock_pool import stock_pool
symbols = []
# 中国A股全市科创版除外
symbols =stock_pool.get('cn')
symbols = random.sample(list(symbols), 66)
print(symbols)
from picker.WzPickNonNew import WzPickNonNew
from abupy import slippage
# 开启针对非集合竞价阶段的涨停,滑点买入价格以高概率在接近涨停的价格买入
slippage.sbb.g_enable_limit_up = True
# 将集合竞价阶段的涨停买入成功概率设置为0,如果设置为0.2即20%概率成功买入
slippage.sbb.g_pre_limit_up_rate = 0
# 开启针对非集合竞价阶段的跌停,滑点卖出价格以高概率在接近跌停的价格卖出
slippage.ssb.g_enable_limit_down = True
# 将集合竞价阶段的跌停卖出成功概率设置为0, 如果设置为0.2即20%概率成功卖出
slippage.ssb.g_pre_limit_down_rate = 0
o_pos_base =0.1
print('o_pos_base:', o_pos_base)
abupy.beta.atr.g_atr_pos_base = o_pos_base * 1.0
# 选股因子,不交易24周内ipo新股
pickers = [
{'class': WzPickNonNew,
'pick_period': 'week',
'weeks': 24},
]
buy_factors = [{'class': AbuDoubleMaBuy, 'fast': 20, 'slow': 60, 'stock_pickers': pickers,}]
abu_result_tuple, metrics = run_loo_back(symbols)
如果从2012-12-12传说中的世界末日后开始至2020-01-20疑似世界末日,一直坚持用这个均线金叉/死叉策略交易中国A股股票似乎可以获得年化收益16.2685%的收益。
但是最倒霉的情况会亏掉:
metrics.plot_max_draw_down()
小结: 相比靠信仰,程序员可以靠代码。 尽管上面例子的选股、择时、仓位管理都是使用abupy内置的因子,但作为程序员,自己有什么idea可以编写因子代码,然后用历史数据测试,看看获利效果。
上面策略的收益并不算好,最大回撤0.416925也挺可怕的, 会不会是我们用的参数 'fast': 20, 'slow': 60,
(20/60日均线金叉/死叉)并不是最好的? 非常值得怀疑! 作为程序员,遍历近可能的参数组合运行上面的过程可以简单理解为蒙特卡罗。由于这种方法落后了,这里就不演示了。
以上我们刚刚接触了一点量化交易的皮毛,但是量化交易之门已经开启了。