如何在交易策略中使用多个时间框架
在本教程中,我将介绍一个如何在策略中使用多个时间框架的示例。
这是我最终得到的完整策略:
from jesse.strategies import Strategy
import jesse.indicators as ta
from jesse import utils
class SampleTrendFollowing(Strategy):
def should_long(self) -> bool:
return self.short_ema > self.long_ema
def should_short(self) -> bool:
return self.short_ema
def should_cancel(self) -> bool:
return True
def go_long(self):
entry = self.price
stop = entry - 3*self.atr
qty = utils.risk_to_qty(self.capital, 3, entry, stop)
profit_target = entry + 5*self.atr
self.buy = qty, entry
self.stop_loss = qty, stop
self.take_profit = qty, profit_target
def go_short(self):
entry = self.price
stop = entry + 3 * self.atr
qty = utils.risk_to_qty(self.capital, 3, entry, stop)
profit_target = entry - 5 * self.atr
self.sell = qty, entry
self.stop_loss = qty, stop
self.take_profit = qty, profit_target
@property
def long_ema(self):
return ta.ema(self.candles, 50)
@property
def short_ema(self):
return ta.ema(self.candles, 21)
@property
def atr(self):
return ta.atr(self.candles)
这是自2019年1月1日至2020年5月1日以4h时间范围回测的结果:
在策略中定义多个时间框架
这一次,我将使用多个时间框架,看看我是否可以改善结果。有经验的交易者在他们的手工交易中使用的一个技巧是观察更大时间范围的趋势(或者他们称之为锚定时间范围)。这个简单的技巧通常会增加你的获胜率,以减少买入信号的数量。
您可能会问我如何知道锚定时间范围是哪个时间范围?常用公式是交易时间的4倍或6倍。例如在我的情况下,4h的锚定时间框架为:
6 * 4h = 24h ("1D" in jesse's terms)
Jesse提供了一个实用工具助手来计算这个值,我将使用这个值。
让我们添加一个返回大趋势的新属性方法。我将返回1表示上升趋势,返回-1表示下降趋势:
@property
def anchor_trend(self):
# use self.get_candles() to get the candles for the anchor timeframe
anchor_candles = self.get_candles(
self.exchange, self.symbol, utils.anchor_timeframe(self.timeframe)
)
ema = ta.ema(anchor_candles, 100)
if self.price > ema:
return 1
else:
return -1
如您所见,这次我使用self.get_candles而不是self.candles。我还使用了其他一些内置属性,而不是使用硬编码的字符串:
# instead of
anchor_candles = self.get_candles(
'Bitfinex', 'BTCUSD', utils.anchor_timeframe('4h')
)
# I wrote
anchor_candles = self.get_candles(
self.exchange, self.symbol, utils.anchor_timeframe(self.timeframe)
)
这样当我更改路线以尝试其他交易所,交易品种和时间范围时,无需更改策略代码。
现在我将输入规则更新为包括anchor_trend:
def should_long(self) -> bool:
return self.short_ema > self.long_ema and self.anchor_trend == 1
def should_short(self) -> bool:
return self.short_ema
修改路由
现在我再次执行回测,以查看此更改将如何影响回测结果,但出现此错误:
Uncaught Exception: RouteNotFound: Bellow route is required but missing in your routes:
('Bitfinex', 'BTCUSD', '1D')
错误很明显。如果我在其他时间范围内使用candle,也应该将其添加到我的route.py文件中。我的交易路线必须保持不变,因为我只交易一个仓位,所以我使用的任何其他时间框架都被视为额外的candle。
这是我的routes.py现在的样子:
# trading routes
routes = [
('Bitfinex', 'BTCUSD', '6h', 'SampleTrendFollowing'),
]
# in case your strategy required extra candles, timeframes, ...
extra_candles = [
]
错误告诉我,我的路线中缺少('Bitfinex','BTCUSD','1D');因此将其添加到extra_candles列表中。这就是我的route.py应该变成的样子:
# trading routes
routes = [
('Bitfinex', 'BTCUSD', '6h', 'SampleTrendFollowing'),
]
# in case your strategy required extra candles, timeframes, ...
extra_candles = [
('Bitfinex', 'BTCUSD', '1D'),
]
这次回测顺利进行。结果如下:
在我使用锚定时间框架来检测市场的更大趋势之后,回测结果有一些显着变化:
1. 净利润从31.44%增加到48.42%,这意味着,更多的钱!
2. 总成交交易减少,这意味着我得到的进入信号更少,这是预期的,因为我添加了另一个进入条件到我的进入规则。
3. 夏普比率从0.62增加到0.86。
4. 胜率从47%增加到50%。
前瞻性偏见
当在算法策略中使用多个时间段时,前瞻性偏差是一个严重的问题。简而言之,这意味着使用未来的数据。
你们中的有些人可能对此很熟悉,并且想知道前瞻性偏差是否对我们刚刚观察到的结果提升有帮助。请放心,事实并非如此。Jesse框架照顾了t背后的前瞻性偏差。
结论
利用锚定时间框架确定市场的更大趋势,我们的策略指标有了明显的提高。
当你在策略中使用多个时间段时,你不会得到同样的提升。但在我看来,至少尝试一下是有意义的。
这个想法可以扩展。例如如果您正在交易以太币,则可能要使用比特币的锚定趋势,因为很明显,比特币是加密货币市场的王者,并且对其他代币的价格产生巨大影响。