量化学习平台
文章
市场宽度
背离图
登录
注册
10倍-二板排板战法优化
策略
作者: 水滴
```python # 风险及免责提示:该策略由聚宽用户在聚宽社区分享,仅供学习交流使用。 # 原文一般包含策略说明,如有疑问请到原文和作者交流讨论。 # 原文网址:https://www.joinquant.com/post/34141 # 标题:10倍-二板排板战法优化-无未来函数 # 作者:游资小码哥 # 按分钟回测 # 克隆自聚宽文章:https://www.joinquant.com/post/34053 # 标题:对 二板排板战法 的部分优化 # 作者:xloong # 二板排板战法研究-游资小码哥 # https://www.joinquant.com/view/community/detail/25e48a8c5048bc2d02f785aeb913afd4?type=1 # 导入函数库 # enable_profile() from jqdata import * help_stock = [] # 初始化函数,设定基准等等 def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_option('use_real_price', True) # 输出内容到日志 log.info() log.info('初始函数开始运行且全局只运行一次') # 过滤掉order系列API产生的比error级别低的log # log.set_level('order', 'error') # g 内置全局变量 g.my_security = '510300.XSHG' set_universe([g.my_security]) ### 股票相关设定 ### # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱 set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock') ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的) # 开盘前运行 run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') # 开盘时运行 run_daily(market_run, time='every_bar', reference_security='000300.XSHG') #run_daily(market_run_sell, time='every_bar', reference_security='000300.XSHG') # 收盘后运行before_open #run_daily(before_market_open, time='after_close', reference_security='000300.XSHG') buy_bool = False # 开盘时运行函数 def market_run(context): log.info('【market_run】') time_buy = context.current_dt.strftime('%H:%M:%S') aday = datetime.datetime.strptime('10:30:00', '%H:%M:%S').strftime('%H:%M:%S') now = context.current_dt zeroToday = now - datetime.timedelta(hours=now.hour, minutes=now.minute, seconds=now.second,microseconds=now.microsecond) lastToday = zeroToday + datetime.timedelta(hours=9, minutes=31, seconds=00) # log.info(now) # 当前对应分钟 # log.info(zeroToday) # 2020-01-08 00:00:00 始终00 # log.info(lastToday) # 2020-01-08 09:31:00 始终9:31 if len(help_stock) > 0 and time_buy>='09:33:00': cash = context.portfolio.available_cash #print(cash) # pre_date = (context.current_dt + timedelta(days = -1)).strftime("%Y-%m-%d") # log.info(pre_date) gc_data = get_current_data() # df_panel_all = get_price(help_stock, start_date=lastToday, end_date=context.current_dt, frequency='minute', fields=['high','low','close','high_limit','money']) for stock in help_stock: # log.info(df_panel_all['close'][stock].values) #log.info("当前时间 %s" % (context.current_dt)) #log.info("股票 %s 的最新价: %f" % (stock, gc_data[stock].last_price)) if(cash > 5000): gc_stock = gc_data[stock] current_price = gc_stock.last_price day_open_price = gc_stock.day_open day_high_limit = gc_stock.high_limit # df_panel = get_price(stock, count = 1,end_date=pre_date, frequency='daily', fields=['open', 'high', 'close','low', 'high_limit','money','pre_close']) # log.info(df_panel) # pre_high = df_panel['high'].values # pre_close = df_panel['close'].values pre_high = g.yest_df_panel['high'][stock].values pre_close = g.yest_df_panel['close'][stock].values # 当天分钟级 最高最低 df_panel_all = get_price( stock, start_date=lastToday, end_date=context.current_dt, frequency='minute', fields=['high','low','close','high_limit','money'] ) df_min_low_all = df_panel_all.loc[:,"close"].min() df_max_high_all = df_panel_all.loc[:,"close"].max() count_max = (df_panel_all.loc[:,'close'] == df_panel_all.loc[:,'high_limit']).sum() # df_min_low_all = min(df_panel_all['close'][stock].values) # df_max_high_all = max(df_panel_all['close'][stock].values) # count_max = (df_panel_all['close'][stock].values == df_panel_all['high_limit'][stock].values).sum() if cash > 5000 and count_max > 3: if current_price > pre_close * 1.07 and current_price < day_high_limit and day_open_price < day_high_limit * 0.98: #open_cash = cash / len(help_stock) print(stock+" 1.买入金额 "+str(cash)) order_value(stock, cash) help_stock.remove(stock) time_sell = context.current_dt.strftime('%H:%M:%S') cday = datetime.datetime.strptime('14:40:00', '%H:%M:%S').strftime('%H:%M:%S') dday = datetime.datetime.strptime('10:30:00', '%H:%M:%S').strftime('%H:%M:%S') now = context.current_dt zeroToday = now - datetime.timedelta(hours=now.hour, minutes=now.minute, seconds=now.second,microseconds=now.microsecond) lastToday = zeroToday + datetime.timedelta(hours=9, minutes=30, seconds=00) if time_sell > cday and len(context.portfolio.positions): stock_owner = context.portfolio.positions # if len(stock_owner) > 0: for stock_two in stock_owner: # current_price_list = get_ticks(stock_two,start_dt=None, end_dt=context.current_dt, count=1, fields=['time', 'current', 'high', 'low', 'volume', 'money']) # current_price = current_price_list['current'][0] # current_price = context.portfolio.positions[stock_two].price current_price = gc_data[stock_two].last_price day_open_price = gc_data[stock_two].day_open day_high_limit = gc_data[stock_two].high_limit day_low_limit = gc_data[stock_two].low_limit #查询当天的最高价 df_panel_allday = get_price( stock_two, start_date=lastToday, end_date=context.current_dt, frequency='minute', fields=['high','low','close','high_limit','money'] ) # low_allday = df_panel_allday.loc[:,"low"].min() high_allday = df_panel_allday.loc[:,"high"].max() # ##获取前一天的收盘价 # # pre_date = (context.current_dt + timedelta(days = -1)).strftime("%Y-%m-%d") # # df_panel = get_price(stock_two, count = 1,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','low',]) # # pre_low_price =df_panel['low'].values # # pre_close_price =df_panel['close'].values # pre_low_price =g.yest_df_panel['low'][stock].values # pre_close_price =g.yest_df_panel['close'][stock].values # 耗时 # num_limit_stock = count_limit_num_all(stock_two,context) #平均持仓成本 cost = context.portfolio.positions[stock_two].avg_cost # print("----------------------------------") # print("current_price="+str(current_price)) # print("day_open_price="+str(day_open_price)) # print("pre_close_price="+str(pre_close_price)) # print("df_max_high="+str(df_max_high)) # print("=====================================") if current_price < high_allday * 0.97 and current_price > day_low_limit: # print("1.卖出股票:小于最高价0.97倍"+str(num_limit_stock)) print("1.卖出股票:小于最高价0.97倍") order_target(stock_two, 0) elif current_price < cost * 0.93 and current_price < day_open_price and current_price >day_low_limit: # print("卖出股票:比开盘价低7个点"+str(num_limit_stock)) print("卖出股票:比开盘价低7个点") order_target(stock_two, 0) elif time_sell > dday and len(context.portfolio.positions): stock_owner = context.portfolio.positions # if len(stock_owner) > 0: for stock_two in stock_owner: # 耗时 # current_price_list = get_ticks(stock_two,start_dt=None, end_dt=context.current_dt, count=1, fields=['time', 'current', 'high', 'low', 'volume', 'money']) # current_price = current_price_list['current'][0] current_price = gc_data[stock_two].last_price day_open_price = gc_data[stock_two].day_open day_high_limit = gc_data[stock_two].high_limit day_low_limit = gc_data[stock_two].low_limit # #查询当天的最高价 # df_panel_allday = get_price(stock_two, start_date=lastToday, end_date=context.current_dt, frequency='minute', fields=['high','low','close','high_limit','money']) # low_allday = df_panel_allday.loc[:,"low"].min() # high_allday = df_panel_allday.loc[:,"high"].max() ##获取前一天的收盘价 pre_date = (context.current_dt + timedelta(days = -1)).strftime("%Y-%m-%d") df_panel = get_price(stock_two, count = 1,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','low',]) pre_low_price =df_panel['low'].values pre_close_price =df_panel['close'].values # 耗时 # num_limit_stock = count_limit_num_all(stock_two,context) #平均持仓成本 cost = context.portfolio.positions[stock_two].avg_cost # print("----------------------------------") # print("current_price="+str(current_price)) # print("day_open_price="+str(day_open_price)) # print("pre_close_price="+str(pre_close_price)) # print("df_max_high="+str(df_max_high)) # print("=====================================") if current_price < pre_close_price * 1.03 and current_price > day_low_limit: # print("1.卖出股票:小于最高价0.97倍"+str(num_limit_stock)) print("1.卖出股票:小于最高价0.97倍") order_target(stock_two, 0) time_sell = context.current_dt.strftime('%H:%M:%S') cday = datetime.datetime.strptime('14:45:00', '%H:%M:%S').strftime('%H:%M:%S') if time_sell > cday and len(help_stock) > 0: instead_stock = help_stock for stock_remove in instead_stock: help_stock.remove(stock_remove) # 开盘前运行函数 选择二板放量股 并且横盘震荡 def before_market_open(context): date_now = (context.current_dt+ timedelta(days = -1)).strftime("%Y-%m-%d")#'2021-01-15'#datetime.datetime.now() yesterday = (context.current_dt + timedelta(days = -30)).strftime("%Y-%m-%d") trade_date = get_trade_days(start_date=yesterday, end_date=date_now, count=None) # log.info(context.current_dt) # log.info(date_now) # log.info(yesterday) # log.info(trade_date) ##查询所有股票的当天的涨停板 stocks = list(get_all_securities(['stock']).index) end_date=trade_date[trade_date.size-1] # log.info(trade_date.size) # 21 log.info(trade_date[trade_date.size-1]) stock_list = stocks ##去除st的连板股票 stock_list = filter_st(stock_list) ##查询所有股票的当天的涨停板 # 耗时 stock_list = pick_high_limit(stock_list, end_date) pre_date=trade_date[trade_date.size-2] tmpList = filter_one_limit(stock_list, pre_date) ##筛选上市时间大于1080天的股票 #tmpList = filter_stock_by_days(context,continuous_price_limit_two,1080) ##查看股票前期是否平整,并且股票第一个板要高过一年的最高收盘价 for stock_flat in tmpList: # 次耗时 bool_result = filter_flat_stock(stock_flat,end_date,pre_date) if bool_result == True : help_stock.append(stock_flat) print("----------------最后被选出的股票-----------") print(help_stock) g.yest_df_panel = get_price(help_stock, count = 1,end_date=end_date, frequency='daily', fields=['open', 'high', 'close','low', 'high_limit','money','pre_close']) # log.info('g.yest_df_panel') # log.info(g.yest_df_panel['high']) # 选出打板的股票 def pick_high_limit(stocks,end_date): log.info('【pick_high_limit】') # 耗时 df_panel = get_price(stocks, count = 1,end_date=end_date, frequency='daily', fields=['open', 'close','high_limit','money','pre_close']) df_close = df_panel['close'] # log.info(df_close) df_open = df_panel['open'] df_high_limit = df_panel['high_limit'] df_money = df_panel['money'] df_pre_close = df_panel['pre_close'] high_limit_stock = [] for stock in (stocks): _high = (df_high_limit[stock].values) _close = (df_close[stock].values) _open = (df_open[stock].values) _pre_close = (df_pre_close[stock].values) if(stock[0:3] == '300'): continue if( # 涨停 _high == _close # 大于昨日收盘价5% and _high > _pre_close*1.05 # 大于今日开盘价5% 非一字 and _close > _open*1.05 ): high_limit_stock.append(stock) return high_limit_stock #去除st的股票 def filter_st(codelist): current_data = get_current_data() codelist = [code for code in codelist if not current_data[code].is_st] return codelist #选出只有一板的股票 def filter_one_limit(stocks,end_date): print(end_date) # 耗时 df_panel = get_price(stocks, count = 1,end_date=end_date, frequency='daily', fields=['open', 'close','high_limit','money']) df_close = df_panel['close'] df_high_limit = df_panel['high_limit'] df_money = df_panel['money'] high_limit_stock = [] for stock in (stocks): _high = (df_high_limit[stock].values) _close = (df_close[stock].values) _money = (df_money[stock].values) _high_imit = df_high_limit[stock].values ##剔除创业板的股票 if(stock[0:3] == '300'): continue if _high_imit != _close : high_limit_stock.append(stock) return high_limit_stock # 查看股票前期是否平整 且两板的最高点是否超过其他的最高点 def filter_flat_stock(stock,end_date,pre_date): #查询昨天的涨停价格 df_panel = get_price(stock, count = 1,end_date=end_date, frequency='daily', fields=['open', 'close','high_limit','money']) df_close = df_panel['close'].values df_open = df_panel['open'].values df_high_limit = df_panel['high_limit'].values df_money = df_panel['money'].values # #20天的波动率 # df_panel_10 = get_price(stock, count = 10,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) # sum_plus_num_two = (df_panel_10.loc[:,'high'] == df_panel_10.loc[:,'high_limit']).sum() # df_max_high = df_panel_10["high"].max() # df_min_low = df_panel_10["low"].min() # abs_sum_10 = (df_panel_10.loc[:,'close'] - df_panel_10.loc[:,'open']).abs() / ((df_panel_10.loc[:,'open']+df_panel_10.loc[:,'close']) / 2) # abs_sum_num_1030 = (abs_sum_10 < 0.03).sum() # abs_sum_num_1015 = (abs_sum_10 < 0.015).sum() # abs_sum_num_1055 = (abs_sum_10 < 0.055).sum() df_panel_20 = get_price(stock, count = 20,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) sum_shipan_num = ((df_panel_20.loc[:,'high_limit'] == df_panel_20.loc[:,'high']) * (df_panel_20.loc[:,'close'] <= df_panel_20.loc[:,'high_limit'] * 0.97)).sum() df_max_high_20 = df_panel_20["high"].max() sum_plus_num_20 = (df_panel_20.loc[:,'high'] == df_panel_20.loc[:,'high_limit']).sum() abs_sum_20 = (df_panel_20.loc[:,'close'] - df_panel_20.loc[:,'open']).abs() / ((df_panel_20.loc[:,'open']+df_panel_20.loc[:,'close']) / 2) abs_sum_num_2030 = (abs_sum_20 < 0.03).sum() abs_sum_num_2015 = (abs_sum_20 < 0.015).sum() abs_sum_num_2055 = (abs_sum_20 < 0.055).sum() # df_panel_30 = get_price(stock, count = 30,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) # df_max_high_30 = df_panel_30["high"].max() # df_min_low_30 = df_panel_30["low"].min() # rate_30 = (df_max_high_30 - df_min_low_30) / df_min_low_30 # rate_10 = (df_max_high - df_min_low) / df_min_low #print(stock+"收盘价的方差为:"+str(std_allday)) #12天的波动率 df_panel_60 = get_price(stock, count = 60,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) high_allday_60 = df_panel_60.loc[:,"high"].max() low_allday_60 = df_panel_60.loc[:,"low"].min() close_allday_60 = df_panel_60.loc[:,"close"].max() percent_rate_60 = low_allday_60 / high_allday_60 sum_close_num_60 = (df_panel_60.loc[:,'close'] <= df_panel_60.loc[:,'open']).sum() abs_sum_60 = (df_panel_60.loc[:,'close'] - df_panel_60.loc[:,'open']).abs() / df_panel_60.loc[:,'open'] abs_sum_num_6015 = (abs_sum_60 < 0.015).sum() abs_sum_num_6030 = (abs_sum_60 < 0.03).sum() abs_sum_num_6055 = (abs_sum_60 < 0.055).sum() sum_plus_num_60 = (df_panel_60.loc[:,'high'] > df_panel_60.loc[:,'high_limit'] * 0.99).sum() # df_panel_100 = get_price(stock, count = 100,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) # df_max_close_100 = df_panel_100["close"].max() # #150天的波动率 # df_panel_150 = get_price(stock, count = 150,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low','pre_close']) # sum_plus_num_150 = (df_panel_150.loc[:,'close'] > df_panel_150.loc[:,'pre_close'] * 1.09).sum() # df_max_close_150 = df_panel_150["close"].max() # df_max_open_150 = df_panel_150["open"].max() # df_min_low_150 = df_panel_150["low"].min() # abs_sum_150 = (df_panel_150.loc[:,'close'] - df_panel_150.loc[:,'open']).abs() / ((df_panel_150.loc[:,'open']+df_panel_150.loc[:,'close']) / 2) # abs_sum_num_1503 = (abs_sum_150 < 0.03).sum() # abs_sum_num_1515 = (abs_sum_150 < 0.015).sum() # abs_sum_num_15555 = (abs_sum_150 < 0.055).sum() # rate_150 = (df_max_close_150 - df_min_low_150) / df_min_low_150 # # df_panel_30 = get_price(stock, count = 30,end_date=pre_date, frequency='daily', fields=['open', 'close','high_limit','money','high','low']) # # close_allday_30 = df_panel_30.loc[:,"close"].max() # # sum_close_num_two = (df_panel_two.loc[:,'close'] <= df_panel_two.loc[:,'open']).sum() # if stock == '603518.XSHG': # print(df_close) # print(close_allday_60) # print("-------20days--------") # print(abs_sum_num_2030) # print(abs_sum_num_2015) # print(abs_sum_num_2055) # print("-------60days--------") # print(abs_sum_num_6015) # print(abs_sum_num_6030) # print(abs_sum_num_6055) # print("------------150days--------------") # print(abs_sum_num_1503) # print(abs_sum_num_1515) # print(abs_sum_num_15555) if ( df_close * 1.1 > close_allday_60 and abs_sum_num_2030 > 15 and abs_sum_num_2015 > 7 and abs_sum_num_2055 >= 18 ): if (abs_sum_num_6015 >=28 and abs_sum_num_6030 > 45 and abs_sum_num_6055 > 50 ): return True #过滤上市时间不满1080天的股票 def filter_stock_by_days(context, stock_list, days): tmpList = [] for stock in stock_list : #days_public=(context.current_dt.date() - get_security_info(stock).start_date).days days_public > days and market_cap = get_circulating_market_cap(stock) market_cap_num = market_cap['circulating_market_cap'].values if market_cap_num >10 and market_cap_num < 150: tmpList.append(stock) return tmpList # 查看他总的涨停数 def count_limit_num_all(stock,context): date_now = (context.current_dt+ timedelta(days = -1)).strftime("%Y-%m-%d")#'2021-01-15'#datetime.datetime.now() yesterday = (context.current_dt + timedelta(days = -30)).strftime("%Y-%m-%d") trade_date = get_trade_days(start_date=yesterday, end_date=date_now, count=None) limit_num = 0 for datenum in trade_date: # 耗时 df_panel = get_price(stock, count = 1,end_date=datenum, frequency='daily', fields=['open', 'close','high_limit','money']) df_close = df_panel['close'].values df_high_limit = df_panel['high_limit'].values if df_close == df_high_limit: limit_num = limit_num + 1 return limit_num # 获取个股流通市 值数据 def getcirculating_market_cap(stock_list): query_list = [stock_list] q = query(valuation.code,valuation.circulating_market_cap).filter(valuation.code.in_(query_list)) market_cap = get_fundamentals(q) market_cap.set_index('code', inplace=True) return market_cap def count_limit_num(stock,context): date_now = (context.current_dt+ timedelta(days = -1)).strftime("%Y-%m-%d")#'2021-01-15'#datetime.datetime.now() yesterday = (context.current_dt + timedelta(days = -20)).strftime("%Y-%m-%d") trade_date = get_trade_days(start_date=yesterday, end_date=date_now, count=None) limit_num = 0 for datenum in trade_date: df_panel = get_price(stock, count = 1,end_date=datenum, frequency='daily', fields=['open', 'close','high_limit','money']) df_close = df_panel['close'].values df_high_limit = df_panel['high_limit'].values if df_close == df_high_limit: limit_num = limit_num + 1 #print("涨停板天数:"+str(limit_num)) return limit_num # 收盘后运行函数 def after_market_close(context): log.info(str('除当天的股票数据-----函数运行时间(after_market_close):'+str(context.current_dt.time()))) #消除当天的股票数据 help_stock = [] #print(help_stock) ```
文章分类
关于作者
水滴
注册时间: