上一篇博文谈了谈股票预测方面的问题,这一篇就谈谈外汇交易吧。
对冲是金融领域的常见操作之一,即利用市场的不对称性,在不同市场进行方向相反的交易来保证稳定收益。我是在观看了李永乐老师对足彩对冲的原理讲解之后(http://www.iqiyi.com/w_19rz0551xx.html),才有了这个想法。
对于一次足彩的投注来说,仅有两个投注方向,即看好A队或看好B队。如果想通过对冲来获得稳定的收益,必须根据不同的博彩公司开出的盘口,来计算是否有套利空间。如果在同一家博彩公司同时进行正、反方向的投注,肯定会入不敷出,因此足彩的对冲需要在不同的博彩公司完成方向相反的投注。不同于足彩的投注,外汇交易由于有多种外汇的存在,每一种货币都会与其他货币产生相应的汇率,理论上在一个有N种货币的外汇市场中,存在的汇率应有
种。即每两种货币之间都会产生汇率,且产生正向与反向两种汇率。例如欧元与美元两种货币,正向汇率是1欧元兑1.1599美元,反向汇率是1美元兑0.8616欧元。
一般来说,直接用两种货币进行对冲,肯定是无法产生收益的,两种相反方向的汇率相乘必定小于1,如欧元换美元再换欧元,1欧元经过这两笔操作,得到1.1599*0.8616=0.99936984欧元。那么,能不能通过第三方货币的加入,经过三角循环交易,获得大于1的收益。为验证对冲获利的可能性,我利用python爬虫,来对汇率进行实时爬取,计算同一时刻人民币、美元、欧元有没有循环交易套利的空间。
图1.三角对冲示意图
由图1可以看出,我们需要对两个方向的交易进行验证,外圈是人民币→美元→欧元→人民币的交易方向,内圈是人民币→欧元→美元→人民币的交易方向。为此我们需要获得6种汇率,即:人民币兑美元、美元兑人民币、人民币兑欧元、欧元兑人民币、美元兑欧元、欧元兑美元。
这里通过新浪财经的网站获取实时汇率,获取这6种对应汇率的URL
1 self.usdcny_url = 'http://finance.sina.com.cn/money/forex/hq/USDCNY.shtml' 2 self.cnyusd_url = 'http://finance.sina.com.cn/money/forex/hq/CNYUSD.shtml' 3 self.eurcny_url = 'http://finance.sina.com.cn/money/forex/hq/EURCNY.shtml' 4 self.cnyeur_url = 'http://finance.sina.com.cn/money/forex/hq/CNYEUR.shtml' 5 self.usdeur_url = 'http://finance.sina.com.cn/money/forex/hq/USDEUR.shtml' 6 self.eurusd_url = 'http://finance.sina.com.cn/money/forex/hq/EURUSD.shtml'
之后对页面源码进行观察,发现其汇率会以文本的形式显示在
标签内。又由于网页是使用ajax技术动态刷新的,需要对动态页面进行爬取,所以我们选用selenium+phantomJS来对汇率进行爬取。
因为这次仅仅是对三角对冲的获利可能性进行验证,因此程序很简单,分为两个函数,一个函数负责爬取汇率,另一个函数分两个方向计算交易获利情况。当交易后的数值大于1的时候,即判断有套利空间。
爬取汇率函数:
1 def get_exchange(self): 2 # 使用selenium通过PhantomJS来进行网络请求 3 tag = 0 4 while(tag==0): 5 driver = webdriver.PhantomJS() 6 try: 7 # C-人民币 U-美元 E-欧元 8 driver.get(self.usdcny_url) 9 UC = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 10 driver.get(self.cnyusd_url) 11 CU = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 12 driver.get(self.eurcny_url) 13 EC = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 14 driver.get(self.cnyeur_url) 15 CE = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 16 driver.get(self.usdeur_url) 17 UE = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 18 driver.get(self.eurusd_url) 19 EU = float(BeautifulSoup(driver.page_source,'html.parser').find('div',id='quoteWrap').find('h5').text) 20 print(u'汇率获取完毕 ') 21 print('美-人:',UC,' 人-美:',CU,' 欧-人:',EC,' 人-欧:',CE,' 美-欧:',UE,' 欧-美:',EU) 22 tag=1 23 except: 24 print(u'爬取数据故障,正在重新爬取。') 25 time.sleep(5) 26 if tag==1: 27 return {'uc':UC,'cu':CU,'ec':EC,'ce':CE,'ue':UE,'eu':EU}
利润计算函数:
1 def calc_profit(self,exchange_dic): 2 begin_money = 1000 3 end1 = begin_money*exchange_dic['cu']*exchange_dic['ue']*exchange_dic['ec'] 4 end2 = begin_money*exchange_dic['ce']*exchange_dic['eu']*exchange_dic['uc'] 5 profit1 = (end1-begin_money)/begin_money 6 profit2 = (end2-begin_money)/begin_money
程序代码在我的GitHub上有分享。
https://github.com/NosenLiu/exchange_proift
最初的时候,设定每30秒进行一次爬取计算,发现确实是有套利空间的,留下类似下方的记录。
图2.套利空间验证结果记录
可以看出,存在某些时间段,通过一次三角循环交易可以获取稳定收益。一次三角对冲的理论收益大约在万分之一左右。那么一个交易日中有多少次机会可以对冲呢?为此,我将程序进行修改,设定大约每20秒计算一次,如果有套利空间的话,自动记录到文件里面,无法获得收益则不进行记录。经过了一个小时的午睡时间。发现日志文件里产生了35条类似下图的记录。
图3.一小时内三角对冲结果记录样本(部分)
粗略计算,每20秒爬取计算一次的话,一个小时约爬取计算180次,其中有35次拥有套利空间,即大约有20%的时间,可以从外汇市场进行三角对冲套利!! 这可不得了,按一次套利万分之一的收益来算,一个小时35次对冲交易,可以获取千分之3.5的收益!每天交易一个小时,一个月交易20天的话,一个月的收益率就有7.2%!!!
当然,上面的推断都是基于0交易佣金的基础上的。各个外汇平台的规定都有所不同,一般来讲收佣金的平台,点差小;不收佣金的平台点差大,相对来讲也就更难以发掘三角对冲的套利空间。
这么一算,似乎真金白银就在眼前。抱着早日实现财务自由的梦想,咱说干就干,初步的想法是基于某个外汇交易平台网站,爬取其中的外汇数据,使用selenium 这个Web应用程序测试工具实现自动下单完成交易的功能(毕竟手动交易太慢了,而且汇率稍微变动一点,套利空间就很有可能消失)。
可是当我真正着手开始做的时候,发现问题果然没那么简单。每个外汇平台都有自己的交易软件,想要获取其中的数据并且实现自动交易功能基本没有可能~~,看起来最有希望的福汇平台也是基于web的纯flash界面,普通爬虫根本就不好使,而flash内部的信息交互方式我也是完全不了解。感觉一下子就触碰到知识盲区了,陷入深深的无力感。
图4.福汇平台的纯flash交易界面
后来也有想过使用抓包软件之类的来获取外汇交易平台的汇率数据。主要存在以下两方面困难:一是抓包操作的自动化处理难以实现,没有在网络上找到现成的抓包+解析工具;二是即使获取了平台汇率数据,没有外汇交易平台的内部接口,自动化交易功能也难以达成。
当然,有困难并不代表着没有办法实现,通过外挂插件或对平台软件进行反编译的方法理论上是可以完成自动交易功能的,这里也欢迎各位朋友参与讨论。