󰅡收起

西屋财富

致力于股票投资分析

30
十月

从零开始打造交易系统(I)(转载)

作者: 西屋财富
分类: 技术文章
发布时间: 2015-10-30 11:03

股票交易系统的核心一般由三个部分组成:
1. 数据系统 
2. 交易模型 
3. 下单接口
此外,风险控制、资金管理、报表生成等也是比较重要的模块。不过就实战而言,有了前三个已经是一个最基本的交易系统了。这一轮,主要讲讲数据系统。首先明确我们使用的编程语言:Python–非常优美简洁高效的语言,此处略去一万字介绍Python的语句。数据可以简单的分为两种 
一、行情类数据 
1. 历史行情 
2. 实时行情 
二、基本面数据 
1. 个股的、财务的 
2. 宏观的、行业的(这个部分的数据我在考虑要不要从我目前的系统里删除,至少在利用波动性赚钱这个问题上,宏观更多的是个筛子)
明确了数据的类别,下面就开始一步步实现之。数据是放在哪里的呢?除了实时行情,别的所有的数据都放在MySQL数据库里,每天定时定点的ETL数据入数据库。如果在模型中用到这些数据,也是从MySQL数据库中加载。实时行情有很多种得到的方法,一种是刷行情软件的数据出来,一种是接收交易所的卫星传来的数据文件解析之,还有或者干脆花点钱买一个数据接口吧。
历史行情的来源:由于时间不着急,可以在收盘之后抽取交易软件的数据,或者不怕麻烦去一些财经网站上去取数据,或者利用Excel插件从一些行情提供商那里扒数据,一种可行的延时行情来自于Sina。 基本面数据通常我都是去Excel里扒(很残暴但是最多一周干一次活,放在周末做倒也不是很影响效率)。
http://vermeulen.ca/python-stock-market.html
插一句,对于交易系统而言,我们需要的一些Python包(这个建议来自这里,略有删减),懒的动脑筋呢就装一个大而全的Python(x,y)吧,下面一大半都搞定了。
如果没有的呢就去这里看一下http://www.lfd.uci.edu/~gohlke/pythonlibs/,UCI的同学们学术之余不忘给大家提供方便啊都是德艺双馨的码农。
1. NumPy:实现各种数组对象函数和傅立叶变换等等科学计算模块。 
2. SciPy:提供更多科学计算功能,包括矩阵,求解线性方程组,积分运算,优化等。 
3. matplotlib:一个跨平台的数值绘图包,可绘制高质量的2D,3D图像,此外还有灰常强大的。 
4. MySQL for Python:Python操作MySQL数据库的接口软件包。 
5. xlrd:开发提取Microsoft Excel的数据的工具库。 
6. RPy2:著名统计软件R的python界面包,可在python内执行各种R功能函数。 
7. Boost.Python:提供C++和Python互操作的C++库。 
8. PyMC:实现MH算法的Python类,提供灵活的建模功能。 
9. SimPy:一个面向对象,基于过程和离散事件的模拟语言,拥有基于代理的整体交付的建模环境。 
10. Pycluster:高效的继承和k-means聚类的实现。 
11. SqlAlchemy:一个很好用的数据库包,用对象关系映射(Object Relational Mapper) 很容易把数据记录 和Python Class搞成配套。它能让开发者完全发挥出 SQL 的灵活性与强大的能量。 
12. wxPython:一组Python扩展模块,跨平台,包括各种从wxWidgets发展的GUI类,
回到正题,先建立数据库,结构、思路和上面一样,这里有一个SQLAlchemy的快速指南,建立好相关的DB之后,开始爽爽的四处抓数据吧!利用multi-thread 可以大大的加速抓数据的速度,第一次由于要抓大量的historical data 费时会比较多一些,但是一旦成型了每天就只要抽取当天的数据就快多了。
实时的高频数据分析起来比较的复杂,不过也是很重要的,实时的高频数据可以认为是一个multi-dimensional data stream, 神马做data stream mining的方法都可以迁移过来做,做compress也是必须的啦,不然都放那就数据库撑爆了或者硬盘很大计算能力也会被撑爆掉的,computational capacity本来就是一个巨大的资源。 这块呢可以做一个feature extraction,各种统计量,技术指标,K线特征量都可以一步步加上。此处省略十万字对高频数据的处理方式,先从daily level的数据起步,逐步实现trading system。
建立一个合理的数据库结构对软件的效率是非常重要的。数据库设计有很多注意点,不过我总体认为股票的数据库还是相对比较简单的,交易系统的主线是以A股成份股本身构建的,此外还有一些辅助的东西,诸如股票池啦,策略池啦,股票信息的变更啦(名字改了、类型改了、ST不ST啊),权益信息啦,等等等等。

