作者: 阿布 阿布量化版權所有 未經允許 禁止轉載 "abu量化系統github地址(歡迎+star,你的支持是我更新的動力!)" "本節ipython notebook" 上一節使用AbuFactorBuyBreak和AbuFactorSellBreak且混入基本止盈止損策略AbuFactorAt ...
作者: 阿布
阿布量化版權所有 未經允許 禁止轉載
abu量化系統github地址(歡迎+star,你的支持是我更新的動力!)
上一節使用AbuFactorBuyBreak和AbuFactorSellBreak且混入基本止盈止損策略AbuFactorAtrNStop,
風險控制止損策略AbuFactorPreAtrNStop,利潤保護止盈策略AbuFactorCloseAtrNStop來提高交易的盈利效果。
本節將繼續在上一節回測的基礎上示例擇時策略其它使用方法,首先完成上一節的回測準備,如下所示:
from abupy import AbuFactorBuyBreak, AbuFactorSellBreak
from abupy import AbuFactorAtrNStop, AbuFactorPreAtrNStop, AbuFactorCloseAtrNStop
from abupy import ABuPickTimeExecute, AbuBenchmark, AbuCapital
# buy_factors 60日向上突破,42日向上突破兩個因數
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
{'xd': 42, 'class': AbuFactorBuyBreak}]
# 四個賣出因數同時並行生效
sell_factors = [
{
'xd': 120,
'class': AbuFactorSellBreak
},
{
'stop_loss_n': 0.5,
'stop_win_n': 3.0,
'class': AbuFactorAtrNStop
},
{
'class': AbuFactorPreAtrNStop,
'pre_atr_n': 1.0
},
{
'class': AbuFactorCloseAtrNStop,
'close_atr_n': 1.5
}]
benchmark = AbuBenchmark()
capital = AbuCapital(1000000, benchmark)
1 滑點買入賣出價格確定及策略實現
第一節中實現的買入策略和賣出策略的編寫,買入策略中確定買入只是通過make_buy_order函數,確定買單生成,賣出策略確定賣出訂單
也只是通過fit_sell_order來提交賣單,那麼執行訂單,應該使用的什麼價格買入或者賣出呢,abupy在預設的策略都是使用當天的均價買入賣出,
當然你可以實現多種複雜的當日交易策略,設置限價單、市價單,獲取當日的分時數據再次進行策略分析執行操作,但是如果你的回測數量足夠多的情況下,比如全市場回測,按照大數定理,這個均值執行其實是最好的模擬,而且簡單、運行速度快。
滑點買入賣出價格確定具體實現代碼請閱讀AbuSlippageBuyMean和AbuSlippageSellMean,它們的實現都很簡單
在買入滑點AbuSlippageBuyMean中有一個小策略噹噹天開盤價格直接下探7%時,放棄買單,看上一節回測結果中如下圖這次交易,從圖上就可以發現雖然是突破買入,但明顯第二天執行買單時的價格是直線下跌的,且下跌不少,但還是成交了這筆交易。因為開盤下跌幅度沒有達到7%的閥值,下麵我們就過擬合這次交易避免買入,只為示例
下麵編寫一個獨立的Slippage策略,只簡單修改g_open_down_rate的值為0.02
from abupy import AbuSlippageBuyBase, slippage
# 修改買入下跌閥值為0.02
g_open_down_rate = 0.02
class AbuSlippageBuyMean2(AbuSlippageBuyBase):
"""示例日內滑點均價買入類"""
@slippage.sbb.slippage_limit_up
def fit_price(self):
"""
取當天交易日的最高最低均價做為決策價格
:return: 最終決策的當前交易買入價格
"""
# TODO 基類提取作為裝飾器函數,子類根據需要選擇是否裝飾,並且添加上根據order的call,put明確細節邏輯
if self.kl_pd_buy.pre_close == 0 or (self.kl_pd_buy.open / self.kl_pd_buy.pre_close) < (1 - g_open_down_rate):
# 開盤就下跌一定比例閥值,放棄單子
return np.inf
# 買入價格為當天均價,即最高,最低的平均,也可使用高開低收平均等方式計算
self.buy_price = np.mean([self.kl_pd_buy['high'], self.kl_pd_buy['low']])
# 返回最終的決策價格
return self.buy_price
上面編寫的AbuSlippageBuyMean2類實現即為滑點買入類的實現:
- 滑點買入類需要繼承自AbuSlippageBuyBase
- 滑點買入類需要實現fit_price來確定交易單執行當日的最終買入價格
- slippage_limit_up裝飾器是針對a股漲停板買入價格決策的裝飾器,處理買入成功概率,根據概率決定是否能買入,及漲停下的買入價格決策,漲停下買入價格模型為,越靠近漲停價格買入成交概率越大,即在漲停下預期以靠近漲停價格買入,
備註:slippage_limit_up及slippage_limit_down具體實現可閱讀源代碼,後面的章節有示例演示使用
但是滑點類時什麼時候被實例化使用的呢,怎麼使用我們自己寫的這個滑點類呢?首先看買入因數基類AbuFactorBuyBase,在每個買入因數初始化的時候即把預設的滑點類以及倉位管理類(稍後講解)賦值,如下片段代碼所示:
詳情請查看AbuFactorBuyBas源代碼
class AbuFactorBuyBase(six.with_metaclass(ABCMeta, ABuParamBaseClass)):
def __init__(self, capital, kl_pd, **kwargs):
# 走勢數據
self.kl_pd = kl_pd
# 資金情況數據
self.capital = capital
# 滑點類,預設AbuSlippageBuyMean
self.slippage_class = kwargs['slippage'] \
if 'slippage' in kwargs else AbuSlippageBuyMean
# 倉位管理,預設AbuAtrPosition
self.position_class = kwargs['position'] \
if 'position' in kwargs else AbuAtrPosition
if 'win_rate' in kwargs:
self.win_rate = kwargs['win_rate']
if 'gains_mean' in kwargs:
self.gains_mean = kwargs['gains_mean']
if 'losses_mean' in kwargs:
self.losses_mean = kwargs['losses_mean']
self._init_self(**kwargs)
之後因數在每次生效產生買單的時候會觸發AbuOrder實例對象的fit_buy_order()函數,fit_buy_order()中將滑點類,倉位管理類實例化後,執行買入價格及數量確定,代碼片段如下所示,詳情請查看源代碼。
def fit_buy_order(self, day_ind, factor_object):
kl_pd = factor_object.kl_pd
# 要執行買入當天的數據
kl_pd_buy = kl_pd.iloc[day_ind + 1]
# 買入因數名稱
factor_name = factor_object.factor_name \
if hasattr(factor_object, 'factor_name') else 'unknown'
# 滑點類設置
slippage_class = factor_object.slippage_class
# 倉位管理類設置
position_class = factor_object.position_class
# 初始資金,也可修改策略使用剩餘資金
read_cash = factor_object.capital.read_cash
# 實例化滑點類
fact = slippage_class(kl_pd_buy, factor_name)
# 執行fit_price(), 計算出買入價格
bp = fact.fit_price()
# 如果滑點類中決定不買入,撤單子,bp就返回正無窮
if bp < np.inf:
# 實例化倉位管理類
position = position_class(kl_pd_buy, factor_name, bp,
read_cash)
# 執行fit_position(),通過倉位管理計算買入的數量
buy_stock_cnt = int(position.fit_position(factor_object))
if buy_stock_cnt < 1:
return
賣出因數的滑點操作及倉位管理與買入類似,讀者可以自行閱讀源代碼。
由以上代碼我們可以發現通過buy_factors的字典對象中傳入slippage便可以自行設置滑點類,由於上圖顯示的交易是60日突破產生的買單,所以我們只修改60日突破的字典對象,執行後可以看到如下圖所示,過濾了兩個60日突破的買單,即過濾了上圖所示的交易,代碼如下所示:
備註:實際上如果只是修改g_open_down_rate的值,可以通過模塊全局變數直接修改,本節只為示例使用流程
# 針對60使用AbuSlippageBuyMean2
buy_factors2 = [{'slippage': AbuSlippageBuyMean2, 'xd': 60,
'class': AbuFactorBuyBreak},
{'xd': 42, 'class': AbuFactorBuyBreak}]
capital = AbuCapital(1000000, benchmark)
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
benchmark,
buy_factors2,
sell_factors,
capital,
show=True)
2. 交易手續費的計算以及自定義手續費
交易必然會產生手續費,手續費的計算在ABuCommission模塊中,比如本例中使用的的美股交易回測,使用的手續費計算代碼如下所示:
def calc_commission_us(trade_cnt, price):
"""
美股計算交易費用:每股0.01,最低消費2.99
:param trade_cnt: 交易的股數(int)
:param price: 每股的價格(美元)(暫不使用,只是保持介面統一)
:return: 計算結果手續費
"""
# 每股手續費0.01
commission = trade_cnt * 0.01
if commission < 2.99:
# 最低消費2.99
commission = 2.99
return commission
針對不同市場美股,a股,港股,比特幣,期貨有不同計算手續費的方法,更多詳情請閱讀ABuCommission模塊源代碼
下麵先看看之前的回測交易中產生的手續費情況,查看代碼如下所示:
capital.commission.commission_df
如果你想把自己的計算手續費的方法使用在回測中,只需要編寫手續費函數,示例如下所示:
def calc_commission_us2(trade_cnt, price):
"""
手續費統一7美元
"""
return 7
如上編寫的手續費函數統一每次買入賣出都是7美元手續費,手續費函數有兩個參數一個trade_cnt代表買入(賣出)股數,
另一個參數是price,代表買入(賣出)價格,下麵使用這個自定義的手續費方法做回測,代碼如下所示:
# 構造一個字典key='buy_commission_func', value=自定義的手續費方法函數
commission_dict = {'buy_commission_func': calc_commission_us2}
# 將commission_dict做為參數傳入AbuCapital
capital = AbuCapital(1000000, benchmark, user_commission_dict=commission_dict)
# 除了手續費自定義外,回測其它設置不變,show=False不可視化回測交易
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
benchmark,
buy_factors2,
sell_factors,
capital,
show=False)
# 回測完成後查看手續費情況
capital.commission.commission_df
從上面回測交易手續費結果可以看到,買入的手續費都變成了7元,賣出手續費還是之前的演算法,下麵的回測將買入賣出手續費計算方法都變成使用自定義的方法,代碼如下所示:
# 賣出字典key='sell_commission_func', 指向同一個手續費方法,當然也可以定義不同的方法
commission_dict = {'buy_commission_func': calc_commission_us2, 'sell_commission_func': calc_commission_us2}
# 將commission_dict做為參數傳入AbuCapital
capital = AbuCapital(1000000, benchmark, user_commission_dict=commission_dict)
# 除了手續費自定義外,回測其它設置不變,show=False不可視化回測交易
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
benchmark,
buy_factors2,
sell_factors,
capital,
show=False)
# 回測完成後查看手續費情況
capital.commission.commission_df
從回測結果即可以看到所有買入賣出的手續費都是7美元
abu量化文檔目錄章節
- 擇時策略的開發
- 擇時策略的優化
- 滑點策略與交易手續費
- 多支股票擇時回測與倉位管理
- 選股策略的開發
- 回測結果的度量
- 尋找策略最優參數和評分
- A股市場的回測
- 港股市場的回測
- 比特幣,萊特幣的回測
- 期貨市場的回測
- 機器學習與比特幣示例
- 量化技術分析應用
- 量化相關性分析應用
- 量化交易和搜索引擎
- UMP主裁交易決策
- UMP邊裁交易決策
- 自定義裁判決策交易
- 數據源
- A股全市場回測
- A股UMP決策
- 美股全市場回測
- 美股UMP決策
abu量化系統文檔教程持續更新中,請關註公眾號中的更新提醒。
更多關於量化交易相關請閱讀《量化交易之路》
更多關於量化交易與機器學習相關請閱讀《機器學習之路》
更多關於abu量化系統請關註微信公眾號: abu_quant