Preface
Four articles have been written in the " WonderTrader Architecture Detailed Explanation" series. For a lazy person like the author, it is really a big project. This is not the first time being introduced architecture, the article will introduce you about how WonderTrader written on a arbitrage strategies across species , aims to show you what WonderTrader general pattern of the underlying strategy of multi, also introduced I look at wtpy latest version v0.6.3
in the latest release of performance analysis module .
List of WonderTrader architecture articles:
- WonderTrader architecture detailed one-the overall architecture
- WonderTrader structure detailed explanation 2-from the data
- WonderTrader structure detailed explanation third-signal and execution
- WonderTrader structure detailed explanation IV-Talking about the platform's support for strategy
Introduction to arbitrage strategy
I believe that everyone who does quantification has studied arbitrage strategies. Arbitrage strategy is favored by most people because of its relatively simple logic and relatively stable returns. At the same time, the arbitrage strategy and the trend strategy are highly complementary, which means that if they are properly coordinated, they can greatly promote the smoothing of the yield curve, reduce the fluctuation of performance, and improve the Sharpe.
There are many classifications of arbitrage strategies. The author once quoted Dr. Ding Peng's " Quantitative Investment-Strategies and Technology " in the WonderTrader Architecture Detailed 4-Talking about Platform Support There are many kinds of arbitrage models mentioned in the classification of arbitrage, such as: cash-in-period, inter-period, cross-variety, pair trading, etc.
In order to develop this strategy, the author saw a point of view when looking up the information, and was deeply : 1609b51ae27a20 No matter how complicated the classification of arbitrage strategies, the essence of arbitrage strategy is to find trading opportunities fluctuation of the spread between different contracts.
Arbitrage strategy implementation
Strategy design
In view of the fact that the author’s skill tree for quantitative strategies has not been illuminated yet, the strategy examples in this article are learned from the Internet. The author would like to sincerely thank the sharers of this strategy. The basic design of the strategy is as follows:
- The contract pair chooses the main continuous contract of rebar
SHFE.rb.HOT
and the main continuous contract of iron oreDCE.i.HOT
- The back-test data is the main continuous data, which has been re-weighted to prevent the spread change caused when the main contract is not synchronized.
- Based . 1 minute data , past
N
minutes closing price two sequences linear regression to obtain a coefficientbeta
, a constantc
and a residual sequence - ADF test on the residual sequence. If the residual sequence is a stationary sequence, enter the signal calculation logic
- Calculate the new residual based on the obtained coefficient
beta
and constantc
, and the latest price - When the new residuals exceed a threshold , admission signal is triggered when then spread back to within the threshold is triggered exit signals
Strategy implementation
Parameter design
According to the above introduction, the core parameters of the strategy are as follows:code1
: Arbitrage contract 1, set toSHFE.rb.HOT
code2
: Arbitrage contract 2, set toDCE.i.HOT
period
: data period, set tom1
this example, that is, one minute linethreshold
: threshold, set to0.9
N
: The number of K lines counted. In this example360
, which is the one-minute line of a trading daybar_cnt
: The number of K lines read by the strategy, which is greater thanN
, and the main consideration is to reserve space for scrolling calculations
def __init__(self, name:str, code1:str, code2:str, bar_cnt:int, period:str, N:int, threshold:float=1): BaseCtaStrategy.__init__(self, name) self.__n__ = N self.__threshold__ = threshold self.__period__ = period self.__bar_cnt__ = bar_cnt self.__code_1__ = code1 self.__code_2__ = code2
Cointegration test
The core logic of the strategy lies in the co-integration test and . Only when the co-integration test passes can the signal trigger.# 协整检验函数 def cointegration_check(series01, series02): # 对两个序列分别进行ADF检验 urt_1 = ts.adfuller(np.array(series01), 1)[1] urt_2 = ts.adfuller(np.array(series02), 1)[1] # 同时平稳或不平稳则差分再次检验 if (urt_1 > 0.1 and urt_2 > 0.1) or (urt_1 < 0.1 and urt_2 < 0.1): urt_diff_1 = ts.adfuller(np.diff(np.array(series01)), 1)[1] urt_diff_2 = ts.adfuller(np.diff(np.array(series02), 1))[1] # 同时差分平稳进行OLS回归的残差平稳检验 if urt_diff_1 < 0.1 and urt_diff_2 < 0.1: matrix = np.vstack([series02, np.ones(len(series02))]).T beta, c = np.linalg.lstsq(matrix, series01, rcond=None)[0] resid = series01 - beta * series02 - c # 最后对残差序列再进行ADF检验 if ts.adfuller(np.array(resid), 1)[1] > 0.1: result = False else: result = True return beta, c, resid, result else: result = False return 0.0, 0.0, 0.0, result else: result = False return 0.0, 0.0, 0.0, result
Signal
When the residual exceeds the upper boundary, it means that the residual is positively expanded . According to the characteristics of the residual mean regression, then is required to short the spread ; on the contrary, when the residual exceeds the lower boundary, it means that the residual is reversed expansion , then we need do more spread ; when to participate in the upper and lower boundaries of the range, then cleared away the existing position, waiting for the next opportunity.# 计算新残差 resid_new = close_ay1[-1] - self.beta * close_ay2[-1] - self.c if resid_new > self.up and curPos1 != 1: context.stra_log_text("[%d.%04d]残差正向扩大,做空价差" % (curDate, curTime)) context.stra_enter_short(self.__code_1__, 1, 'OpenSA') context.stra_enter_long(self.__code_2__, 1, 'OpenLB') elif resid_new < self.down and curPos1 != -1: context.stra_log_text("[%d.%04d]残差反向扩大,做多价差" % (curDate, curTime)) context.stra_enter_long(self.__code_1__, 1, 'OpenLA') context.stra_enter_short(self.__code_2__, 1, 'OpenSB') elif curPos1 != 0 and self.down <= resid_new and resid_new <= self.up: context.stra_log_text("[%d.%04d]残差回归,清掉头寸" % (curDate, curTime)) context.stra_set_position(self.__code_1__, 0, 'CutA') context.stra_set_position(self.__code_2__, 0, 'CutB')
Strategy backtest
Performance Analysis
In this example, wtpy in the v0.6.3
version is used for analysis. The calling method is basically the same as the old version, but the analysis entry has changed.
analyst = WtBtAnalyst()
analyst.add_strategy("t1_rb_i", folder="./outputs_bt/t1_rb_i/", init_capital=350000, rf=0.02, annual_trading_days=240)
# 绩效分析的入口,老版本run的仍然可用
analyst.run_new()
Performance analysis screenshot
Summary of Strategic Performance
Detailed transaction list
Overall transaction analysis
Continuous transaction analysis
Income distribution
Daily performance analysis
Other cycle performance
Daily performance overview
As can be seen from the foregoing, the new version of the performance analysis module provides more dimensional analysis functions . The new version of the performance analysis module mainly refers to MultiCharts
, so the comprehensiveness and practicability of the analysis results should be guaranteed.
Going back to the strategy itself, it can be seen from the previous performance report that the strategy is obviously not very successful. How to optimize this strategy? The author considers whether it can be adding stop-profit and stop-loss logic , or by adjusting the threshold . However, these are beyond the purpose of this article. If you are interested, you can research on your own.
Strategy acquisition
The example strategy in this article has been shared under /demos/cta_arbitrage_bt in the wtpy project on github, and interested friends can download it by themselves. click here to jump
Concluding remarks
This concludes the introduction of using WonderTrader write arbitrage strategies. The author feels uneasy while writing an article today. Although the author has been working with everyone in an excellent quantitative team, because the author is engaged in technical work, the understanding of the strategy is still on the surface after all, so I am afraid that the strategy shared today has made a low-level error. Fortunately, the author finally decided to find a ready-made strategy from the Internet, which slightly alleviated the author's anxiety. Even so, this article and the strategies demonstrated in this article will inevitably have errors and omissions, and I hope that all viewers can include their corrections. Fortunately, the ultimate goal of this article is to cause everyone to find more "beautiful jade" through the "bricks" thrown by the author today. If it can be of benefit to everyone, it would be great.
Finally, Amway WonderTrader
WonderTrader aims to provide better wheels for all quantitative practitioners, encapsulate technology-related things in the platform, create a more efficient underlying framework, and strive to bring better strategy development and trading experience to strategy research and development.
WonderTrader of github
address: https://github.com/wondertrader/wondertrader
WonderTrader official website address: https://wondertrader.github.io
wtpy of github
address: https://github.com/wondertrader/wtpy
market is risky and investment needs to be cautious. The above statement only serves as a review of historical events, does not represent an opinion on the future, and does not serve as any investment advice.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。