單因子PEG選股策略


導語

彼得 林奇的PEG策略:
投資大師彼得·林奇(Peter Lynch)有過一個著名的論斷:任何一家公司股票如果定價合理的話,市盈率就會與收益增長率相等

PEG概念解析

  1. EPS(Earnings Per Share)表示每股收益(一般按年計算)
EPS = \frac{increment per year}{stocknumbers}
  1. PE(Price to Earning Ratio)表示市盈率,是當前股價(P)相對每股收益(EPS)的比值:
PE = \frac{P}{EPS}

市盈率反映的是股票的投資回報能力,市盈率越低,代表股票的價值越低或者股票的每股收益更高

  1. G(Growth Rate of Expected Profit)表示企業的收益增長率:
G = \frac{EPS_{this year}-EPS_{last year}}{EPS_{last year}}
  1. PEG計算公式:
PEG = \frac{PE}{G*100}

將公式變換一下可以得到:

PEG = \frac{1}{100}*P*\frac{EPS_{last year}}{(EPS_{this year}-EPS_{last year})*EPS}

上面的式子表明PEG和股價成正相關,所以PEG越高表明股價有被高估的可能,相反則表明股價有被低估的可能,可以考慮買入

PEG的原理很簡單,並不是一個很復雜的策略,市盈率低代表該公司要么股價低要么盈利能力強,而收益增長率高則代表該公司的盈利能力強,如果在這個時候該公司的具有較低的市盈率則表明該公司的股價已經被嚴重低估,所以按照PEG策略的思想,PEG的值越低越好


PEG策略雖然簡單並且比較符合理論情況,但是在實際使用過程中得到的效果並不是十分的出色,這里面主要有兩個原因:1.公司的盈利能力不能簡單的預測,可能今年公司盈利能力很強,但是第二年公司就出現盈利大幅下滑;2.這個策略只是一個簡單的單因子選股擇時策略,而且沒有倉位控制和止損策略相配合,在市場環境較差的時候公司的基本面並不能和股價相配合,所以該策略對熊市的抵御能力較差


PEG策略源碼

import pandas as pd
"""
----------------------------
回測前
----------------------------
"""
def initialize(context):
    set_params()
    set_variables()
    set_backtest()

def set_params():
    g.tc = 15
    g.num_stocks = 10
    
def set_variables():
    g.days = 0
    g.if_trade = False

def set_backtest():
    set_option('use_real_price',True)
    log.set_level('order','error')
"""
----------------------------
開盤前
----------------------------
""" 
def before_trading_start(context):
    if g.days%g.tc == 0:
        g.if_trade = True
        set_slip_fee(context)
        g.stocks = get_index_stocks('000300.XHSG')
        g.feasible_stocks = set_feasible_stocks(g.stocks,context)
    g.days += 1

def set_feasible_stocks(initial_stocks,context):
    paused_info = []
    current_data = get_current_data()
    for i in initial_stocks:
        paused_info.append(current_data[i].paused)
    df_paused_info = pd.DataFrame({'paused_info':paused_info},index = initial_stocks)
    unsuspened_stocks =list(df_paused_info.index[df_paused_info.paused_info == False])
    return unsuspened_stocks

def set_slip_fee(context):
    set_slippage(FixedSlippage(0))
    dt = context.current_dt
    if dt>datetime.datetime(2013,1,1)
    set_commission(PerTrade(buy_cost=0.0003,sell_cost=0.0013,min_cost=5))
    elif dt>datetime.datetime(2011,1, 1):
        set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5))
            
    elif dt>datetime.datetime(2009,1, 1):
        set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5))
    else:
        set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5))
"""
----------------------------
每天交易時
----------------------------
"""  
#每天回測時做的事情
def handle_data(context,data):
    #1.如果當天可以買入則列出待買入的股票和待賣出的股票
    #2.進行買入和賣出操作
    #3.設置可買入狀態為False
    if g.if_trade == True:
        list_to_buy = stocks_to_buy(context)
        list_to_sell = stocks_to_sell(context,list_to_buy)
        sell_operation(list_to_sell_       buy_operation(context,list_to_buy)
    g.if_trade = False
    
# 1.獲得PEG值列表
# 2.獲得買入信號
# 3.獲得賣出信號

def get_PEG(context,stock_list):
    PEG_query = query(valuation.code,valuation.pe_ratio,indicator,inc_net_profit_year_on_year).filter(valuation.code.in_(stock_list))
    df = get_fundamentals(PEG_query)
    df_growth = df[(df.pe_ration>0)&df.inc_net_profit_year_on_year>0)]
    df_growth.dropna()
    series_PE = df_growth.ix[:,'pe_ratio']
    series_G = df_growth.ix[:,'inc_net_profit_year_on_year']
    series_PEG = series_PE/series_G
    series_PEG.index = df_growth.ix[:,0]
    df_PEG = pd.DataFrame(series_PEG)
    return df_PEG
    
def stocks_to_buy(context):
    list_to_buy = []
    df_PEG = get_PEG(context,g.feasible_stocks)
    df_sorted_PEG = df_PEG.sort(columns='series_PEG',ascending=[1])
    for i in range(g.num_stocks):
        if df_sort_PEG.ix[i,0] < 0.5:
        list_to_buy.append(df_sort_PEG.index[i])
    return list_to_buy
    
def stocks_to_sell(context,list_to_buy):
    list_to_sell=[]
    for stock_sell in context.portfolil.positions:
    if stock_sell not in list_to_buy:
        list_to_sell.append(stock_sell)
    return list_to_sell
    
def sell_operation(list_to_sell):
    for stock_sell in list_to_sell:
        order_target_value(stock_sell,0)

def buy_operation(context,list_to_buy):
    for stock_sell in list_to_buy:
    g.capital_unit = context.portfolio.portfolil_value/len(list_to_buy)
    for stock_buy in list_to_buy:
        order_target_value(stock_buy,g.capital_unit)
        
"""
----------------------------
每天收盤后
----------------------------
"""  
def after_trading_end(context):
    return

上面的策略很簡單,具體步驟可以看下表:

時間 操作1 操作2 操作3
回測前 初始化參數 初始化變量 初始化變量
開盤前 設置調倉信息 設置可選股票 設置滑點和手續費
交易時 獲得PEG表 獲取買入和賣出stock_list 進行買入和賣出操作
收盤后


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM