利用 Python 实现格雷厄姆价值投资

2017-07-11 16:42:48 +08:00
 OceanCafe
### **Life is short,I use python to invest..囧**
### **今天给大家分享

![alt text]( https://dn-ricequant.qbox.me/forum/upload-66e71217-1351-4dfd-ba5b-923d3d554a67.jpg)

这个 22.5 是怎么来的呢?取自他的观点 -只买便宜的,投资 15 倍以下 pe 和 1.5 倍以下 pb 的股票。

著名的 Graham number 适用于 Defensive investor (防御型投资者),既然是防御保守型的投资者,那么除了较低的 PE 和 PB ratio 以外,还需要考察一个超经典的价值投资策略**

Benjamin Graham 是一位价值投资者。他比较有名的有 Graham number 和 Graham formula。

### **著名的 Graham number 公式**公司的其他几个方面(不然就选到垃圾股了)

抗风险的大公司,高市值,高销售

偿债能力,不会有破产风险 current ratio>2, long term debt<working captial

赚钱能力,利润持续增长

**PE ratio < 15**

**PB ratio <1.5**

这是价值投资的一个大概思路。每个月调仓一次。看下来中长期的投资回报还是相对稳健的。有兴趣的同学可以尝试修改完善。


### 这是收益图
![alt text]( https://alicdn.ricequant.com/upload/b1/b9ae956b997775b69e3bbfc62e797eb1.png)

### 这是源码
源码在 <a herf="www.ricequant.com">Ricequant</a>实现

```
# 可以自己 import 我们平台支持的第三方 python 模块,、numpy 等。
import pandas as pd
import numpy as np
import datetime
import math

# 在这个方法中编写任何的初始化逻辑。context 对象将会在你的算法策略的任何方法之间做传递。
def init(context):


scheduler.run_monthly(rebalance,8)



# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):

pass

def before_trading(context):
num_stocks = 10

#删选股票
fundamental_df = get_fundamentals(
query(
fundamentals.eod_derivative_indicator.pb_ratio,
fundamentals.eod_derivative_indicator.pe_ratio,
fundamentals.financial_indicator.inc_earnings_per_share,
fundamentals.financial_indicator.inc_profit_before_tax,
fundamentals.financial_indicator.quick_ratio,
fundamentals.financial_indicator.earnings_per_share,
fundamentals.financial_indicator.book_value_per_share,
)
.filter(
fundamentals.eod_derivative_indicator.pe_ratio<15
)
.filter(
fundamentals.eod_derivative_indicator.pb_ratio<1.5
)
.filter(
fundamentals.financial_indicator.inc_earnings_per_share>0
)
.filter(
fundamentals.financial_indicator.inc_profit_before_tax>0
)
.filter(
fundamentals.financial_indicator.current_ratio>2
)
.filter(
fundamentals.financial_indicator.quick_ratio>1
)
.order_by(
fundamentals.eod_derivative_indicator.market_cap.desc()
).limit(
num_stocks
)
)



context.fundamental_df = fundamental_df
context.stocks = context.fundamental_df.columns.values



def rebalance(context,bar_dict):

#调仓
for stock in context.portfolio.positions:
if stock not in context.fundamental_df:
order_target_percent(stock, 0)



weight = update_weights(context, context.stocks)

for stock in context.fundamental_df:
if weight != 0 and stock in context.fundamental_df:
order_target_percent(stock,weight)


def update_weights(context,stocks):
if len(stocks) == 0:
return 0
else:

weight = .95/len(stocks)
return weight
```
1836 次点击
所在节点    Python
1 条回复
4ever911
2017-07-11 20:11:46 +08:00
life is short, so please don't spam here.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/374552

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX