教程
止损止盈信号
测试止损、移动止损和止盈配置
会员内容预览(英文)
Our goal is to use large-scale backtesting to compare the performance of trading with and without stop loss (SL), trailing stop (TS), and take profit (TP) signals. To ensure this analysis is comprehensive, we will conduct a large number of experiments across three dimensions: instruments, time, and parameters.
First, we will select 10 cryptocurrencies by market capitalization (excluding stablecoins such as USDT) and gather 3 years of their daily pricing data. Specifically, we will backtest the period from 2018 to 2021, as this range includes periods of sharp price declines (such as corrections after the all-time high in December 2017 and during the coronavirus crisis in March 2020) as well as surges (the all-time high in December 2020). This provides a balanced perspective. For each instrument, we will split this period into 400 smaller, overlapping time windows, each lasting 6 months. We will run our tests on each of these windows to account for different market conditions. For each instrument and time window, we will generate an entry signal at the very first bar and determine an exit signal according to the stop configuration. We will test 100 stop values, increasing by 1% increments, and compare the performance of each one to trading randomly and holding during that specific time window. In total, we will conduct 2,000,000 tests.
Make sure you have at least 16 GB of free RAM available, or memory swapping enabled.
Parameters
The first step is to define the parameters of the analysis pipeline. As discussed above, we will backtest 3 years of pricing data, use 400 time windows, 10 cryptocurrencies, and 100 stop values. We will also set fees and slippage to 0.25% each, and the initial capital to $100. The absolute amount does not matter, but it must be consistent across all assets to allow for direct comparison. Feel free to change any parameter of interest.
from vectorbtpro import *
import ipywidgets
seed = 42
symbols = [
"BTC-USD", "ETH-USD", "XRP-USD", "BCH-USD", "LTC-USD",
"BNB-USD", "EOS-USD", "XLM-USD", "XMR-USD", "ADA-USD"
]
start_date = vbt.utc_timestamp("2018-01-01")
end_date = vbt.utc_timestamp("2021-01-01")
time_delta = end_date - start_date
window_len = vbt.timedelta("180d")
window_cnt = 400
exit_types = ["SL", "TS", "TP", "Random", "Holding"]
step = 0.01
stops = np.arange(step, 1 + step, step)
vbt.settings.wrapping["freq"] = "d"
vbt.settings.plotting["layout"]["template"] = "vbt_dark"
vbt.settings.portfolio["init_cash"] = 100.
vbt.settings.portfolio["fees"] = 0.0025
vbt.settings.portfolio["slippage"] = 0.0025
pd.Series({
"Start date": start_date,
"End date": end_date,
"Time period (days)": time_delta.days,
"Assets": len(symbols),
"Window length": window_len,
"Windows": window_cnt,
"Exit types": len(exit_types),
"Stop values": len(stops),
"Tests per asset": window_cnt * len(stops) * len(exit_types),
"Tests per window": len(symbols) * len(stops) * len(exit_types),
"Tests per exit type": len(symbols) * window_cnt * len(stops),
"Tests per stop type and value": len(symbols) * window_cnt,
"Tests total": len(symbols) * window_cnt * len(stops) * len(exit_types)
})Start date 2018-01-01 00:00:00+00:00
End date 2021-01-01 00:00:00+00:00
Time period (days) 1096
Assets 10
Window length 180 days 00:00:00
Windows 400
Exit types 5
Stop values 100
Tests per asset 200000
Tests per window 5000
Tests per exit type 400000
Tests per stop type and value 4000
Tests total 2000000
dtype: objectOur configuration produces sample sizes with enough statistical power to analyze four variables: assets (200k tests per asset), time (5k tests per time window), exit types (400k tests per exit type), and stop values (4k tests per stop type and value). Similar to Tableau's approach to dimensions and measures, we can group our performance metrics by each of these variables. However, we will mainly focus on 5 exit types: SL exits, TS exits, TP exits, random exits, and holding exits (executed at the last bar).
cols = ["Open", "Low", "High", "Close", "Volume"]
yfdata = vbt.YFData.pull(symbols, start=start_date, end=end_date)yfdata.data.keys()dict_keys(['BTC-USD', 'ETH-USD', 'XRP-USD', 'BCH-USD', 'LTC-USD',
'BNB-USD', 'EOS-USD', 'XLM-USD', 'XMR-USD', 'ADA-USD'])yfdata.data["BTC-USD"].shape(1096, 7)The data instance yfdata contains a dictionary of OHLCV data, keyed by cryptocurrency name. Each
DataFrame contains 1096 rows (days) and 5 columns (O, H, L, C, and V). You can plot each DataFrame
as follows:
yfdata.plot(symbol="BTC-USD").show() Since assets are one of the dimensions we want to analyze, VBT expects us to combine them as columns into a single DataFrame and label them clearly. To do this, we swap assets and features to create a dictionary of DataFrames, now with assets as columns and keyed by feature name, such as "Open".
ohlcv = yfdata.concat()
ohlcv.keys()dict_keys(['Open', 'High', 'Low', 'Close',
'Volume', 'Dividends', 'Stock Splits'])ohlcv['Open'].shape(1096, 10)Time windows
止损止盈类订单是投资者工具箱中的重要组成部分,有助于限制持仓亏损并锁定利润。但在特定市场状态下,订单类型和参数值怎样组合才是最优的?
✅ 学习如何在短短几分钟内运行 200 万次测试,为主流加密货币市场回答这个问题。与开源文章不同,我们还将把止损止盈的触发价格纳入分析,以提高准确性!
版权所有 © 2021–2026 Oleg Polakow。保留所有权利。
本站内容与文档供使用和评估 VectorBT PRO 以及教育用途。任何其他用途,包括开发或支持竞争产品或服务,均须事先取得书面同意。