获取连续下跌股票策略

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

(njchenxin) #1

克隆策略
In [ ]:
# 1. 策略基本参数
#抓取数据
df=D.history_data(D.instruments(),start_date='2015-01-01', end_date='2017-05-05', fields=['open', 'high', 'low', 'close'])
df.set_index('date', inplace=True)

# 回测起始时间
start_date = '2015-01-01'
# 回测结束时间
end_date = '2017-05-05'
# 策略比较参考标准,以沪深300为例
benchmark = '000300.INDX'
# 证券池 以贵州茅台为例
instruments =  D.instruments()
# 起始资金
capital_base = 100000

def resample(df):
# https://pandas-docs.github.io/pandas-docs-travis/timeseries.html#offset-aliases
# 周 W、月 M、季度 Q、10天 10D、2周 2W
    period = 'Q'

    year_df = df.resample(period, how='last')
    year_df['open'] = df['open'].resample(period, how='first')
    year_df['high'] = df['high'].resample(period, how='max')
    year_df['low'] = df['low'].resample(period, how='min')
    year_df['close'] = df['close'].resample(period, how='last')
    # 去除空的数据(没有交易的周)
    year_df = year_df[year_df.instrument.notnull()]
    year_df.reset_index(inplace=True)
    return year_df


def seek_stock(df):
    df['pre_open'] = df['open'].shift()
    df['condi_0'] = df['high'] < df['pre_open']
    df['condi_1'] = df['condi_0'].shift(1)
    df['condi_2'] = df['condi_0'].shift(2)
    df['condi_3'] = df['condi_0'].shift(3)
    df['condi_4'] = df['condi_0'].shift(4)
    return df[(df['condi_0'] == True) & (df['condi_1'] == True) & (df['condi_2'] == True) &(df['condi_3'] == True) &(df['condi_4'] == True)]



# 2. 策略主体函数
def initialize(context):
    
    # 设置手续费,买入时万3,卖出是千分之1.3,不足5元以5元计
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    context.hold_periods = 40 # 持有40天,固定持仓期
    context.stock_max_num = 10 # 最大持仓数量
    context.hold_days = {}
    

# 策略交易逻辑,每个交易日运行一次
def handle_data(context, data):
 
    #筛选股票列表
    year_df = df.groupby('instrument').apply(resample)
    year_df = year_df.reset_index(drop=True, inplace=True)
    stock_seeked = year_df.groupby('instrument').apply(seek_stock)
    stock_seeked = stock_seeked.reset_index(drop=True, inplace=True)
    context.daily_buy_stock = list(stock_seeked['instrument'])

    #买股列表
    stock_can_buy_num = context.stock_max_num 
    stock_to_buy = context.daily_buy_stock
    
    weight =  1 / len(stock_to_buy)

    for stock in stock_to_buy:
        if data.can_trade(context.symbol(stock)):
            curr_position =  context.portfolio.positions['instrument'].amount
            if curr_position == 0:
                # 买入10W股票
                context.order_target_percent(context.symbol(stock), weight)
        

# 3. 启动回测

# 策略回测接口: https://bigquant.com/docs/strategy_backtest.html
m = M.backtest.v5(
    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=capital_base,
    benchmark=benchmark,
)
[2017-05-10 18:43:25.579287] INFO: bigquant: backtest.v5 start ..
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-dea12fbcba43> in <module>()
     90     order_price_field_sell='open',
     91     capital_base=capital_base,
---> 92     benchmark=benchmark,
     93 )

<ipython-input-1-dea12fbcba43> in handle_data(context, data)
     58     year_df = df.groupby('instrument').apply(resample)
     59     year_df = year_df.reset_index(drop=True, inplace=True)
---> 60     stock_seeked = year_df.groupby('instrument').apply(seek_stock)
     61     stock_seeked = stock_seeked.reset_index(drop=True, inplace=True)
     62     context.daily_buy_stock = list(stock_seeked['instrument'])

AttributeError: 'NoneType' object has no attribute 'groupby'

报错:AttributeError: 'NoneType' object has no attribute 'groupby'
仔细想想我的逻辑没出 错,哪位大神能帮忙看看

(小Q) #2

矩形标记的地方有问题。

这两句代码参数传入有问题 ,year_df = year_df.reset_index(drop=True) 等价于 year_df.reset_index(drop=True, inplace=True)

inplace=True的含义是就地修改变量的意思,如果加了这个参数,就不用再绑定到year_df上了。


(njchenxin) #3

谢谢哦!!!