1. 程式人生 > >量化交易學習:交易資料自動抓取

量化交易學習:交易資料自動抓取



    題記:一直對量化交易比較感興趣,想先自學一下,將來如果有機會,能到機構實戰就更棒了。去年用matlab做過一個股票下一交易日價格區間的預測演算法,至少在股災前那段時間準確率還行(別笑,預測區間當然不是在正負10%之間),不過受限於自己的本職工作強度太大(苦逼的移動網際網路行業),一直沒能繼續做下去。後面希望能擠時間慢慢做下去,就當是個業餘愛好吧。由於自己的本職工作是做音視訊的編解碼、增強相關的演算法的,所以對量化交易的演算法更偏好一點,其實兩個方向本質上是相通的,都可以抽象為對隨機過程的描述建模,模型建的好,音視訊的壓縮效率更高、增強效果更好,交易演算法的預測準度更高。anyway:我的思路是用RNN-LSTM做學習模型,RNN-LSTM可以用來做自然語言處理,也可以用來做語音識別及增強,當然也可以用來做交易趨勢預測啦。

       第一步:抓取交易資料。

       無論後面交易演算法多麼核心,都要先解決輸入問題。先解決交易資料的自動抓取吧。沒有絕對的原創,我的這步工作90%都是基於牛人的既有工作,原帖連結:http://www.zhihu.com/question/29648560/answer/56186559,先表示感謝。不過,原帖的程式碼應該是在低版本的python上可以工作的,但是在我的3.4.3版本上不能用,所以我的改造工作大約10%。改造後、可以正常work的程式碼如下:


"""
@author: David
"""
import const as ct
import pandas as pd
import json
import urllib.request
import urllib.error

def get_hist_data(code = None, start = None, end = None, ktype = 'D'):
 """
功能:
獲取個股歷史交易資料
--------
輸入:
--------
code:string
股票程式碼 比如:601989
 start:string
開始日期 格式:YYYY-MM-DD 為空時取到API所提供的最早日期資料
end:string
結束日期 格式:YYYY-MM-DD 為空時取到最近一個交易日資料
ktype:string(default=D, 函式內部自動統一為大寫)
資料型別 D=日K線,W=周K線,M=月K線,5=5分鐘,15=15分鐘
30=30分鐘,60=60分鐘
 輸出:
--------
DataFrame
 date 日期
open 開盤價
high 最高價
close 收盤價
low 最低價
chg 漲跌額
p_chg 漲跌幅
ma5 5日均價
ma10 10日均價
ma20 20日均價
vma5 5日均量
vma10 10日均量
vma20 20日均量
turnover換手率(指數無此項)
 """
 code = code_to_APIcode(code.upper())
 ktype = ktype.upper()

 url = ''
 url = get_url(ktype, code)
 print(url)

 js = json.loads(ping_API(url))
 cols = []

 if len(js['record'][0]) == 14:
  cols = ct.INDEX_DAY_PRICE_COLS
 else:
  cols = ct.DAY_PRICE_COLS
 df = pd.DataFrame(js['record'], columns=cols)

 if ktype in ct.K_TYPE_KEY:
  df = df.applymap(lambda x:x.replace(u',', u''))
 for col in cols[1:]:
  df[col]=df[col].astype(float)
 if start is not None:
  df = df [df.date >= start]
 if end is not None:
  df = df[df.date <= end]
 df = df.set_index('date')
 return df

def code_to_APIcode(code):
 """
功能:
 驗證輸入的股票程式碼是否正確,若正確則返回API對應使用的股票程式碼
"""
 print(code)
 if code in ct.INDEX_KEY:
  return ct.INDEX_LIST[code]
 else:
  if len(code) != 6:
   raise IOError('code input error!')
  else:
   return 'sh%s'%code if code[:1] in ['5', '6'] else 'sz%s'%code

def get_url(ktype, code):
 """
功能:
 驗證輸入的K線型別是否正確,若正確則返回url
 """
 if ktype in ct.K_TYPE_KEY:
  url = ct.DAY_PRICE_URL % (ct.PAGE_TYPE['http'], ct.PAGE_DOMAIN['ifeng'],
  ct.K_TYPE[ktype], code)
  return url
 elif ktype in ct.K_TYPE_MIN_KEY:
  url = ct.MIN_PRICE_URL % (ct.PAGE_TYPE['http'], ct.PAGE_DOMAIN['ifeng'],
  code, ktype)
  return url
 else:
  raise IOError('ktype input error!')

def ping_API(url):
 """
功能:
 向API傳送資料請求,若連結正常返回資料
"""
 text = ''
 try:
  #req = Request(url)
  text = urllib.request.urlopen(url,timeout=10).read().decode('utf-8')
  if len(text) < 15:
   raise IOError('no data!')
 except Exception as e:
  print(e)
 else:
  return text

#測試入口
print(get_hist_data('300291','2016-09-11'))

這部分程式碼已測試有效、可以直接使用。不過,需要提個醒(尤其是剛開始用python的童鞋):要注意程式碼的縮排,誰讓python的解析器那麼注重格式涅。。。