本文最初发布于 The Startup,经原作者授权由 InfoQ 中文站翻译并分享。
最近,作者完成了他人生中的第一个加密货币交易 bot 的程序编写。他从比特币的历史价格入手,以十分钟为间隔,将数据导入 python Pandas 数据帧后,运行模拟程序,低买高卖。一切很顺利,代码也不复杂,作者甚至觉得,再给他几小时,他就能用robin_stock函数直接进行线上交易。然而,理想很丰满,现实很残酷。本文中作者分享了他在编写代码过程中的血汗教训,希望能够为大家节约些时间。
线上交易远比模拟交易要复杂
当你模拟交易时,你通常会做一些假设。当你的程序决定以某一时间点的价格进行买入或卖出时,交易永远是成功的,而你模拟的利润也会滚雪球式增长。
现实中的交易要比模拟交易复杂许多。线上交易需要时间完成,而价格也是在实时变化的。当 bot 在进行实盘交易时,在你的订单全部完成、甚至有的还没有开始之前,价格很可能已经有了大幅的变动。我将这种情况称作“摇摆不定”,这时就需要 bot 有灵活应对的能力。我选择的解决方案是保存订单交易号,每隔一段时间就检查一次结果。如果在一小时后没有任何币买入,那么 bot 自动取消买入订单,并再次尝试。
模拟中的交易可以全部完成,但在现实中,你还需要检查交易完成度以及订单是否完全丢失。
限价买入/卖出是个好习惯
线上交易时,我们需要确定买入卖出订单是限价交易还是市价交易。市价委托意味着交易是以现行汇率完成的,这很不好,毕竟价格可以在几秒钟内改天换地。这也是我们需要 bot 的原因之一。我选择以限价交易方式下单,这种情况下,即使价格大幅变动,我们也不会以预期之外的价格买入卖出。
面对精度要小心
作为事后诸葛来看,这点是非常显而易见的。但当我初次尝试用 bot 进行线上交易时,还是不幸掉进了坑里。在模拟交易中,执行一个以(cash_on_hand/coin_price)价格的买入指令非常正常,我们甚至可以让模拟器记录我们买入了 12.2342348998729384797 个 ETH,没有任何的问题。
但如果我们想在现实中复刻这种操作,那么我们极可能会以失败告终。交易平台对我们所指定的购买金额和价格的精度都有限制,这种限制因币种而异。仔细想想,其实没有任何问题;DOGE 目前的售价仅有几分钱,但 BTC 目前的售价超过了 19,000 美刀,以百分比形式小额购买 BTC 和 DOGE 的方式必然不能相同。
我的 bot 通过一个存储了不同币种价格和买入时的最大精度值查找表来计算买入委托数量。如果这点出了问题,那么我们很可能会收到服务器端的报错提示。
图源:Pixabay
注意服务器的异常处理
这一点更偏向于编程好习惯的养成,在刚开始写代码时就记得加上异常处理还是很重要的。当我们向服务器发出对话请求,无论是想获取价格、发布订单,还是检查状态,都要记得检查异常,检查异常,检查异常,重要的事情要说三遍。
我们的模拟交易没有维护窗口,没有服务器故障,也没有对我们自己写的库的错误调用。但是!现实生活中,这些都有可能发生。
电脑掉线或者没电关机怎么办
我们必须要面对电脑没电、网络掉线以及程序崩溃的问题。在计算移动平均线、相对强度指数(RSI),以及分析烛台模式(金融交易模式)时,我们需要确保数据的连贯性。断点的存在会导致我们程序的错误调用。这种情况下,我们就需要保存状态并检查数据的日期戳。如果在计算指标的时间段内存在断点,那么我们就需要暂停程序的运行,直到我们能拿到目标时间段内的全部数据。
货币种类和销售价格要匹配
bot 抽风并企图以 A 货币的价格卖出 B 货币的情况完全有可能发生,正如我曾经遇到过的一样,这种时候我们就需要一些看起来很蠢的操作。由于我在设计决定方面的缺陷,他早期版本的 bot 曾试图以比特币现金(BCH)的成本卖出比特币(BTC),这二者之间完全差了一个数量级。
唯一能令我不至于伤心欲绝的是,由于价格相差太多,交易被判定为错误。但假设误差仅仅是四倍的话,我怕是要赔的裤子都没了。
小心,小心,再小心。
能发短信报告情况的 bot 才是好 bot
大多移动公司可以以短信息形式发送邮件。在我们忙于其他事情时,如果 bot 可以实时通知我们情况,那真的是很方便了。我们会想知道交易是否成功,但我们更想知道 bot 是不是又干了些非常非常蠢的事情。
我的 bot 会在买入卖出时有通知提醒,同时还会发送每一笔交易订单的结果。这样,每笔订单是否交易成功,我都会了如指掌。
别让交易金额高于你的现有金额
编写 bot 时,我们可能会需要用小额交易测试一些更改。记得在代码开头添加金额限制,我们是不会想用账户内全部金额进行线上交易测试的。
用静态分析缩短开发时间
这一点其实也是编程好习惯的养成。在 Python 中,有的错误是直到我们执行某特定分支时才能发现的。如果一个错误出现在某个不常运行的函数中,比如 buy()或者 sell()函数,那么很可能在我们编程的几小时内都注意不到这点错误。
利用 PyLint 和 PyFlakes 之类的工具,我们可以更快地找到这类的错误。强烈建议大家多多利用这类工具,节约时间,节约精力。
小心驶得万年船,大家玩的开心!
请注意,本文中的所有观点都不是理财建议,我本身也只是个菜鸟。投资风险需要您自身承担,本文并不负任何责任。利用程序消费要远比手动加密货币交易风险更高,还请您多多注意!
原文链接:
https://medium.com/swlh/design-lessons-from-my-first-crypto-trading-bot-fcf654b99546
评论