布林带策略

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

计算公式:

中间线 = 20日均线

up线 = 20日均线 + N*SD(20日收盘价)

down线 = 20日均线 - N*SD(20日收盘价)

(N通常2倍,SD价格的标准差)

#聚宽Boll逢高轨卖出,逢低轨买入策略代码
from jqdata import *

def initialize(context):    #初始化
    #设置基准
    set_benchmark('000300.XSHG')
    
    #设置复权,使用真实价格
    set_option('use_real_price',True)
    
    #设置订单成本cost(close_tax印花税,open_commission买入佣金,close_commission卖出佣金,min_commission最小佣金5元,type类型选择股票)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003,min_commission=5), type='stock')
    
    #设置security证券标的
    g.security = ['600036.XSHG']
    g.N = 2     #2倍
    g.ma_days20 = 20        #20天
    
    
def handle_data(context,data):      #handle句柄表示对象,默认每天调用一次
    cach = context.portfolio.available_cash     #可获得的现金
    
    for stock in g.security:
    #获取往前20天的收盘价--计算出BOLL的上中下轨道--判断是否突破上下轨道,突破卖出,下破买入
        price_days20 = attribute_history(stock,20)['close']
        middle = price_days20.mean()
        upper = middle + g.N * price_days20.std()
        lower = middle - g.N * price_days20.std()
        
        #获得现在current时间股票价格
        p = get_current_data()[stock].day_open
        
        #判断是否突破,突破卖出,跌破买入。并且是否持仓
        if p > upper and stock in context.portfolio.positions:
            order_target(stock,0)
        if p < lower and stock not in context.portfolio.positions:
            order_target(stock,cach)

 

PEG策略

彼得林奇:任何一家公司股票如果定价合理的话,市盈率就会与收益增长率相等。

每股收益(EPS)

股价(P)

市盈率(PE)=P/EPS

收益增长率(G)=(EPSi-EPSi-1)/ESPi-1

PEG=PE/G/100

PEG越低,代表股价被低估可能性越大,股价会上涨的可能性就越大。

PEG是一个综合指标,既考查价值,有兼顾成长性。PEG估值法适合应用于成长型公司。

(PS:过滤掉收益率或收益增长率为负的情况)

 

#彼得林奇PEG策略
#PEG = 市盈率PE/收益增长率G/100
from jqdata import *

def initialize(context):    #初始化
    #设置基准
    set_benchmark('000300.XSHG')
    
    #设置复权,使用真实价格
    set_option('use_real_price',True)
    
    #设置订单成本cost(close_tax印花税,open_commission买入佣金,close_commission卖出佣金,min_commission最小佣金5元,type类型选择股票)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003,min_commission=5), type='stock')
    
    #设置security股票池,最终操作股票数g.N
    g.security = get_index_stocks('000300.XSHG')
    g.N = 20
    run_monthly(handle,1)
    
    
def handle(context):      #handle句柄表示对象,默认每天调用一次
    #调用财务数据,查询query(code代码,ratio市盈率,indicator财务数据.净利润增长率).filter(valuation市值数据.代码集)
    df = get_fundamentals(query(valuation.code,valuation.pe_ratio,indicator.inc_net_profit_year_on_year).filter(valuation.code.in_(g.security)))
    #排除负数
    df = df[(df['pe_ratio']>0)&(df['inc_net_profit_year_on_year']>0)]
    #计算PEG,同时排序获得前10排的元素赋值给df
    df['PEG'] = df['pe_ratio']/df['inc_net_profit_year_on_year']/100
    df = df.sort_values('PEG')[:g.N]
    #拿到满足条件的df所有代码,检索持仓信息,卖出不在持仓信息哦股票
    #用列表生成式生成准备买的股票池,用for循环分别买入操作
    tohold = df['code'].values
    for stock in context.portfolio.positions:
        if stock not in tohold:
            order_target(stock,0)
    tobuy = [stock for stock in tohold if stock not in context.portfolio.positions]
    
    #计算现金,分批买入
    cash = context.portfolio.available_cash
    n = cash // len(tobuy)
    
    for stock in tobuy:
        order_value(stock,n)

 

 

羊驼交易策略

 

 

海龟交易策略

唐奇安通道:

  • 上线 = Max(前N个交易日的最高价)
  • 下线 = Min(前N个交易日的最低价)
  • 中线 = (上线 + 下线) / 2

java boll线计算 boll线算法_java boll线计算

