LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 币圈百科 > 如何使用algotrade编写比特币的高级趋势跟踪策略

如何使用algotrade编写比特币的高级趋势跟踪策略

2020-06-17 陀螺财经 来源:火星财经

在开始文章阅读时,有些交易名词需要先了解一下:

头寸:指的是银行当前所有可以运用的资金的总和。

candle:与条形图一样,该图表显示高低价以及开盘价和收盘价,蜡烛的形状反映了这些价格之间的关系。

RSI:其可识别走势将要达到当前方向尽头的时间以及超卖和超买市场条件。

既要开始使用算法交易又要获利,趋势跟踪通常是最容易的。在上一篇文章中,我写了一个趋势跟踪策略,甚至通过使用更长的时间框架来确定趋势来提高其性能。但这是一次简单的一次进入和一次退出的策略。

本教程的重点是让您开始使用Jesse的一些功能,这些功能有助于您编写大多数趋势跟踪策略。这些功能中很少有:

1. 在两个点退出交易,一个是固定价格,另一个是动态价格。

2. 将停止损失更新为退出一半位置后盈亏平衡。

3. 过滤盈亏比不好的交易。

4. 使用事件挂钩交易的生命周期。

首先我使用make strategy命令创建一个新策略:

jessemake-strategyTrendFollowingStrategy

然后我编辑routes.py文件以使用此策略,并将时间范围设置为4h:

#tradingroutesroutes=[('Bitfinex','BTCUSD','4h','TrendFollowingStrategy'),]#incaseyourstrategyrequiredextracandles,timeframes,...extra_candles=[]

然后打开新创建的策略文件,如下所示:

fromjesse.strategiesimportStrategyimportjesse.indicatorsastafromjesseimportutilsclassTrendFollowingStrategy(Strategy):defshould_long(self)->bool:returnFalsedefshould_short(self)->bool:returnFalsedefshould_cancel(self)->bool:returnFalsedefgo_long(self):passdefgo_short(self):pass

进入规则

我想在以下情况走多长时间:

1. 我们处于上升趋势(空头交易反之亦然)

2. 收盘价(当前价)触及50 EMA线

defshould_long(self)->bool:returnself.current_candle_touches_long_emaandself.trend==1defshould_short(self)->bool:returnself.current_candle_touches_long_emaandself.trend==-1

他们说一张图片值1000个字说明,所以这里有一张图片显示了在这种情况下我认为是上升趋势:

这是我所说的,当前candle碰到50 EMA(橙色线是50 EMA):

现在让我们为current_candle_touch_long_ema和trend编写代码:

@propertydeftrend(self):short_ema=ta.ema(self.candles,50)long_ema=ta.ema(self.candles,100)longer_ema=ta.ema(self.candles,200)ifshort_ema>long_ema>longer_ema:return1elifshort_ema<long_ema<longer_ema:return-1else:return0@propertydefcurrent_candle_touches_long_ema(self):long_ema=ta.ema(self.candles,50)returnself.high>=long_ema>=self.low

我使用了3条EMA线来确定趋势方向。我返回1代表上升趋势,返回-1代表下降趋势。current_candle_touches_long_ema非常简单,我只需要确保当前candle的高价大于long_ema线(周期为50的EMA),并且当前candle的低价低于long_ema线。

设定入场价格和头寸规模

进入价格将是目前长期交易的最高点。止损价格将是当前ATR的3倍,而不是我的进场价格。

在这种策略中,我想一次全部进入交易,但要在两个点退出。我将在趋势的前一个高点退出头寸。这就是我所说的上升趋势的最高点(蓝线是我的目标):

要对此进行编码,我首先选择最近20条candle的高价。然后简单地返回它们的最大值。

对于头寸规模,我希望每次交易的风险为总资本的5%。要计算qty,我使用risk_to_qty实用程序。

当然,做空交易则相反。这是代码:

defgo_long(self):entry=self.highstop=entry-ta.atr(self.candles)*3qty=utils.risk_to_qty(self.capital,5,entry,stop)#highestpriceofthelast20barslast_20_highs=self.candles[-20:,3]previous_high=np.max(last_20_highs)self.buy=qty,entryself.stop_loss=qty,stopself.take_profit=qty/2,previous_highdefgo_short(self):entry=self.lowstop=entry+ta.atr(self.candles)*3qty=utils.risk_to_qty(self.capital,5,entry,stop)#lowestpriceofthelast20barslast_20_lows=self.candles[-20:,4]previous_low=np.min(last_20_lows)self.sell=qty,entryself.stop_loss=qty,stopself.take_profit=qty/2,previous_low

使止损达到收支平衡

