基本原理
  • 三因素模型表达式:

    E(Rit) − Rft = βi[E(Rmt − Rft] + siE(SMBt) + hiE(HMIt)

  • 根据一篇文章,选择三个因子作测试:
    • 财务因子:EPS
    • 成交量因子:log(30日日均交易量/昨日交易量)
    • 反转因子:(ma10-ma5)/ma5
    • 综合选取这三个因子,0.3,0.4,0.3的权值加和,选取较高的股票并持仓。综合选取这三个因子,0.3,0.4,0.3的权值加和,选取较高的股票并持仓。
策略实现
  • 初始资金100万,20万无明显效果差异,时间段为2017-01-01~2018-01-01.
  • 选取市盈率0~20之间的股票,每日对三因子加和进行排序
  • 每天进行判断,选取三因子加和排名前n的股票,若已持股,继续买入,未持股则买入,已持股中有不在排名前n中的,卖出。
  • (每日操作10只股票)运行截图(忽略曲线名):
  • (每日操作20只股票)运行截图(忽略曲线名):
遇到的问题及改进:
  • 采用的三个因子或许还能有其他财务因子进行代表
  • 本次代码中取得EPS的时间有些过长,有点想法,等我后面改进(已改进,不必每只股票每天的eps都获取一次)
代码如下:
# coding: utf-8
# @author: lin
# @date: 2018/11/20import QUANTAXIS as QA
import datetime
import pandas as pd
import time
import math
import matplotlib.pyplot as plt
import numpy as nppd.set_option('max_colwidth', 5000)
pd.set_option('display.max_columns', 5000)
pd.set_option('display.max_rows', 5000)class ThreePara:def __init__(self, start_time, stop_time, n_stock=10, stock_init_cash=1000000, n_days_before=1):self.Account = QA.QA_Account()  # 初始化账户self.Account.reset_assets(stock_init_cash)  # 初始化账户self.Account.account_cookie = 'three_para'self.Broker = QA.QA_BacktestBroker()self.time_quantum_list = ['-12-31', '-09-30', '-06-30', '-03-31']self.start_time = start_timeself.stop_time = stop_timeself.n_days_before = n_days_beforeself.stock_pool = []self.data = Noneself.ind = Noneself.n_stock = n_stockself.get_stock_pool()def get_financial_time(self):"""得到此日期前一个财务数据的日期:return:"""year = self.start_time[0:4]while (True):for day in self.time_quantum_list:the_financial_time = year + dayif the_financial_time <= self.start_time:return the_financial_timeyear = str(int(year) - 1)def get_assets_eps(self, stock_code, the_financial_time):"""得到高级财务数据:param stock_code::param the_financial_time: 离开始时间最近的财务数据的时间:return:"""financial_report = QA.QA_fetch_financial_report(stock_code, the_financial_time)if financial_report is not None:return financial_report.iloc[0]['totalAssets'], financial_report.iloc[0]['EPS']return None, Nonedef get_stock_pool(self):"""选取哪些股票"""stock_code_list = QA.QA_fetch_stock_list_adv().code.tolist()the_financial_time = self.get_financial_time()for stock_code in stock_code_list:# print(stock_code)assets, EPS = self.get_assets_eps(stock_code, the_financial_time)if assets is not None and EPS != 0:data = QA.QA_fetch_stock_day_adv(stock_code, self.start_time, self.stop_time)if data is None:continueprice = data.to_pd().iloc[0]['close']if 0 < price / EPS < 20:  # 满足条件才添加进行排序# print(price / EPS)self.stock_pool.append(stock_code)def cjlyz(self, data, n=20):# log(30日日均交易量/昨日交易量)data['cjlyz'] = 0data['n_days_vol_ave'] = QA.MA(data['volume'], n)data = data.fillna(0)last_index = 0for index, row in data.iterrows():if last_index != 0:data.loc[index, 'cjlyz'] = row['n_days_vol_ave'] / data.loc[last_index, 'volume']last_index = indexfor index, row in data.iterrows():if row['cjlyz'] != 0:data.loc[index, 'cjlyz'] = math.log10(row['cjlyz'])return data# 反转因子def fzyz(self, data, n=10, m=5):# (ma10-ma5)/ma5data['ma_10'] = QA.MA(data['close'], n)data['ma_5'] = QA.MA(data['close'], m)data['fzyz'] = (data['ma_10'] - data['ma_5']) / data['ma_5']data = data.fillna(0)return datadef get_EPS(self, stock_code, the_time):# 由财政数据中得到EPS,是上个季度的year = the_time[0:4]if_break = Falsen_EPS_list = []while (True):for day in self.time_quantum_list:date = year + dayif date < the_time:financial_report = QA.QA_fetch_financial_report(stock_code, date)if financial_report is not None:return financial_report.iloc[0]['EPS']if if_break:  # 触发,则跳出循环breakyear = str(int(year) - 1)def three_para(self, data):# 整合三个因子data = self.cjlyz(data)data = self.fzyz(data)data['EPS'] = 0if_first = Truelast_index = Nonefor index, row in data.iterrows():if_value_equal = True  # 值是否跟上次值相同the_time = str(index[0])[:10]if not if_first:last_time = str(last_index[0])[:10]for time_quantum in self.time_quantum_list:middle_time = last_time[:4] + time_quantum  # 得到判断的分界点if last_time < middle_time < the_time:  # 有一次处于分界点左右,则需要重新计算if_value_equal = Falsebreakif if_value_equal:data.loc[index, 'EPS'] = data.loc[last_index, 'EPS']if if_first or not if_value_equal:stock_code = str(index[1])# print(stock_code)value = self.get_EPS(stock_code, the_time)data.loc[index, 'EPS'] = valueif_first = Falselast_index = index  # 把当次索引加入,下次调用则为上次索引data['decided_para'] = 0.3 * data['EPS'] + 0.4 * data['cjlyz'] + 0.3 * data['fzyz']return datadef solve_data(self):self.data = QA.QA_fetch_stock_day_adv(self.stock_pool, self.start_time, self.stop_time)self.ind = self.data.add_func(self.three_para)def run(self):self.solve_data()print(self.ind)for items in self.data.panel_gen:today_time = items.index[0][0]one_day_data = self.ind.loc[today_time]      # 得到有包含因子的DataFrameone_day_data['date'] = items.index[0][0]one_day_data.reset_index(inplace=True)one_day_data.sort_values(by='decided_para', axis=0, ascending=False, inplace=True)today_stock = list(one_day_data.iloc[0:self.n_stock]['code'])one_day_data.set_index(['date', 'code'], inplace=True)one_day_data = QA.QA_DataStruct_Stock_day(one_day_data)  # 转换格式,便于计算bought_stock_list = list(self.Account.hold.index)print("SELL:")for stock_code in bought_stock_list:# 如果直接在循环中对bought_stock_list操作,会跳过一些元素if stock_code not in today_stock:try:item = one_day_data.select_day(str(today_time)).select_code(stock_code)order = self.Account.send_order(code=stock_code,time=today_time,amount=self.Account.sell_available.get(stock_code, 0),towards=QA.ORDER_DIRECTION.SELL,price=0,order_model=QA.ORDER_MODEL.MARKET,amount_model=QA.AMOUNT_MODEL.BY_AMOUNT)self.Broker.receive_order(QA.QA_Event(order=order, market_data=item))trade_mes = self.Broker.query_orders(self.Account.account_cookie, 'filled')res = trade_mes.loc[order.account_cookie, order.realorder_id]order.trade(res.trade_id, res.trade_price, res.trade_amount, res.trade_time)except Exception as e:print(e)print('BUY:')for stock_code in today_stock:try:item = one_day_data.select_day(str(today_time)).select_code(stock_code)order = self.Account.send_order(code=stock_code,time=today_time,amount=1000,towards=QA.ORDER_DIRECTION.BUY,price=0,order_model=QA.ORDER_MODEL.CLOSE,amount_model=QA.AMOUNT_MODEL.BY_AMOUNT)self.Broker.receive_order(QA.QA_Event(order=order, market_data=item))trade_mes = self.Broker.query_orders(self.Account.account_cookie, 'filled')res = trade_mes.loc[order.account_cookie, order.realorder_id]order.trade(res.trade_id, res.trade_price, res.trade_amount, res.trade_time)except Exception as e:print(e)self.Account.settle()Risk = QA.QA_Risk(self.Account)print(Risk.message)# plt.show()Risk.assets.plot()  # 总资产plt.show()Risk.benchmark_assets.plot()  # 基准收益的资产plt.show()Risk.plot_assets_curve()  # 两个合起来的对比图plt.show()Risk.plot_dailyhold()  # 每只股票每天的买入量plt.show()start = time.time()
sss = ThreePara('2017-01-01', '2018-01-01', 10)
stop = time.time()
print(stop - start)
print(len(sss.stock_pool))
sss.run()
stop2 = time.time()
print(stop2 - stop)

[QUANTAXIS量化分析]三因素模型相关推荐

  1. [QUANTAXIS量化分析]羊驼策略1

    羊驼策略1 基本原理 在本策略中,每天按照收益率从小到大对股票池中的所有股票进行排序,起始时买入num_of_stocks只股票,然后每天在整个股票池中选出收益率前num_of_stocks,如果这些 ...

  2. garch预测 python_【2019年度合辑】手把手教你用Python做股票量化分析

    引言 不知不觉,2019年已接近尾声,Python金融量化公众号也有一年零两个月.公众号自设立以来,专注于分享Python在金融量化领域的应用,发布了四十余篇原创文章,超过两万人关注.这一路走来,有过 ...

  3. #让我们用python跑回归#Fama-French三因素模型(一)

    先简单介绍一下尤金·法玛: 尤金·法玛(Eugene F. Fama),著名经济学家.金融经济学领域的思想家,芝加哥经济学派代表人物之一.芝加哥大学教授,2013年诺贝尔经济学奖得主. 1990年代初 ...

  4. python量化分析招聘_怎么准备国内量化分析师岗位的面试?

    既然是面试,那么面试就有很多常规的准备工作,可以参考:面试前你都做了什么准备? - 知乎 对于量化分析师,有如下几点可以注意:岗位职责 招人肯定是希望能够干活,能干好活,所以你应该重视招聘内容里面的岗 ...

  5. python 量化分析 入门_【合辑·收藏】Python量化从入门到精通

    原标题:[合辑·收藏]Python量化从入门到精通 引言 自2018年9月27日发第一篇推文以来,公众号"Python金融量化"专注于分享Python在金融量化领域的实战应用,坚持 ...

  6. TensorRT-8量化分析

    TensorRT-8量化分析 本文讲非对称量化.量化方式等等一些细节,不过有一段时间在做基于TensorRT的量化,需要看下TensorRT的量化细节.这次文章是偏实践的一篇,主要过一下TensorR ...

  7. 从直觉主义到量化分析 让大数据做主

    文章讲的是从直觉主义到量化分析 让大数据做主,还记得去年8·15电商竞争价格大战吗?如果你是某电商CEO,你还会采用这样的竞争战略吗?变化是永恒的主题,企业管理不能一成不变.在大数据时代,电商采用价格 ...

  8. 【Python金融量化 2- 100 】股票量化分析基本知识

    Author:Runsen 文章目录 什么是股票 什么是量化分析 股票代码 K线图 tushare的抓取数据 pandas_datareader 什么是股票 股票(stock)是股份公司发行的所有权凭 ...

  9. 阿里云Lindorm联合智臾科技发布,金融高频交易数据量化分析与处理方案

    简介:面向银行.保险.券商和私募的高频数据高性能一站式解决方案. 金融市场L1/L2的报价和交易数据是量化交易研究非常重要的数据,随着数字业务快速演进,具有时序特征的交易数据激增,对底层数据库和量化分 ...

最新文章

  1. HDU3434数学题
  2. Tensor for ‘out‘ is on CPU, Tensor for argument #1 ‘self‘ is on CPU
  3. 朴素贝叶斯分类器(Navie Bayesian Classifier)中的几个要点(一)
  4. java实现对properties类型文件的读写
  5. python课程设计
  6. html ul高度自适应,如何让div中的ul元素自适应
  7. Adobe AIR移动App的互相调用实现方式
  8. 调用 WebService 请求因 HTTP 状态 407 失败
  9. 还原真实的 cache recovery
  10. PyCharm中的一些设置
  11. MATLAB神经网络应用之Elman神经网络
  12. MIMOl信道估计基本原理
  13. linux 更新包缓存目录,清除ubuntu下缓存、软件安装包和多余内核
  14. analyze 命令
  15. 一文教你如何在Linux系统上搭建samba文件共享服务器
  16. 【2019.05】python 爬取拉钩数据(静态+动态)
  17. memcacheredis构建缓存服务器
  18. app 服务器维护通知,启用 App Store 服务器通知
  19. 基于Python和TensorFlow的AI作曲的设计与实现
  20. 什么是客户终身价值(LTV)

热门文章

  1. 每天学点统计学——频率和累计频数
  2. vr全景系统平台哪家好, vr全景是什么?
  3. 关于Mac电脑UTF8转码的问题
  4. DETR、conditional DETR、Deformable DETR
  5. 51nod 1238 最小公倍数之和 V3
  6. 运算库之numpy(数组的切片操作和数组shape的转换)
  7. 智慧档案室改造建设方案 - 一站式建设智慧档案馆建设方案
  8. 架构 | 如何从零开始搭建高性能直播平台?
  9. OpenGL学习笔记(七)-深度测试-模板测试-混合
  10. 学好计算机的用途,学电脑的用途是什么