海龟交易法则:核心

  • 造成的损失不要超过总仓位的 k%

True Range(一天内波动量)

  • TrueRange = Maximum( H最高价 - L最低价, H最高价 - PDC前一天收盘价, PDC前一天收盘价 - L最低价)

N值计算

N值是仓位管理的核心,涉及加仓及止损。另外,N值与技术指标平均真实波幅 ATR很相似

首先介绍真实波幅: 真实波幅是以下三个值中的最大值

1、当前交易日最高价和最低价的波幅
    2、前一交易日的收盘价与当前交易日最高价的波幅
    3、前一交易日的收盘价与当前交易日最低价的波幅

用公式写就是:

TrueRange=Max(High−Low,abs(High−PreClose),abs(PreClose−Low))

接下来,N值计算公式为:

N=(PreN[−19:]+TrueRange)/20

其中 preN为前面N值,TrueRange为当前的真实波幅,此公式的真是含义为计算之前20天(包括今天在内)的N的平均值

买卖单位及首次建仓

先给出公式:

Unit=(1%∗Account)/N

首次建仓的时候,当捕捉到趋势,即价格突破唐奇安上轨时,买入1个unit。

其意义就是,让一个N值的波动与你总资金1%的波动对应,如果买入1unit单位的资产,当天震幅使得总资产的变化不超过1%。例如:

现在你有10万元资金,1%波动就是1000元。假如标X的N值为0.2元,1000元÷0.2元=5000股。也就是说,你的第一笔仓位应该是在其突破上轨(假设为5元)时立刻买入5000股,耗资25000元。

加仓

若股价在上一次买入(或加仓)的基础上上涨了0.5N,则加仓一个Unit。

接上面的例子:假如N值仍为0.2。
    价格来到 5 + 0.2*0.5 = 5.1时,加仓1个Unit,买入5000股,耗资25500元,剩余资金 49500元
    价格来到 5.1 + 0.2*0.5 = 5.2 时再加仓1个unit。买入5000股,耗资26000元,剩余资金 23500元

动态止损

当价格比最后一次买入价格下跌2N时,则卖出全部头寸止损。

接上面的例子,最后一次加仓价格为5.2。假如此时N值0.2元。 当价格下跌到 5.2 - 2*0.2 = 4.8元时,清仓。
        持仓成本为 (5+5.1+5.2)*5000/15000 = 5.1元。 此时亏损 (5.1-4.8)*15000 = 4500元 对于10万来说 这波亏损4.5%

止盈

当股价跌破10日唐奇安通道下沿,清空头寸结束本次交易。

——

原始的海龟交易采用唐奇安通道来捕捉趋势,虽然能捕捉到大趋势,但是在震荡的情况下表现不如人意,不过这也是所有趋势型策略的通病。但是回测小的特点可以应用在资金管理上,择时可以看看多因子、动量反转等。

#海归策略
# 2020-01-01 到 2020-12-1, ¥1000000, 分钟
from jqdata import *
def initialize(context):    #初始化
    #设置基准
    #set_benchmark('000063.XSHG')
    
    #设置复权,使用真实价格
    set_option('use_real_price',True)
    
    #设置订单成本cost(close_tax印花税,open_commission买入佣金,close_commission卖出佣金,min_commission最小佣金5元,type类型选择股票)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003,min_commission=5), type='stock')
    
    g.total_days = 0#运行总天数
    g.security = '000002.XSHE'
    g.N = [] #接收每天波动平均值N
    g.sys1_amount = 0 #系统1建的仓数
    g.sys2_amount = 0 #系统2建的仓数
    g.loss = 0.1 #可承受最大损失率
    g.adjust = 0.8 #若超过最大损失率,则调整为0.8
    g.ratio = 0.8 #系统1配置金额占总金额比例
    g.system1_system2 = True #系统1执行则系统2不执行
    
    #设置策略参数
    g.short_in_date = 20
    g.short_out_date = 10    
    g.long_in_date = 55
    g.long_out_date = 20
    g.unit = 1000 #初始买卖单位
    #每波动1个的最小单位,1手股票的价格变化
    #国内最小单位0.01元,最低买100股 0.01*100=1
    g.dollars_per_share = 1
    g.unit_limit = 4 #开单限制limit 在4个买卖单位 
    g.break_price1 = 0 #系统1的突破价格
    g.break_price2 = 0 #系统2的突破价格
'''
======================每天开盘前========================
'''
#开盘前运行函数
def before_trading_start(context):
    set_slip_fee(context)
#设置,滑点slip,费用fee
def set_slip_fee(context):
    #根据不同时间区间,设置手续费
    dt = context.current_dt ##获取当前时间+日期,获取当前日期为(ontext.current_dt.date())
    if dt>datetime.datetime(2013,1, 1):
        set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003,min_commission=5), type='stock')
    elif dt<datetime.date(2013,1, 1):
        set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003,min_commission=5), type='stock')
'''
======================正式交易时间========================
'''
def handle_data(context,data):
    #------每天开盘时间计算出20天的N
    dt = context.current_dt    #当前日期时间
    current_price1 = data[g.security].price  #当前价格
    if dt.hour==9 and dt.minute==30:
        print('--------------------')
        g.total_days += 1
        calculate_N()   #计算calculate
        
        
    #------大于20天后进行(资金,仓位)配置啊         
    if g.total_days > 20:
        #------总资产,可用现金,操作比率
        value = context.portfolio.portfolio_value #total_value
        cash = context.portfolio.cash #available_cash
        #当两个系统仓位都为0时,复位资金比率
        if g.sys1_amount == 0 and g.sys1_amount == 0:
            #若总资产小于 初始资金比率, 则降低20%资产变量和可用现金变量
            if value < (1-g.loss)*context.portfolio.starting_cash:
                value*=g.adjust 
                cash*=g.adjust
        
        
        #------按照波动量计算买卖手数单位
        #根据本策略,计算买卖单位(最大损失的1%进行下单)
        #每波动1个的最小单位,1手股票的价格变化
        #国内最小单位0.01元,最低买100股 0.01*100=1
        dollar_volatility = g.dollars_per_share*(g.N)[-1]
        g.unit = value*0.01/dollar_volatility
        
        
        #------系统操作1(如果市场没有订单,则进行开单函数验证)
        g.system1_system2 = True
        if g.sys1_amount == 0:
            #传入参数(当前价格,仓位比率金额,入市系统时机参数)
            market_in(current_price1,g.ratio*cash,g.short_in_date)
        #否则有订单,则加仓或者出
        else:
            #先调入止损函数,再调入加仓,离场函数
            stop_loss(current_price1)
            #传入参数(当前价格,仓位比率金额,入市系统时机参数)
            market_add(current_price1,g.ratio*cash,g.short_in_date)
            #传入参数(当前价格,仓位比率金额,出市系统时机参数)
            market_out(current_price1,g.short_out_date)
        #------系统操作2
        g.system1_system2 == False
        if g.sys2_amount == 0:
            #传入参数(当前价格,仓位比率金额,入市系统时机参数)
            market_in(current_price1,(1-g.ratio)*cash,g.long_in_date)
        #否则有订单,则加仓或者出
        else:
            #先调入止损函数,再调入加仓,离场函数
            stop_loss(current_price1)
            #传入参数(当前价格,仓位比率金额,入市系统时机参数)
            market_add(current_price1,(1-g.ratio*cash),g.long_in_date)
            #传入参数(当前价格,仓位比率金额,出市系统时机参数)
            market_out(current_price1,g.long_out_date)
    
        
'''
======================调用函数========================
'''
#计算calculate_N的值
def calculate_N():
    #交易总天数小于20天,N值为每天波动幅度True_Range的平均值(最大波动价格的均值)
    if g.total_days <= 20:
        #取得股票价格表,循环计算当天的波动幅度(最高价,最低价,前天收盘价)
        price = attribute_history(g.security,g.total_days,'1d',('high','low','pre_close'))
        lst = []
        #循环1-20天计算每天波动传入lst列表,然后均值运算
        for c_day in range(0, g.total_days):
            H_L = price['high'][c_day] - price['low'][c_day]    #当天最高-最低
            H_C = price['high'][c_day] - price['pre_close'][c_day]
            L_C = price['pre_close'][c_day]- price['low'][c_day]
            True_Range = max(H_L,H_C,L_C)#计算最大动量值
            lst.append(True_Range)
        #把当天列表序列转换成数组,均值运算得出单个波动值N,把每天的N加入接收列表
        current_N = np.mean(np.array(lst))
        (g.N).append(current_N)

    else:
        #交易天数大于20,就只以当天数据计算(前面的N 已经计算出来直接调用)
        price = attribute_history(g.security,1,'1d',('high','low','pre_close'))
        H_L = price['high'][0] - price['low'][0]    #当天最高-最低
        H_C = price['high'][0] - price['pre_close'][0]
        L_C = price['pre_close'][0] - price['low'][0]
        True_Range = max(H_L,H_C,L_C)
        #最终N值公式:N=(当前波动量+19*(g.N)[-1])/20 #(g.N)[-1]是列表最后一个值,也就是上一个交易日的动量值
        current_N = (True_Range+19*(g.N)[-1])/20
        (g.N).append(current_N)
        
        
