ls-2018

量化策略

 

 

双均线策略:

择时
# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context):
    # 设定沪深300作为基准
    set_benchmark(\'000300.XSHG\')
    # 开启动态复权模式(真实价格)
    set_option(\'use_real_price\', True)
    
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level(\'order\', \'error\')
    
    ### 股票相关设定 ###
    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    
    g.security = [\'601318.XSHG\',]
    g.p1 = 5
    g.p2 = 60
    
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    for stock in g.security:
        # 金叉:如果5日均线大于10日均线并且不持仓
        # 死叉:如果5日均线小于10日均线并且持仓
        
        df = attribute_history(stock,g.p2)
        ma10 = df[\'close\'].mean()
        ma5 = df[\'close\'][-5:].mean()
        
        if ma10 > ma5 and stock in context.portfolio.positions:
            # 死叉
            order_target(stock,0)
        if ma10 < ma5 and stock not in context.portfolio.positions:
            # 金叉
            order(stock,context.portfolio.available_cash * 0.8)
    record(ma5=ma5,ma10=ma10)

  

 因子选股策略

因子:选择股票的某种标准
  增长率、市值、市盈率、ROE(净资产收益率)
选股策略
  对于某个因子,选取表现最好的N只股票持仓
  每隔一段时间调仓一次
小市值策略:选取股票池中市值最小的N只股票持仓

 

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000002.XSHG\') 
    set_option(\'use_real_price\', True) 
    log.set_level(\'order\', \'error\')
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000002.XSHG\') 
    
    g.q = query(valuation).filter(valuation.code.in_(g.security))# valuation表
    g.N = 20
    # g.days = 0
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass


def handle_(context):
    df = get_fundamentals(g.q)[[\'code\',\'market_cap\']]# 查询数据
    df = df.sort(\'market_cap\').iloc[:g.N,:]# 0.16.2 版本, # 获取沪深300以总市值排序
    
    to_hold = df[\'code\'].values
    for stock in context.portfolio.positions:
        if stock not in to_hold:
            order_target(stock,0)# 卖出
    
    
    to_buy = [stock for stock in to_hold if stock not in context.portfolio.positions]
    if len(to_buy)>0:
        cash_per_stock = context.portfolio.available_cash/len(to_buy)
        for stock in to_buy:
            order_value(stock,cash_per_stock) # 买

    
"""
get_current_data 
    last_price : 最新价
    high_limit: 涨停价
    low_limit: 跌停价
    paused: 是否停止或者暂停了交易, 当停牌、未上市或者退市后返回 True
    is_st: 是否是 ST(包括ST, *ST),是则返回 True,否则返回 False
    day_open: 当天开盘价
    name: 股票现在的名称, 可以用这个来判断股票当天是否是 ST, *ST, 是否快要退市
"""

多因子选股策略


因子:选择股票的某种标准
  增长率、市值、市盈率、ROE(净资产收益率)
选股策略
  对于某个因子,选取表现最好的N只股票持仓
  每隔一段时间调仓一次
小市值策略:选取股票池中市值最小的N只股票持仓

如何同时综合多个因子来选股? 评分模型:   每个股票针对每个因子进行评分,将评分相加   选出总评分最大的N只股票持仓   如何计算股票在某个因子下的评分:归一化(标准化) github/book/有

 

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000002.XSHG\') 
    set_option(\'use_real_price\', True) 
    log.set_level(\'order\', \'error\')
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000002.XSHG\') 
    
    g.q = query(valuation,indicator).filter(valuation.code.in_(g.security))# valuation表
    g.N = 20
    # g.days = 0
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass


def handle_(context):
    df = get_fundamentals(g.q)[[\'code\',\'market_cap\',\'roe\']]# 查询数据
    # 0-1归一化
    df[\'market_cap\']=(df[\'market_cap\']-df[\'market_cap\'].min())/(df[\'market_cap\'].max()-df[\'market_cap\'].min())
    df[\'roe\'] = (df[\'roe\']-df[\'roe\'].min())/(df[\'roe\'].max()-df[\'roe\'].min())
    df[\'score\'] = df[\'roe\'] - df[\'market_cap\'] # 可以加权重 # 净资产收益率 - 总市值(亿元)  #  已经归一化
    
    df = df.sort(\'score\').iloc[-g.N:,:]# 0.16.2 版本, # 获取沪深300以总市值排序
    
    to_hold = df[\'code\'].values
    for stock in context.portfolio.positions:
        if stock not in to_hold:
            order_target(stock,0)# 卖出
    
    
    to_buy = [stock for stock in to_hold if stock not in context.portfolio.positions]
    if len(to_buy)>0:
        cash_per_stock = context.portfolio.available_cash/len(to_buy)
        for stock in to_buy:
            order_value(stock,cash_per_stock) # 买

 均值回归理论讲解  (选股策略)

均值回归:跌下去的迟早要涨上来
均值回归的理论基于以下观测:价格的波动一般会以它的均线为中心。也就是说,当标的价格由于波动而偏离移动均线时,他将调整并重新归于均线。(破产除外))
定义偏离程度(MA-P)/MA
均值回归策略 :在每个调仓日进行
  计算股票池中所有股票的N日均线
  计算股票池中所有股票与均线的偏离度
  选取偏离度最高的M只股票并调仓

 

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000002.XSHG\') 
    set_option(\'use_real_price\', True) 
    log.set_level(\'order\', \'error\')
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000002.XSHG\') 
    
    
    g.ma_days = 30
    g.stock_num = 10
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass


def handle_(context):
    
    sr = pd.Series(index=g.security)
    for stock in sr.index:
        ma = attribute_history(stock,g.ma_days)[\'close\'].mean() # 30日均线
        p = get_current_data()[stock].day_open
        ratio = (ma-p)/ma
        sr[stock] = ratio
    tohold = sr.nlargest(g.stock_num).index # 和sort一样,速度更快
    # print(tohold)    
        
    
    to_hold = tohold
    for stock in context.portfolio.positions:
        if stock not in to_hold:
            order_target(stock,0)# 卖出
    
    
    to_buy = [stock for stock in to_hold if stock not in context.portfolio.positions]
    if len(to_buy)>0:
        cash_per_stock = context.portfolio.available_cash/len(to_buy)
        for stock in to_buy:
            order_value(stock,cash_per_stock) # 买

布林带策略  

布林带/布林线/保利加通道 (Bollinger Band): 由三条轨道线组成,其中上下两条线分别可以看成是价格的压力线和支撑线,在两条线之间是一条价格平均线

计算公式:
  中间线 = 20日均线
  up线 = 20日均线 + N*SD(20日收盘价)
  down线 = 20日均线 - N*SD(20日收盘价)
布林带策略: 择时
  当估价突破阻力线时,清仓
  当估价跌破支撑线时,全仓买入
布林带策略研究:N的取值问题,布林带宽度等。
# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000300.XSHG\') 
    set_option(\'use_real_price\', True) 
    log.set_level(\'order\', \'error\')
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = \'600036.XSHG\' 
    g.M = 20
    g.k = 2

# 初始化此策略
def handle_data(context, data):
    sr = attribute_history(g.security,g.M)[\'close\']
    ma = sr.mean()
    up = ma + g.k * sr.std()
    down = ma -g.k * sr.std()
    p = get_current_data()[g.security].day_open
    cash = context.portfolio.available_cash
    
    if p < down and g.security not in context.portfolio.positions:
        order_value(g.security,cash)
    elif p > up and g.security in context.portfolio.positions:
        order_target(g.security,0)

  

 

 

PEG策略

 

任何一家公司股价如果定价合理的话,市盈率就会与收益增长率相等 
市盈率 (PE) = 股价(p)/每股收益(eps)
市盈率 ≈ 市值/净收益

例如: 有一家包子铺,每年净收益为50万元,收益价格(市值)为100万元;
    有一家家具店,每年净利润为100万元,市值为1000万元

每股收益(EPS)
估价(P)
市盈率(PE) = P/EPS
收益增长率(G) = (EPSi - EPSi-1) /EPSi-1
PEG = PE/(g*100)

pe越低,代表股价被低估的可能性越大,估价会涨的可能性越大
peg是一个综合指标,既考察价值,又兼顾成长性。peg估值法是应用成长型公司。

 

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000002.XSHG\') 
    set_option(\'use_real_price\', True) 
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000002.XSHG\') 
    
    g.q = query(valuation.code,valuation.pe_ratio,indicator.inc_net_profit_year_on_year).filter(valuation.code.in_(g.security))# valuation表
    g.N = 20
    # g.days = 0
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass


def handle_(context):
    df = get_fundamentals(g.q)# 查询数据
    
    df = df[(df[\'pe_ratio\']>0)&(df[\'inc_net_profit_year_on_year\']>0)]
    df[\'peg\'] = df[\'pe_ratio\']/df[\'inc_net_profit_year_on_year\']/100
    df = df.sort(columns=[\'peg\'])
    to_hold = df[\'code\'][:g.N].values  #  先取列,在取行
    print(to_hold)
    
    # 0-1归一化
    # df[\'market_cap\']=(df[\'market_cap\']-df[\'market_cap\'].min())/(df[\'market_cap\'].max()-df[\'market_cap\'].min())
    # df[\'roe\'] = (df[\'roe\']-df[\'roe\'].min())/(df[\'roe\'].max()-df[\'roe\'].min())
    # df[\'score\'] = df[\'roe\'] - df[\'market_cap\'] # 可以加权重 # 净资产收益率 - 总市值(亿元)  #  已经归一化
    
    # df = df.sort(\'score\').iloc[-g.N:,:]# 0.16.2 版本, # 获取沪深300以总市值排序
    
    # to_hold = df[\'code\'].values
    for stock in context.portfolio.positions:
        if stock not in to_hold:
            order_target(stock,0)# 卖出
    
    
    to_buy = [stock for stock in to_hold if stock not in context.portfolio.positions]
    if len(to_buy)>0:
        cash_per_stock = context.portfolio.available_cash/len(to_buy)
        for stock in to_buy:
            order_value(stock,cash_per_stock) # 买

  

 动量策略&反转策略

动量策略:如果某只股票在前一段时期表现较好,那么下一段时期该股票扔有良好表现
反转策略:如果某只股票在前一段时期表现不好,那么下一段时期该股票将会反转,即表现变好


计算股票池中所有股票在前一段时间的收益率
选择收益率最大(最小的)N只股票调仓

 

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    
    set_option(\'use_real_price\', True) 
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000002.XSHG\') 
    
    g.benchmark = \'000300.XSHG\'
    set_benchmark(g.benchmark) 
    
    g.N = 10
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass


def handle_(context):
    stocks = get_index_stocks(\'000300.XSHG\')
    
    df_close = history(30,field=\'close\',security_list=list(stocks)).T
    df_close[\'ret\'] = (df_close.iloc[:,-1]-df_close.iloc[:,0])/df_close.iloc[:,0]
    sorted_stocks = df_close.sort(\'ret\',ascending=False).index
    
    to_hold = sorted_stocks[:g.N]
    for stock in context.portfolio.positions:
        if stock not in to_hold:
            order_target(stock,0)# 卖出
    
    
    to_buy = [stock for stock in to_hold if stock not in context.portfolio.positions]
    
    if len(to_buy)>0:
        cash = context.portfolio.available_cash 
        cash_per_stock = cash / len(to_buy)
        
        for stock in to_buy:
            order_value(stock,cash_per_stock) # 买

  

 羊驼法则

 

买入历史收益最低的N只股票,调仓日留下反转程度大的股票,卖掉表现最差的M只股票,再买入收益率最低的M只股票。
  
起始时随机买入N只股票,每天卖掉收益率最差的M只,在随机买入剩余股票池的M只
随机选股,随机调仓

 

 

 

from jqdata import *

# 初始化函数,设定基准等等
def initialize(context): 
    set_benchmark(\'000300.XSHG\') 
    set_option(\'use_real_price\', True) 
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type=\'stock\')
    g.security = get_index_stocks(\'000300.XSHG\') 
    g.period = 30
    g.change = 1
    g.init = True
    g.N = 10
    run_monthly(handle_,1)# 每月第一个交易日
 
def handle_data(context, data):
    # print(get_current_data()[\'601318.XSHG\'].day_open)
    # print(attribute_history(\'601318.XSHG\',5)) 
    # order(\'601318.XSHG\',100)
    # order_value(\'601318.XSHG\',10000)
    
    pass

def get_sorted_stocks(context,stocks):
    df = history(g.period,field=\'close\',security_list=stocks).T
    df[\'ret\'] = (df.iloc[:,len(df.columns)-1]-df.iloc[:,0])/df.iloc[:,0]
    df = df.sort(columns=\'ret\',ascending=False)
    return df.index.values
    
    
def handle_(context):
    if g.init:
        stocks = get_sorted_stocks(context,g.security)[:g.N]
        cash = context.portfolio.available_cash * 0.9/len(stocks)
        for stock in stocks:
            order_value(stock,cash)
        g.init = False
        return
    
    stocks = get_sorted_stocks(context,context.portfolio.positions.keys())[:g.N]
    
   
    for stock in stocks[-g.change:]:
        order_target(stock,0)# 卖出
    
    
    stocks = get_sorted_stocks(context,g.security)
    
    for stock in stocks:
        if len(context.portfolio.positions) >= g.N:
            break
        if stock not in context.portfolio.positions:
            order_value(stock,context.portfolio.available_cash * 0.9)

  

 

分类:

技术点:

相关文章:

  • 2021-08-04
  • 2021-12-24
  • 2021-11-20
  • 2021-08-31
  • 2021-06-14
  • 2021-11-22
  • 2022-12-23
猜你喜欢
  • 2021-07-20
  • 2021-11-20
  • 2021-07-26
  • 2021-12-13
  • 2021-12-23
  • 2021-12-01
相关资源
相似解决方案