为什么在2014-05-19买入200股而不是价值20000的股票

策略分享
标签: #<Tag:0x00007fcf613b6f90>

(chidaye) #1
克隆策略
In [83]:
import talib
# 股票选择
#全部自选股
instruments=['601998.SHA']

#instruments =['000099.SZA','002197.SZA','600520.SHA','600312.SHA','600995.SHA','601998.SHA','000012.SZA','000625.SZA','000623.SZA','601088.SHA','601800.SHA','002673.SZA','002206.SZA','000559.SZA']
#蓝筹股 '601998.SHA','601088.SHA','601800.SHA',
#超跌股 '000099.SZA','002197.SZA','600312.SHA','002673.SZA','002206.SZA','000559.SZA'
#中信海直  ,政通电子,     文一科技,   平高电气,  文山电力,    中信银行,      南玻,         长安汽车,    吉林敖东      中国神华      中国交建      西部证券,   海利得       万向钱潮
# 开始时间
start_date = '2014-01-01'
# 结束时间
end_date = '2018-03-30'


# 大盘金叉
bm_price = D.history_data(['000300.SHA'], start_date , end_date, fields=['close'])
bm_price['sma'] = bm_price['close'].rolling(5).mean()
bm_price['lma'] = bm_price['close'].rolling(30).mean()
bm_price['gold_cross_status'] = bm_price['sma'] > bm_price['lma']
bm_price['pos_percent'] = np.where(bm_price['gold_cross_status'],1,0)
pos_df = bm_price[['date', 'pos_percent']].set_index('date')
#布林通道
bm_price['ma20'] = bm_price['close'].rolling(20).mean()
bm_price['std'] = bm_price['close'].rolling(20).std() 
bm_price['upper_line']=bm_price['ma20']+2 *bm_price['std']
bm_price['lower_line']=bm_price['ma20']-2 *bm_price['std']
bm_price['boll_buy'] = bm_price['close'] < bm_price['lower_line']
bm_price['boll_sell'] = bm_price['close'] > bm_price['upper_line']
bm_price['pos_percent_boll'] = np.where(bm_price['boll_buy'],1,0)
bm_price['neg_percent_boll'] = np.where(bm_price['boll_sell'],1,0)
pos_df_boll = bm_price[['date', 'pos_percent_boll']].set_index('date')




# 初始化账户
def initialize(context):
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) # 设置手续费,买入成本为万分之三,卖出为千分之1.3
    context.period_5 = 5
    context.period_10 =10
    context.period_20= 20
    context.period_30 =30
    context.period_60 =60
    context.short = 12
    context.long = 26
    context.smoothperiod = 9
    context.observation = 100
    context.ins = context.instruments
    context.weights = 1/len(context.instruments)
    context.pos = pos_df
    context.pos_boll = pos_df_boll
    
def handle_data(context, data):
    date = data.current_dt.strftime('%Y-%m-%d')  
   #------------------------------------------止赢模块START--------------------------------------------
    positions = {e.symbol: p.cost_basis  for e, p in context.portfolio.positions.items()}
    # 新建当日止赢股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
    current_stopwin_stock = [] 
    if len(positions) > 0:
        for i in positions.keys():
            stock_cost = positions[i] 
            stock_market_price = data.current(context.symbol(i), 'price') 
            # 赚10%就止赢
            if (stock_market_price - stock_cost ) / stock_cost>= 0.1:   
                context.order_target_percent(context.symbol(i),0)     
                current_stopwin_stock.append(i)
                print('日期:',date,'股票:',i,'出现止盈状况')
    #-------------------------------------------止赢模块END---------------------------------------------
  #------------------------------------------止损模块START--------------------------------------------
    positions = {e.symbol: p.cost_basis  for e, p in context.portfolio.positions.items()}
    # 新建当日止损股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
    current_stoploss_stock = [] 
    if len(positions) > 0:
        for i in positions.keys():
            stock_cost = positions[i] 
            stock_market_price = data.current(context.symbol(i), 'price') 
            # 亏5%就止损
            if (stock_market_price - stock_cost) / stock_cost <= -0.85:   
                context.order_target_percent(context.symbol(i),0)     
                current_stoploss_stock.append(i)
                print('日期:',date,'股票:',i,'出现止损状况')
    #-------------------------------------------止损模块END---------------------------------------------

    
   
     
    # 长期均线值要有意义,需要在60根k线之后
    if context.trading_day_index <  20:     
        return
    for k in context.instruments:
        if k in current_stoploss_stock or k in current_stopwin_stock:
             continue
        sid = context.symbol(k) # 将标的转化为equity格式
        price = data.current(sid, 'price') # 最新价格
        #print (price)
        #MACD
        prices = data.history(sid, 'price', context.observation, '1d')
        macd, signal, hist = talib.MACD(np.array(prices), context.short, context.long, context.smoothperiod)
        ma = data.history(sid, 'price', 20, '1d').mean() 
        std = data.history(sid, 'price', 20, '1d').std() 
        upper_line = ma + 2 * std
        lower_line = ma - 2 * std 
        short_mavg = data.history(sid, 'price',5, '1d').mean() # 短期均线值
        min_mavg = data.history(sid, 'price',30, '1d').mean() # 短期均线值
        long_mavg = data.history(sid, 'price',60, '1d').mean() # 长期均线值
        cash = context.portfolio.portfolio_value  # 现金
        cur_position = context.portfolio.positions[sid].amount # 持仓
        
             # 买入逻辑  macd上穿signal 或者大盘穿过布林线下方
      # if (macd[-1] - signal[-1] > 0 and macd[-2] - signal[-2] < 0) and (context.pos.ix[date].pos_percent == 1) :
        if price<lower_line:
            if data.can_trade(sid):  
                context.order_target_value(sid, 20000) # 买入
        

                