如您所见,我仅以获利价格退出一半的头寸规模。换句话说,在降低头寸之后,我想将止损价调整为收支平衡。要在Jesse中为其编写代码,我将使用内置的on_reduced_position方法。

我只需要更新self.stop_loss即可告诉jesse更新我的止损订单。Jesse会自动选择它,取消上一个停止订单,然后提交新的停止订单。再简单不过了!

defon_reduced_position(self):self.stop_loss=self.position.qty,self.position.entry_price

动态退出交易的后半部分

对于这种策略,我打算在动态情况下退出交易我的剩余的头寸。这种情况背后的想法是,在价格高度超买并即将进行严重调整时退出。用quant的语言来说,我想在RSI指标达到80以上时退出。

首先我将使用内置的update_position()方法写入我的逻辑。只有在我们有未平仓合约时,此方法才会在每次添加新candle后执行。因此它用于更新位置。这意味着我们不需要检查仓位是否打开。

在此要考虑的下一件事情是,我只想退出头寸的剩余半部分。换句话说,如果未结头寸已减少,我想将其平仓。检查我的位置是否已降低的最简单方法是使用内置的is_reduced属性和liquidate()方法。

defupdate_position(self):#theRSIlogicisintendedforthesecondhalfofthetradeifself.is_reduced:rsi=ta.rsi(self.candles)ifself.is_longandrsi>80:#self.liquidate()closesthepositionwithamarketorderself.liquidate()elifself.is_shortandrsi<20:self.liquidate()

使用过滤器(filter)

到目前为止,我的策略看起来不错,让我们进行一次回溯测试,看看其进展如何:

jessebacktest2019-01-012020-05-01

经过约4%的回测后,我得到一个错误:

UncaughtException:InvalidStrategy:take-profit(3601.6)mustbebelowentry-price(3601.6)inashortposition

这个错误试图告诉我们,在某种程度上,我们策略的止盈和入场价相等($ 3601.6),这是不可接受的。这是一个棘手的调试问题,但是您在编写了最初的几条策略后就会熟练使用Jesse进行调试。

defgo_long(self):#entry:thehighofthecurrentcandleentry=self.highstop=entry-ta.atr(self.candles)*3qty=utils.risk_to_qty(self.capital,5,entry,stop)last_20_highs=self.candles[-20:,3]previous_high=np.max(last_20_highs)self.buy=qty,entryself.stop_loss=qty,stop#(first)take-profit:thehighofthelast20candlesself.take_profit=qty/2,previous_high

这个错误告诉我们,在某些情况下,入场和获利在某些时候是相同的。也就是说,在那一点上,当前蜡烛的高位是最近20个candle中的最高点。我们考虑的不是这种策略的交易类型。

我们可以通过在should_long方法中使用一些肮脏的if-else语句或使用针对此类情况设计的过滤器(filter)来防止这种情况的发生。

过滤器(filter)只是一个返回布尔值的函数。通过返回True值来传递过滤器(filter),反之亦然。我定义一个过滤器并将其命名为reward_to_risk_filter。名称可以是任何东西,但是通常最好的做法是使用单词filter来开始或结束过滤方法的名称。该筛选器(filter)的工作是确保我们尝试输入的交易值得。

defreward_to_risk_filter(self):profit=abs(self.average_entry_price-self.average_take_profit)loss=abs(self.average_entry_price-self.average_stop_loss)win_loss_ratio=profit/lossreturnwin_loss_ratio>1

目前Jesse仍然不知道reward_to_risk_filter()是一个过滤器(filter)。为了使其能够识别我的过滤器(filter),我需要将其添加到filters()方法中,该方法是一个返回Python列表的内置方法:

deffilters(self):return[]

现在,我将在返回列表中添加reward_to_risk_filter作为变量。这意味着它的结尾不能有括号:

deffilters(self):return[self.reward_to_risk_filter,]

现在让我们再执行一次回测:

jessebacktest2019-01-012020-05-01

这次一切进展顺利。

结 论

保持策略越简单,随着时间的推移调试策略甚至改进策略就越容易。

使用Jesse编写策略就像手动交易策略一样简单。因此下次您找到交易手册或交易专家介绍的策略时,只需为其编写代码,然后对其进行回测。

------------------------------------------------------------------------------

原文作者:Saleh

原文链接:https://towardsdatascience.com/how-to-write-an-advanced-trend-following-strategy-to-algotrade-bitcoin-a38e47443ddc

译者:链三丰

------------------------------------------------------------------------------

相关文章阅读:

区块链研究实验室|如何利用Jesse协议编写比特币交易获利策略

区块链研究实验室|如何在交易策略中使用多个时间框架

本文来源:陀螺财经
原文标题:如何使用algotrade编写比特币的高级趋势跟踪策略

—-

编译者/作者:陀螺财经

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...