在上一篇中已经说到,数据如何摆放是交易系统好用的一个基本要素,而且数据本身和系统的耦合度很低。如果有一家公司能做这种独立的数据提供商本来就是可以做的一个事情,但是我们的市场还处在一个比较早期的阶段只有一切靠自己了。
数据库我们选用MySQL,为什么选这个呢:1. 稳定 2. 高效 3. 免费 4. 流行。SQLite也是一个很好的选择,不过我对这个不太熟悉,在没有做HFT(High Frequency Trading)之前,其实对数据库也没有那么的挑剔。
数据库结构:

1. Bar data: Open, Close High, Low, Volume, Time, Ticker
2. Quote: Ticker, Date, Time Stamp, [Bid, Bid Size; Ask, Ask Size](i=1-5);
3. TA data: K, D, J, RSI,… …(这个可以N长N长)
4. Fundamental data
5. MacroEconomics data

数据库交互:
正如我们提及到的,整个Proj将以Python为主要的载体,利用模块化的设计来逐步完善。

程序是为了解决问题存在的,而不是制造问题。

Python本来是有MySQLDB这个很方便的DB API模块的,有人会说那你还要罗嗦什么嘛,直接SQL之呀!大错特错了,如果用SQL来进行系统的开发,我们将会陷入万劫不复的困境。Python是个优美的语言,SQL也是一个优美的语言,但是两个优美的语言遇到一起,产生的不总是优美:-) 我们遇到的第一个问题是,如果更优美的存放数据,如何把这个一行一行的数据和Python程式里的Objects联系在一起,这是一个朴素的想法。
所以我们有sqlalchemy! 这就是解决上面的问题的!
Base = declarative_base(bind=engine) 继承这个Base,即可以实现对象到数据的mapper,实在是很强大和方便。
[backcolor=white !important][size=1em][backcolor=white !important][size=1em]

01

class Bar(Base):


[backcolor=white !important][size=1em]

02

__tablename__ = 'bar'


[backcolor=white !important][size=1em]

03


[backcolor=white !important][size=1em]

04

bar_id = Column(Integer, primary_key=True)


[backcolor=white !important][size=1em]

05

gregorian_day = Column(Integer)


[backcolor=white !important][size=1em]

06

date_string = Column(String(12))


[backcolor=white !important][size=1em]

07

year = Column(Integer)


[backcolor=white !important][size=1em]

08

month = Column(Integer)


[backcolor=white !important][size=1em]

09

day = Column(Integer)


[backcolor=white !important][size=1em]

10

px_open = Column(DECIMAL)


[backcolor=white !important][size=1em]

11

px_close = Column(DECIMAL)


[backcolor=white !important][size=1em]

12

px_high = Column(DECIMAL)


[backcolor=white !important][size=1em]

13

px_low = Column(DECIMAL)


[backcolor=white !important][size=1em]

14

volume = Column(Integer)


[backcolor=white !important][size=1em]

15


[backcolor=white !important][size=1em]

16

def __init__(self, gregorian_day, date_string, year, month, day,


[backcolor=white !important][size=1em]

17

  px_open, px_close, px_high, px_low, volume):


[backcolor=white !important][size=1em]

18

  self.gregorian_day = gregorian_day


[backcolor=white !important][size=1em]

19

  self.date_string = date_string


[backcolor=white !important][size=1em]

20

  self.year = year


[backcolor=white !important][size=1em]

21

  self.month = month


[backcolor=white !important][size=1em]

22

  self.day = day


[backcolor=white !important][size=1em]

23

  self.px_open = px_open


[backcolor=white !important][size=1em]

24

  self.px_close = px_close


[backcolor=white !important][size=1em]

25

  self.px_high = px_high


[backcolor=white !important][size=1em]

26

  self.px_low = px_low


[backcolor=white !important][size=1em]

27

  self.volume = volume