m=M.trade.v3(
    instruments=instruments,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    order_price_field_buy='open', # 以开盘价买入
    order_price_field_sell='open', # 以开盘价卖出
    capital_base=100000, # 本金
    price_type='real'
    )   
[2018-04-08 21:58:11.851827] INFO: bigquant: backtest.v7 开始运行..
[2018-04-08 21:58:11.986617] INFO: algo: set price type:original
日期: 2014-04-11 股票: 601998.SHA 出现止盈状况
[2018-04-08 21:58:21.595546] INFO: algo: get splits [2014-07-17 00:00:00+00:00] [asset:Equity(0 [601998.SHA]), ratio:0.9419950497208653]
[2018-04-08 21:58:21.597000] INFO: Position: position handle split[sid:0, orig_amount:4700, new_amount:4989.0, orig_cost:4.479558676169826,new_cost:4.22, ratio:0.9419950497208653, last_sale_price:4.0599986103955406]
[2018-04-08 21:58:21.598225] INFO: Position: after split: asset: Equity(0 [601998.SHA]), amount: 4989.0, cost_basis: 4.22, last_sale_price: 4.309999942779541
[2018-04-08 21:58:21.599281] INFO: Position: returning cash: 1.67
日期: 2014-10-16 股票: 601998.SHA 出现止盈状况
日期: 2014-10-31 股票: 601998.SHA 出现止盈状况
日期: 2015-06-08 股票: 601998.SHA 出现止盈状况
日期: 2015-07-06 股票: 601998.SHA 出现止盈状况
日期: 2015-11-09 股票: 601998.SHA 出现止盈状况
[2018-04-08 21:58:33.283065] INFO: algo: get splits [2016-07-25 00:00:00+00:00] [asset:Equity(0 [601998.SHA]), ratio:0.9657426445424234]
[2018-04-08 21:58:33.284440] INFO: Position: position handle split[sid:0, orig_amount:3500, new_amount:3624.0, orig_cost:6.418763557275184,new_cost:6.2, ratio:0.9657426445424234, last_sale_price:5.9200025215655305]
[2018-04-08 21:58:33.285605] INFO: Position: after split: asset: Equity(0 [601998.SHA]), amount: 3624.0, cost_basis: 6.2, last_sale_price: 6.130000114440918
[2018-04-08 21:58:33.287017] INFO: Position: returning cash: 0.91
日期: 2016-11-23 股票: 601998.SHA 出现止盈状况
[2018-04-08 21:58:40.117728] INFO: algo: get splits [2017-07-24 00:00:00+00:00] [asset:Equity(0 [601998.SHA]), ratio:0.9700427168666901]
[2018-04-08 21:58:40.119299] INFO: Position: position handle split[sid:0, orig_amount:3200, new_amount:3298.0, orig_cost:6.677758899227598,new_cost:6.48, ratio:0.9700427168666901, last_sale_price:6.799999667260655]
[2018-04-08 21:58:40.120819] INFO: Position: after split: asset: Equity(0 [601998.SHA]), amount: 3298.0, cost_basis: 6.48, last_sale_price: 7.010000228881836
[2018-04-08 21:58:40.122201] INFO: Position: returning cash: 5.6
日期: 2018-01-18 股票: 601998.SHA 出现止盈状况
[2018-04-08 21:58:45.003490] INFO: Performance: Simulated 1036 trading days out of 1036.
[2018-04-08 21:58:45.004836] INFO: Performance: first open: 2014-01-02 01:30:00+00:00
[2018-04-08 21:58:45.005968] INFO: Performance: last close: 2018-03-30 07:00:00+00:00
  • 收益率19.42%
  • 年化收益率4.41%
  • 基准收益率67.32%
  • 阿尔法-0.01
  • 贝塔0.08
  • 夏普比率-0.0
  • 胜率0.692
  • 盈亏比58.949
  • 收益波动率4.31%
  • 信息比率-0.39
  • 最大回撤3.85%
[2018-04-08 21:58:49.160446] INFO: bigquant: backtest.v7 运行完成[37.308643s].

(chidaye) #2

为什么买入的条件,满足条件,第一笔买入正常,后面1-2笔买入都是100或者200股,我条件设置到每次跌破布林道就买入2万,如何修改呢


(小Q) #3

首先我们看看持仓详情:
image

可以发现,601998这只股票在2014-5-16已经有4400股,价值18964元。

再来看看你的下单函数:

 context.order_target_value(sid, 20000) # 买入

该下单接口的含义是希望买入一些股票,使得601998这只股票持仓达到20000元,目前已经有18964的持仓了,因此只需买1000元的股票就可以,换算下来刚好200股。
关于下单接口,你可以查看:交易相关方法


(chidaye) #4

我本来想设计,每次达到布林线下,都买入2万元,需要怎么修改呢?