SPL Quantitative Trading Practice Series: The KNN Trading Strategy
The trading strategy is like this:
1. Set “up or not” as the target (target). If the closing price is higher than that of the previous date, assign 1 as the target value, otherwise assign -1 to it.
2. Add two metrics – highest closing price minus lowest closing price (max_dif) and closing price minus opening price (co_dif).
3. Suppose we need to predict the stock prices in the year 2023. Compute distance between the two metrics (max_dif and co_dif) on the current date and those on each of the previous 660 trading dates, find the 95 dates with the shortest distances, make the mode of the 95 dates’ target values the result (predict) of predicting the up and down in the next trading date’s price, and record 1 if the price is up and -1 if the price is down.
4. When predict=1 and no position is held, place an order to buy; and when predict=-1 and positions are held, place an order to sell. Generate the buy/sell signal (flag) according to prediction result – make purchases when flag=1, perform selling when flag=-1, and take no action when flag=0.
SPL code:
A | |
---|---|
1 | =file(“daily/300750.csv”).import@tc() |
2 | =A1.select(trade_date>20200101&&trade_date<=20231231) |
3 | =A2.derive(if(#>1, close/ pre_close *factor[-1], close/pre_close):factor) |
4 | =hfq_fst=A3(1),A3.derive((fcls=factor/hfq_fst.factor*hfq_fst.close,c=fcls/close,round(c*open,2)): hfq_open,round(c*high,2): hfq_high,round(c*low,2): hfq_low,round(fcls,2): hfq_close) |
5 | =A4.derive(round(hfq_high-hfq_open,2):max_dif,round(hfq_close-hfq_open,2):co_dif,if(!hfq_close[1],,if(hfq_close[1]>hfq_close,1,-1)):target) |
6 | =n=95 |
7 | =ps=0 |
8 | =A5.derive(if(trade_date<20230101,null,(train=~[-660,-1].([max_dif,co_dif]),rtarget=~[-660:-1].(target),v=[max_dif,co_dif],rtarget(train.ptop(n,dis(~,v))).mode())):predict,if(ps==0&&predict==1,(ps=1,1),if(ps!=0&&predict==-1,(ps=0,-1),0)):flag,if(flag!=0,100,0):shares) |
9 | =A8.select(predict) |
A4: Backward adjust the stock price. The result includes “open”, “high”, “low” and “close” values.
A5: Compute the two metrics and “target” variable values.
A8: Get prediction results (predict) for the year 2023, determine the buy/sell signal (flag) according to the prediction result and whether positions are held or not, and buy 100 shares in each purchase.
A9: Get records where predict values are not null.
SPL does not offer a ready-for-use KNN algorithm, but it is simple to implement one. We just need one statement rtarget(train.ptop(n,dis(~,v)).mode() to get it done. While we need to manually code such a simple algorithm like KNN, SPL is flexible enough to let users set up parameters and optimize the code according to the specific needs. Though Python has a ready-to-use third-party library, setting up parameters is complicated and it is almost impossible to optimize the code. As a result, it is inevitable to write the code manually.
Plot a buy/sell chart according to A9’s data:
In the above chart, red dots represent buy points and green squares are sell points.
Same as what is explained in SPL Quantitative Trading Practice Series: Turtle Trading Strategy, compute the flag and then we can do the backtesting. Just get records where flag values are not 0 from A9’s result set and call the backtesting interface.
Below is the chart displaying backtested RoRs:
The following table lists backtested indicators:
Indicators | Value |
---|---|
Cumulative rate of return | 5.54% |
Annualized rate of return | 5.77% |
Annual volatility | 15.59% |
Sharpe ratio | 0.18 |
Maximum drawdown | 14.63% |
Cash invested | 40425.29 |
Total assets | 42664.29 |
Stock holding ratio | 0.0% |
Profits count | 18 |
Losses count | 18 |
It should be noted that the annualized return is calculated based on 252 trading days per year. In practice, a specific year may have slightly fewer or more trading days. Additionally, since the first purchase in this example was made on January 20, 2023, the annualized return differs from the cumulative return.
SPL Official Website 👉 https://www.esproc.com
SPL Feedback and Help 👉 https://www.reddit.com/r/esProcSPL
SPL Learning Material 👉 https://c.esproc.com
SPL Source Code and Package 👉 https://github.com/SPLWare/esProc
Discord 👉 https://discord.gg/2bkGwqTj
Youtube 👉 https://www.youtube.com/@esProc_SPL
Chinese version