1. 前言

有點泄氣,讀者不多,贊同也不多,不過萬事開頭難。上一篇我分享了因子庫的設計,這一篇主要講實現,加上我的標題叫Python與量化多因子,勢必要加點代碼在裡頭,不過旨在拋磚引玉,點到即止,更多的內容需要讀者們自己去探索。

對了,讀者如果自己動手,基礎的Pandas,Numpy的操作還是需要會的,網上也有很多教程,大家也可以去看,如果有需要,後面我也可以寫篇文章來介紹。

2. 因子構成

好像現在各家券商的研報後面都會加上他們因子的構成,很多因子也都是差不多的。我把要做的因子簡單的歸類,大概有如下這些:

  • 規模類
  • 估值類
  • 盈利類
  • 成長類
  • 技術類
  • 一致預期類
  • 另類

其實大家用的因子估計都差不多,現在更關鍵的是對風格的把握,但這顯然也更難。

3. 準備工具

上一篇文章,我有說,我們的因子來自於一些底層的數據,但這些數據都存儲在一些底層的表當中,我們需要一個中間層,構建一個統一的數據介面,為我們計算因子提供便利。

這個中間層至少需要包含:

  • 提供交易日曆
  • 提供股票的行情
  • 提供財務數據,一致預期數據
  • 提供行業分類數據

這四個功能,至於每個功能如何實現,具體問題具體對待。

參考網上開源的Tushare,我們也可以設計自己簡單的Python數據介面:

import pandas as pd

class ForTheData:
def __init__(self):
self.calendar = pd.read_csv(r../calendar.csv)

def get_date_list(self, start, end, freq=d):
"""
獲取一段時間的交易日列表
:param start: 開始時間,str
:param end: 結束時間,str
:param freq: 頻率,d, w, m, q
:return: list of date
"""
pass

def get_next_date(self, date, n):
"""
用於獲得指定n天后的日期的函數,當n>0時往後推,當n小0時往前推
:param date: str
:param n: int
:return: str
"""
pass

def get_hist_data(self, start, end, universe, field):
"""
用於獲取股票的行情
:param start: 開始時間,str
:param end: 結束時間,str
:param universe: 股票池, list of tickers
:param field: 獲取的欄位, list
:return:
"""
pass

def get_balance_sheet(self, start, end):
"""
獲取資產負債表
:param start: 開始時間,str
:param end: 結束時間,str
:return: pd.DataFrame
"""
pass

def get_industry_classified(self, start, end, universe, classified_type=zx):
"""
獲取股票的行業分類數據
:param start: 開始時間,str
:param end: 結束時間,str
:param universe: 股票列表,list of tickers
:param classified_type: 行業分類類型
:return: pd.DataFrame
"""
pass

for_the_data = ForTheData()

我們定義了一個Python類,它可以幫助我們從前面提到的幾項數據源提取需要的Python數據。當然,考慮到環境不一致的原因,我沒有寫具體實現的邏輯,但我算是提供了一個設計文檔,可以藉助這個文檔來完成代碼。

4. 以20日市值平均因子為例

市值是規模因子類當中的一種,我們以20日市值平均這個因子為例,提供一個Python的偽代碼:

class AvgSize20d:
"""
20日總市值平均
"""
def __init__(self):
pass

def cal_factor(self, size):
"""
計算市值的平均值
:param size: 市值數據,pd.DataFrame,column為股票列表, index為日期
:return: Series
"""
return pd.Series()

def load_data(self, start, end):
"""
下載市值數據
:param start: 開始日期, str
:param end: 結束日期, str
:return:
"""
return pd.DataFrame()

def product(self, date):
"""
每日運行函數
:param date:
:return:
"""
pre_20d = for_the_data.get_next_date(date, -20)
size = self.load_data(pre_20d, date)
factor = self.cal_factor(size)

return factor

結合上一節定義的行情函數,日曆函數,輕輕鬆鬆,我們便完成了該因子的計算。當然,這個因子的定義確實也比較簡單,像基本面因子的計算會比較複雜些,但大體的框架是不變的。

5. 思考

  • 我們簡單的定義了因子計算的框架,但是如何將因子計算同一調度,並保存到資料庫當中,需要讀者進行思考
  • 因子計算當中可能會出現哪些異常,又如何處理?
  • 加油!

推薦閱讀:

相關文章