暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

积极投资法与史蒂夫•路佛价值选股法

量化分析之路 2020-04-06
889


一:积极投资法

格雷厄姆在《聪明的投资者》“积极型投资者”的六条选股标准

1.股票的市盈率低于市场水平

2.股票的市净率小于1.2

3.企业的流动比率要大于1.5

4.企业总借款不超过流动资产与总资产太多

5.最近5年净利润均大于零

6.利润増长处于较高水平

    这其中有部分条件 对A股市场不太适用 。比如中国涨的好的股票市盈率和市净率都比较高。有很多科技股是部分年份亏损的。

根据中国市场的实践,对部分参数进行修改:得到一个简单策略

1 股票的市盈率高于市场平均水平

2 股票的市净率小于3

3 企业的流动比率要大于1.1

流动比率(Current ratio),计算方法:流动比率=流动资产合计/流动负债合计。属于质量类因子

4 企业长期负债与营运资金比率不超过5

长期负债与营运资金比率(Long term debt to working capital)。计算方法:长期负债与营运资金比率=非流动负债合计/(流动资产合计-流动负债合计)。属于质量类因子

5 利润増长处于较高水平:大于80%的股票

•买入条件:满足中国市场规则,则买入

•卖出条件:不满足中国市场规则有持仓,则卖出

def stock_sellection_Graham_positive_stock(context):
'''股票的市盈率高于市场平均水平
股票的市净率小于3
企业的流动比率要大于1.1
企业的长期负债 与营运资金(流动资产-流动负债)比率不超过5
利润増长处于较高水平:大于80%的股票 '''
    previous_date = context.previous_date
account = context.get_account('fantasy_account')
current_universe = context.get_universe( exclude_halt=True)

#获取因子 5年收益增长率 收盘价 稀释每股收益
data = DataAPI.MktStockFactorsOneDayGet(tradeDate=previous_date, secID=universe,
field=['secID','tradeDate','PE','PB','CurrentRatio','LongDebtToWorkingCapital','NetProfitGrowRate'], pandas='1')


data = data.dropna()

#数据处理部分 #neg 流通市值
data = data[(data.PB<3) & (data.PB)>0 &(data.PE > data.PE.quantile(0.9)) & (data.CurrentRatio>1.1) & (data.LongDebtToWorkingCapital < 5)
&(data.NetProfitGrowRate >data.NetProfitGrowRate.quantile(0.9))]
log.info(data)
buy_list = data['secID'].tolist()

print type(buy_list)

return list(buy_list)


跑了下15年 牛市和股灾的回测  跑赢大盘20个点 还可以 调仓频率 较少  


二  史蒂夫•路佛投资法

 这个人也是一个比较牛逼的人  具体多牛我就不在这讲了 。他的选股法则

史蒂夫•路佛价值选股法则如下:

1 市净率低于全市场平均值的80%且小于1.5

2 以五年平均盈余计算的PE低于全市场平均值的70%且小于12

3 每股现金至少是股价的15%    现金流

4 股息收益率不低于全市场平均值且不低于3%

5 股价现金流量比 低于 全市场平均值的75%

6 长期借款加未提拨退休金负债占总资本比率低于50%    负债比

7 流动比率高于全市场平均值   (偿还短期负债能力)

•结合中国实际情况后,原始标准调整如下:

1 市净率低于全市场均值的80%

2 五年平均盈余计算的PE高于全市场平均值的70%

5年平均收益市值比(Five-year average earnings to price)。计算方法:5年平均收益市值比=近五年净利润(TTM)/近五年总市值

3 不考虑股息收益率因素(中国股利的派发情况稀少)

4 股价现金流量比低于全市场平均值的75%

5 长期借款占总资本比率低于50%

6 流动比率高于全市场均值


满足 买入  

买入后有持仓  股价涨到不满足 卖出。


Current ratio = Current assets / Current liabilities    流动资产 / 流动负债)

 