[backcolor=white !important][size=1em]

28


[backcolor=white !important][size=1em]

29

def __repr__(self):


[backcolor=white !important][size=1em]

30

  return "<price('%s', '%s',="" '%s','%s','%s','%s','%s','%s','%s','%s')="">" % \


[backcolor=white !important][size=1em]

31

  (self.gregorian_day, self.date_string, self.year, self.month,


[backcolor=white !important][size=1em]

32

  self.day, self.px_open, self.px_close, self.px_high,


[backcolor=white !important][size=1em]

33

  self.px_low, self.volume)


[backcolor=white !important][size=1em]

34

</price('%s',>




然后调用一下Base.metadata.create_all(engine)即可以自动创建好相关的数据库。再调用session()既可以实现数据的提交。这里不妨看下manual,或者偷懒的看一下中文版的。
定义好Class,定义好relation,定义好mapper,定义好DB。下面就是去找数据了。
最重要的数据来自两块,首先解决Bar,对于Python而言,强大而牛X的matplotlib里有一个finance组件里就直接包含了这个函数。quotes_historical_yahoo这个函数可以直接返回ticker的Bar data在tuples,真是方便无比。

from matplotlib.finance import quotes_historical_yahoo
quotes_historical_yahoo(ticker, start, end) #list of tuples

然后每日让电脑自动的去synchronize数据,那么Bar的数据就搞定勒;下面就是实时data,实时的data来自sina(下文为部分复制粘贴),只需访问新浪的股票数据 接口:
例如: http://hq.sinajs.cn/list=sh601006这个股票数据接口会返回一串文本,如下:

var hq_str_sh601006="大秦铁路, 27.55, 27.25, 26.91, 27.55, 26.20, 26.91,26.92, 22114263, 589824680, 4695, 26.91, 57590, 26.90, 14700, 26.89, 14300,26.88, 15100, 26.87, 3100, 26.92, 8900, 26.93, 14230, 26.94, 25150, 26.95,15220, 26.96, 2008-01-11, 15:05:32";

其实上面的每一个数据都代表了一个股票数据,具体股票数据的含义如下:

0: "大秦铁路",股票名字;1: "27.55",今日开盘价;2: "27.25",昨日收盘价;3: "26.91",当前价格;4: "27.55",今日最高价;5: "26.20",今日最低价;6: "26.91",竞买价,即“买一”报价;7: "26.92",竞卖价,即“卖一”报价;8: "22114263",成交的股票数(单位是股)9: "589824680",成交金额,单位为“元10: "4695",“买一”申请4695股,即47手;11: "26.91",“买一”报价;12: "57590",“买二”13: "26.90",“买二”14: "14700",“买三”15: "26.89",“买三”16: "14300",“买四”17: "26.88",“买四”18: "15100",“买五”19: "26.87",“买五”20: "3100",“卖一”申报3100股,即31手;21: "26.92",“卖一”报价(22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”30: "2008-01-11",日期;31: "15:05:32",时间;

这个接口迄今为止还用的挺好,根据我自己和level II数据的比对,这个数据基本是实时的,更新非常快,用Python解析上面这段报文是很简单的,不加多说,放入数据库就可以实现高频数据,不放呢,就让你的trading system帮你看盘吧!为了能更快的读取数据,可行的方法是用多线程,不过还是比较慢,一个更为山寨的方法是,通过读大智慧的数据来获得实时数据,复制大智慧的数据进剪贴板,然后解析剪贴板的内容,这个我用一个叫快手的软件实现了:-) 那叫一个山寨!有一位朋友做了一个local的数据解析软件叫STS,我还没有弄清楚原理,有机会问问他怎么做的再和大家分享~
到这里,行情的数据都做完了,下面就是fundamental数据了,这一块我也有一些山寨的好用的方法:-)
先回家了,最近的市场在震荡中寻找突破,不过短期总结是,害怕踏空不敢往下砸,恐惧紧缩不愿往上顶。市场的意见非常的不一致,所以短期很难有大行情,也非常的难做。

󰁠

本文出自 西屋财富 ,转载时请注明出处及相应链接。

本文永久链接: http://www.15fund.com/2015/10/30/352.html

发表评论

电子邮件地址不会被公开。

*

普人特福的博客cnzz&51la for wordpress,cnzz for wordpress,51la for wordpress