下面是一个交易环境,在这个环境中,所有可能的交易策略都可以以非常动态的方式进行测试。即使是初学者Python程序员也可以创建和回溯他们的交易想法,最终解决他们的疑虑。使用环境和实现您自己想法的唯一先决条件是对Python结构(如for循环和if语句)有基本的了解,以及对pandas的足够了解,以便从数据帧的正确列/索引位置获得正确的价格,这可能对面向对象编程的理解水平较低,这取决于您的策略的复杂性。
收集数据
首先读取数据。在这个脚本中,我们使用二进制API,它允许从交易所列出的各种加密货币中收集数据。例如,从2019年3月12日起,每种加密货币的价格从6月28日的6月28日起发生变化,每种加密货币的价格从2020年3月的6月28日不同。在我的机器上,binanceapi的读取过程大约需要五个小时才能完成,但是通过一个简单的CSV写操作,在使用脚本时几乎可以立即检索到它。
关于数据读取的一些值得注意的事情:
1要访问binance API,只需从命令行PIP安*inance客户机。其他依赖项在其各自的导入行上进行了注释。
2当binance客户机请求API密钥时,这些密钥只对实时向币安交换发送事务订单是必需的,而不是用于读取数据。我保留格式,以防这是任何读者所期望的用例。
3在收集每个代币的数据之后,我们需要停止脚本运行60秒。这是为了防止binance API因为我们请求的数据太多而把我们踢出去。我目前还没有遇到这种问题,但是如果遇到错误,这个时间可能需要增加。
4其中包含一个简单的移动平均函数,该函数展示了如何从价格数据中设计特性并将其添加到数据帧中的示例。如图所示,这可以是您选择的自定义函数,也可以是web上的通用指示器的函数。
5卷数据也可用,但在这种情况下不使用。如果您感兴趣,请将其添加到第32行。
6CSV文件的自定义名称可以在第72行用引号编辑。
importnumpyasnp#pipinstallnumpyfromtqdmimporttqdm#pipinstalltqdmfrombinance.clientimportClient#pipinstallpython-BinanceImportPandasPd#PipInstallPandasFromDateTimeImportDateTimeImportTransDoma_LOW=40A_uHigh=150DeFicompute_Ua(数据,窗口):a=数据滚动(window=window).mean()returna#selectCryptoCurrencesYou’dliketogatherandtimeinteralratios=[‘何一’,’火币4’,’LTC‘,’XLM’,’XRP‘,’XMR’,’TRX’,’IOTA’,’以太坊‘,’DASH’,’ZRX’]开始时间’2019年3月28日’END_TIME=’2020年6月1日’api密钥=”api’secret=”client=client(api_key=api’key,api_usecret=api_usecret)合并=false ForRatiO比率:打印(f’正在收集{ratio}数据…’)数据=客户端.getu历史克林(符号=f'{ratio}USDT‘,区间=客户:克莱恩区间1分钟,开始时间str=开始时间,结束时间=结束时间)cols=[‘TIME’,’Open’,’High’,’Low’,f'{ratio}-美元’close’,f'{ratio}-美元体积’,’CloseTime’,’QuoteAssetVolume’,’NumberOfTrades’、’TBBAV’、’TBQAV’、’null’]温度Df=pd数据帧(data,columns=cols)temp_df=temp_2;df[[‘time’,f'{ratio}-USD_uClose’]]ifmerge==错误:df=温度dfelse:df=pd.merge(df,temp_2;df,how=’inner’,on=’time’)merge=Trueprint(’complete’)时间。睡觉(60)ţ睡一觉,双城API不会把你踢出门外nydatasksforcolindf.columns:ifcol!=“时间”:df[col]=df[col].astype(np.浮动64)福拉蒂O比率:df[f'{ratio}}{A{LOW}’]=compute Ua(df[f'{ratio}-USD},A}LOW)df[f'{ratio}}{A{HIGH}]=compute{A(df[f'{ratio}-USD{close’],A高)#clipNaNsdf=df[A UUHIGH:]df=测向复位index(drop=True)#conertbinancetimestamptodatetimeforiintqdm(范围(len(df)):df[‘time’][i]=datetime.fromtimestamp(整数(df[‘time’][i]/1000))df.tocs(’12-硬币-Mar18-Jun20’)
很好,现在我们有一个庞大的加密货币价格数据集。在进入交易环境之前,让我们创建一个简单的内存类,这样我们就可以存储每个回溯测试事件的信息。
记忆
氯助理记忆:DeFi初始化(自身):自我清除()DeFiclear(自我):self.actions=[]删除内存(自身,新操作):self.actions.append(新动作)
这个类很容易解释;它只是一个简单的内存对象,允许我们在每个周期后附加购买/出售操作和清除内存。
现在我们有了数据和内存对象,让我们进入交易环境。
我们的环境有两个参数:我们刚刚创建的数据帧和要在回溯测试过程中包括的货币比率(例如何一和LTC等)。
我们的环境还有两个其他方法:reset()和step()。
这是另一个不需要太多解释的项目:它只是将交易环境重置为默认状态。我们的目标是运行多个召回周期,我们将在每个周期之后调用它。环境重置()重置所有本地变量,如代币余额、周期、数据帧的索引位置、跟踪特定策略以及可能对日志记录有用的任何其他信息。环境的默认状态是美元余额为1.0,每个加密货币的余额为0.0。有关reset()方法的一些重要注意事项:
请注意,每次重置都占用主数据帧的一小部分,并将其称为“事件”,而不是在回溯测试期间遍历整个600000个或更多的数据实例。这是策略对每个周期进行回测的区间。您可以使用常量分钟/集或天/集来指定此周期的数据帧持续时间。在本例中,我们使用1天或1440分钟的周期大小。
启动环境时(在uuInit上,调用reset()方法。这将在第一次调用en对象时设置所有环境变量。
环境步骤()方法
本文将此方法分为两个部分:交易策略的实施和绩效指标的计算。
策略
在这个例子中,我不想对讨论中可能遇到的更复杂的交易策略进行更深入的技术分析,而是尝试一下我们在互联网上看到的一种常见策略的有效性:移动平均线交叉策略。如果你不熟悉这个概念,那么这个想法的要点是,当一个短窗口移动平均线穿过一个较长的窗口移动平均线rarr;buy;时,当短窗口移动平均线返回到长窗口移动平均线rarr;卖出之下时。
现在,我不确定是否有人相信这个策略真的有效(在某些情况下可能会这样),但是为了演示回溯测试环境(因为实现更复杂的策略会让您从修改自己的想法中获得一些乐趣),让我们考虑一下。如下面的代码所示,我们有两个关键的if语句,它们检查移动平均线并决定是否记录买入或卖出(或不记录)。需要熟悉几个本地变量:money_uin和to_uBuy。这些字符串变量跟踪您当前持有的资金量以及购买开始时的去向。输入买入和卖出if语句后,这些变量将相应地更新;因此,余额将根据您当前持有的价格进行更新。请注意,对应余额乘以每笔交易的交易费用乘数,在本例中为0.99925。此值基于使用BNB代币(币安交易所可用的***选项)时的0.075%币安交易费,但可以根据您特定交易所的交易费用进行更改。
性能指标
我们将使用两个指标来评估回测区间内策略的结果:回测区间后的资产净值和回测区间内的平均市场变化。您的净余额是根据您的货币的当前价格和您的货币金额将您持有的资产转换为美元来计算的。一个区间内的平均市场变化是通过在事件开始和结束时对所有选定货币的价格进行平均,然后除以这些值来计算的。基于这些指标,最终目标是以高于平均市场份额时的净资产(明显高于刚开始时的净资产)来完成这一事件。
每集天数=每集1分钟=1440*每集天数=100交易费用乘数=0.99925;如果使用bnopayfee,这是双关优惠sclassEn:定义初始值,测向):self.ratios=比率本身.主数据框=dfself.reset()DeFireset(自动):自身余额={‘USD’:1.0}自我比率: 自我平衡[比率]=0.0self.iloc=随机.randint(0,长度(self.maindf)-每分钟第1集)自我。插曲Df=self.main东风[自我.iloc: 自我.iloc+每集分钟数+2]自我金钱单位:=’USD’self.start时间=自我。插曲df[‘time’].iloc[0]自我结束时间=自我。插曲df[‘time’].iloc[-1]destep(自我):自我.iloc+=1#—–此处实施策略——–如果自己有钱单位:=‘美元’:自我比率:#iFlows宏esaboeighaifself.第集df[f'{ratio}}{A}LOW}][自我.iloc]gt;自我。插曲df[f'{ratio}}{A}HIGH}][自我.iloc] 和自己。第集df[f'{ratio}}{A}LOW}][自我.iloc-1] gt;自我。插曲df[f'{ratio}}{A}HIGH}][自我.iloc-1] 公司名称:自我介绍买入=比率自我介绍购买)自我平衡[ 自我介绍购买]=(自我平衡[美元]/自我。插曲df[f'{自我介绍买入}-美元成交][自我.iloc])*交易费乘数自我平衡[‘USD’]=0.0自行购买价格=自我。插曲df[f'{自我介绍买入}-美元成交][自我.iloc] 内存.add记忆(购买)自我介绍购买}:{自行购买价格}’)自我金钱英寸=自我介绍buybreakifself.money进来!=’USD’:#无法支付因努斯迪夫赛尔夫第集df[f'{自我金钱在}{A}LOW}’][自我.iloc]lt;自我。插曲df[f'{自我金钱在}{A}HIGH}’][自我.iloc]:#如果Highacrosselowlowa#卖钱#/美元自身余额[‘USD’]=(自我平衡[ 自我金钱在]*自我。插曲df[f'{自我金钱单位:美元自我.iloc])*交易费乘数自我平衡[ 自我金钱英寸]=0.0自我推销价格=自我。插曲df[f'{自我金钱单位:美元自我.iloc] 内存.add去记忆(f’Sell{自我金钱在}:{自我推销价格}’)自我金钱in=’USD’—-实施策略此处———-计算绩效指标此处——–运行networthself.net价值=自我平衡[“美元”]自我比率: self.net价值+=自我平衡[比率]*自我。插曲df[f'{ratio}-美元结算][自我.iloc]#净资产负债率超过第集“平均市场变化”自我平均值起始价格=0自我平均值结束价格=0自我比率: 自我平均值起始价格+=自我。插曲df[f'{ratio}-美元关闭’].iloc[0]自我平均值结束价格+=自我。插曲df[f'{ratio}-USDclose’].iloc[-1]自我平均值起始价格/=长度(比率)自我平均值结束价格/=长度(比率)自我平均值市场变化=自我平均值起始价格/自我平均值结束价格—–计算性能指标此处—-返回self.net沃思,自我平均值市场变化,self.start时间,自我结束时间
执行环境
在这里,我们一次一分钟遍历环境,根据策略进行买卖,跟踪性能指标以及将它们输出到日志的过程。
Df=读博士cs(’12-coins-Mar18_20’)en=en(比率,df)memory=memory()净价值_uworth_uocollect=[]平均市场价值u change_ucollect=[]对于i峎eposeInrange(NUM_u集):foriinrange(len(环境插曲df)-1):净值、平均市价变化、开始时间,结束时间=环境步骤()净值收集.追加(净值)平均市价变动收集.追加(平均市场变化)每次打印后的日志(插曲:{i}}’)打印(记忆.动作)print(’/n’)print(f’interal:{start{time}-{end{time}’)打印(f’networthafter{DAYS}每集}天:{net}worth}’)打印(f’aeragemarketchetchange:{aerage{market_uchange}’)打印(’/n’)内存。清除() 环境重置()logoerallprint(f’networthaerageafter{NUM_uepeats}后台测试代码:{np平均值(净值收集)}是的,平均市场价值的平均值(f’aerage,aeragemarketchangeoer{NUM_u集}集:{np平均值(平均市价变化收集)
我们怎么样?
好吧,正如之前预测的那样,因为策略比较简单,效果不是很好。如图所示,我们预计,在平均日增长率为0.2%的市场中,该策略的实施将导致日均净值下降4%(OOPS)。然而,除此之外,日志还显示了一个快速、动态和易于阅读的策略输出。策略随机选取2019年3月至2020年6月的100多个单日区间进行回溯测试,并提供每笔交易的买卖信息。现在你对你的问题有了一些答案!
第96集[“买入何一:5255.99”,“卖出何一:5227.76”,“买入火币4:155.86”,“卖出火币4:155.41”,’买价:67.46′,’ 销售成本:67.45′,’ 买主:0.3167′,’ 鞍区:0.3176′,’ 买主:0.3167′,’ 塞利奥塔:0.3151′,’ 买价:67.67′,’ 销售成本:67.42′,’ 买方:61.38′,’ 销售收入:61.59’,’买入以太坊:4.5225’,’卖出以太坊:4.5076’,’买主:0.2743′,’ SellZRX:0.2723’,’买入火币4:155.2’,’卖出火币4:156.98’,’买入:0.09605′,’ SellXLM:0.09597′,’ BuyLINK:0.439′,’ SellLINK:0.439′,’ 购买链接:0.4418′,’ SellLINK:0.4672’,’买入何一:5308.08’,’卖出何一:5304.94’,’买入:0.09966′,’ SellXLM:0.09965′,’ 买方:62.29′,’ 销售收入:62.22′,’ 买方:0.02312′,’ 卖方:0.02307′, ‘ 买价:72.82] 时间区间:2019-04:2912:25:00-2019-04-3012:26:00 1天后净值:1.022167284772814平均ketchange:0.988959335567251集:99[‘买入卢比:0.30917′,’ SellXRP:0.31171’,’买入何一:9641.57’,’卖出何一:9635.6’,’买方:0.02252′,’ 卖方:0.02238′,’ 买入:0.08462′,’ SellXLM:0.08457′,’ BuyLINK:2.2158′,’ SellLINK:2.211’,’买入以太坊:4.2811’,’卖出以太坊:4.2527’,’买入火币4:212.07’,’卖出火币4:211.26’,’布约塔:0.2835′,’ 鞍区:0.2833′,’ 买入:0.08375′,’ SellXLM:0.083179999999999′,’ 买方:89.2′,’ 销售成本:89.34′,’ 买方:79.39′,’ 销售收入:79.15’,’买入何一:9570.01’,’卖出何一:9548.48’,’购买链接:2.1819′,’ SellLINK:2.1595′,’ 买价:89.33′,’ 销售成本:89.4’,’买入以太坊:4.1803’,’卖出以太坊:4.1903’,’买入何一:9540.07’,’卖出何一:9559.46’,’买入火币4:210.83’,’卖出火币4:208.78’,’买价:90.68′,’ 销售成本:90.39′,’ 买价:90.76′,’ 销售成本:90.44′,’ 3100.08卢比’,’ 售价:99xRP’,’买入何一:9504.64’,’卖出何一:9490.15’,’买入火币4:209.7’,’卖出火币4:209.77’,’布约塔:0.2853] 时间区间:2019-07-2816:39:00-2019-07-2916:40:00 1天后净值:0.9218801235080804平均ketchange:0.9984598063740531 100BackTestePicode后的平均净值:0.9656146271760888平均值,平均市场变化超过100剧集:1.0021440510159623
这显示了100组只有两个周期的输出。为了简洁起见,我选择了一个盈利期(96)和一个非盈利期(99)来显示,而实际输出显示了所有100个周期的结果。但我们真正关心的不是某个事件的结果,而是一个问题:我的战略平均表现如何?这将显示在最终平均事件日志中。
python日志包对于运行许多不同策略并登录到不同文件中以比较结果的人来说非常有用。
事实证明,当日交易风险很大。我希望读过这篇文章的人会发现这个工具有助于探索他们的交易理念,使他们能够在将策略投放市场之前探索自己的决策。对于编程和算法交易知识有限的人来说,他们似乎缺乏做出明智交易决策的资源;
一些其他的想法
在我看来,在这个例子中使用我们的环境是向像我这样对面向对象编程知识有限的人(也许还是我自己)介绍动态算法交易的好方法。就我个人而言,我使用这个工具来回溯测试许多不同的策略,这些策略包括价格数据的更多特性,并允许额外的功能;也就是说,交易加密货币(例如何一/LTC等价物)的能力,而不仅仅是加密货币兑美元的能力,反之亦然。
————————————-
原作者:Lee SCHMALZ
链接到原文:https://towardsdatascience.com/dynamic-cryptocurrency-trading-backtesting-platform-python-219dfcd7421e
翻译:连三丰
————————————-
相关文章如下:
区块链研究实验室如何使用JaaScript为DeFi协议提供资产数据
区块链研究实验室如何从DeFi协议中获取交易数据
区块链研究实验室|使用jaa应用程序在kybernetwork中实现Dei代币交易
文章标题:区块链研究实验室动态数字货币交易策略回测平台Python
文章链接:https://www.btchangqing.cn/46079.html
更新时间:2023年06月12日
本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。