Quick ratio

=[cash + marketable securities + receivable] / Current liabilities

=[current asset - inventories] / Current liabilities

 

=【现金+有价证券+应收款项】/流动负债

=[流动资产-存货]/流动负债


Cash ratio

=[cash + marketable securities] / Current liabilities


第一部分 准备工作

import numpy as np
import pandas as pd
import talib
import datetime


start = '2015-01-01' # 回测起始时间
end = '2016-01-01' # 回测结束时间
universe = DynamicUniverse('A') # 证券池,支持股票、基金、期货、指数四种资产
benchmark = 'HS300' # 策略参考标准
freq = 'd' # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 10 # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟

# 配置账户信息,支持多资产多账户
accounts = {
'fantasy_account': AccountConfig(account_type='security', capital_base=10000000)
}


##每只股票买入卖出阈值
Max_Position = 1000000


def initialize(context):
pass


def handle_data(context):
buy_list = stock_sellection_steve_stock(context)
trading(buy_list,context)


第二部分 选股 

def stock_sellection_steve_stock(context):
previous_date = context.previous_date
account = context.get_account('fantasy_account')
previous_date = previous_date.strftime('%Y%m%d')
current_universe = context.get_universe( exclude_halt=True)
security_position = account.get_positions()
SV_factor = DataAPI.MktStockFactorsOneDayGet(tradeDate=previous_date, secID=current_universe, field=['secID','PB','ETP5','PCF','CurrentRatio','LongDebtToAsset'], pandas='1')
SV_factor = SV_factor.dropna()
SV_factor = SV_factor.set_index(['secID'])

SV_factor = SV_factor[SV_factor['PCF']>0] #去掉现金流负的企业

# ETP5 5年平均收益市值比(Five-year average earnings to price)。计算方法:5年平均收益市值比=近五年净利润(TTM)/近五年总市值。属于价值类因子。数据更新时间:T日21点30分。
# PCF 市现率(Price-to-cash-flow ratio)。计算方法:总市值/经营活动产生的现金流量净额(TTM)
#长期借款与资产总计之比(Long term loan to total assets)。计算方法:长期借款与资产总计之比=长期借款/总资产
#流动比率(Current ratio),计算方法:流动比率=流动资产合计/流动负债合计。属于质量类因子
SV_factor = SV_factor[(SV_factor['ETP5']>0.7*SV_factor['ETP5'].mean()) &(SV_factor['PCF']<0.75*SV_factor['PCF'].mean())& (SV_factor['LongDebtToAsset']<0.5) &
(SV_factor['PB']< 0.8*SV_factor['PB'].mean()) & (SV_factor['CurrentRatio'] >SV_factor['CurrentRatio'].mean())]

print(type(SV_factor))
buy_list = SV_factor.index
print(type(SV_factor))
print(SV_factor)


return list(buy_list)

第三部分 操作买入卖出 在这 多说一句  就是在策略中有单个股的持仓上限 为总资产的1/10   最多持仓为10个股 

d = min(len(buy_list),int(cash)//Max_Position)

在buy_list 与 cash//max_positon选择较小的那个数字 即最多只买10只股票。

def trading(buy_list,context):
account = context.get_account('fantasy_account')
current_universe = context.get_universe( exclude_halt=True)
security_position = account.get_positions()
cash = account.cash

for sec in current_universe:
if sec not in buy_list and sec in security_position:
account.order_to(sec,0)
cash += security_position[sec].amount * context.current_price(sec)

d = min(len(buy_list),int(cash)//Max_Position)
for sec in buy_list[:d]:
if sec not in security_position:
account.order(sec,Max_Position/ context.current_price(sec))




     跑了下15年的 牛市和股灾的回撤  跑赢沪深300 60个点 很牛逼

    跑了下 19年-20年的回测 也小幅跑赢大盘

调仓记录也不频繁  不错不错。

文章转载自量化分析之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论