#没有订单的开仓函数(入市以突破唐奇安通道Max(N20),收破唐奇安通道Min(N10)出)
def market_in(current_price1,cash,in_out):
    price = attribute_history(g.security,in_out,'1d',('close'))
    if current_price1 > max(price['close']):
        #买单前计算可买股份数 >= 一个买进单位则买入
        num_of_shares = cash/current_price1
        if num_of_shares >= g.unit:
            print('空仓买入前打印买入价格')
            print('current_price1')
            print(max(price['close']))
            
            
            #系统1开单,否则就是系统2开单
            if g.system1_system2 == True:
                #波动1个单位unit为1%,总仓位小于4个单位
                if g.sys1_amount < int(g.unit_limit*g.unit):
                    order(g.security,int(g.unit)) #买入一个单位
                    g.sys1_amount += int(g.unit)  #持仓单位加一个
                    g.break_price1 = current_price1 #记录系统1的开仓价格
            else:
                if g.sys2_amount < int(g.unit_limit*g.unit):
                    order(g.security,int(g.unit)) #买入一个单位
                    g.sys2_amount += int(g.unit)  #持仓单位加一个
                    g.break_price2 = current_price1 #记录系统2的开仓价格
                
            


#加仓函数
def market_add(x,cash,in_date):
    if g.system1_system2 ==True:
        break_price = g.break_price1 #获取系统1开仓价格
    else:
        break_price = g.break_price2 #获取系统2开仓价格
    #每上涨前一个波动值的0.5倍,加仓一个单位
    if x >= break_price + 0.5*(g.N)[-1]:
        #开仓前计算可买股份,大于1个买入单位则买入
        num_of_shares = cash/x
        if num_of_shares >= g.unit:
            print('加仓买入前打印订单仓位,买入价格')
            print(g.sys1_amount)
            print(g.sys2_amount)
            print(x)
            print(break_price + 0.5*(g.N)[-1])
            
            
            if g.system1_system2 == True:
                #波动1个单位unit为1%,总仓位小于4个单位
                if g.sys1_amount < int(g.unit_limit*g.unit):
                    order(g.security,int(g.unit)) #买入一个单位
                    g.sys1_amount += int(g.unit)  #持仓单位加一个
                    g.break_price1 = x #记录系统1的开仓价格
            else:
                if g.sys2_amount < int(g.unit_limit*g.unit):
                    order(g.security,int(g.unit)) #买入一个单位
                    g.sys2_amount += int(g.unit)  #持仓单位加一个
                    g.break_price2 = x #记录系统2的开仓价格
            
            
#离场函数
def market_out(x,out_date):
    price = attribute_history(g.security, out_date,'1d',('close'))
    if x < min(price['close']):
        print('开始离场')
        print(type(x))
        print('离场价格%.2f'%x)
        #print('唐奇安通道N10价:%.2f'%min(price['close']))
        if g.system1_system2 == True:
            if g.sys1_amount > 0:
                order(g.security,-g.sys1_amount)
                #卖出以后,仓位数重置标记为0
                g.sys1_amount = 0
        else:
            if g.sys2_amount > 0:
                order(g.security,-g.sys2_amount)
                #卖出以后,仓位数重置标记为0
                g.sys2_amount = 0
                
                
#止损函数
def stop_loss(x):
    if g.system1_system2 == True:
        break_price = g.break_price1 #获取系统1开仓价格
    else:
        break_price = g.break_price2 #获取系统2开仓价格
    #损失大于2N,则卖出
    if x < (break_price - 2*(g.N)[-1]):
        print('止损开始')
        print('当前价格:%.2f'%x)
        print('开仓价-2倍的波动价N:%.2f'%(break_price - 2*(g.N)[-1]))
        if g.system1_system2 == True:
                order(g.security,-g.sys1_amount)
                g.sys1_amount = 0
        else:
                order(g.security,-g.sys2_amount)
                g.sys2_amount = 0