# 克隆自聚宽文章:https://www.joinquant.com/post/24681
# 标题:根据北上资金买股票的最佳持股时间探讨
# 作者:见路不走2019
# 请选择 python 2 来进行回测
import talib
from prettytable import PrettyTable
import pandas
import datetime
import time
from jqdata import *
def initialize(context):
set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
set_option('use_real_price', True)
set_benchmark('000300.XSHG')
log.set_level('order', 'error')
log.set_level('history', 'error')
g.buy_stock_count = 3
g.hour = 9
g.minute = 30
g.days = 0
g.refresh_rate = 23
g.nday=2
set_option("avoid_future_data", True)
def handle_data(context, data):
hour = context.current_dt.hour
minute = context.current_dt.minute
today=context.current_dt.day
buy_stocks = []
if g.days%g.refresh_rate==0:
if hour == g.hour and minute == g.minute:
buy_stocks = select_stocks(context,data)
print '前%d个交易日港资(北向资金)净买额最高的股票:\n'%g.nday
for stock in buy_stocks:
print show_stock(stock)
adjust_position(context, buy_stocks)
print get_portfolio_info_text(context,buy_stocks)
g.days+=1
def select_stocks(context,data):
date = context.previous_date
startdate=date-datetime.timedelta(g.nday)
trade_days=get_trade_days(startdate,date)
total_df=pd.DataFrame()
for day in trade_days:
q = query(finance.STK_EL_TOP_ACTIVATE).filter(finance.STK_EL_TOP_ACTIVATE.day == day )
df = finance.run_query(q)
df['net'] = df.buy - df.sell
df = df.sort(columns = ['net'] , axis = 0, ascending = False)
df = df[(df.link_id != 310003 ) & (df.link_id != 310004 )]
total_df=pd.concat((total_df,df))
stock_net=total_df.groupby(total_df['code'])['net'].sum()
stock_net=pd.DataFrame(stock_net)
stock_list=list(stock_net.index)
df_cap=get_fundamentals(query(valuation.code, valuation.circulating_market_cap).filter(valuation.code.in_(stock_list)),date=date)
df_cap.index=df_cap.code
#log.info('df_cap',df_cap)
df_cap=pd.concat((df_cap,stock_net),axis=1)
df_cap['rate']=(df_cap['net']/100000000/df_cap['circulating_market_cap'])
df_cap=df_cap.sort('rate',ascending=False)
stock_list = list(df_cap['code'])
# 过滤掉停牌的和ST的
#stock_list = filter_paused_and_st_stock(stock_list)
#过滤掉创业板
#stock_list = filter_gem_stock(context, stock_list)
# 过滤掉上市超过1年的
#stock_list = filter_old_stock(context, stock_list)
# 过滤掉现在涨停或者跌停的
#stock_list = filter_limit_stock(context, stock_list)
#stock_list = filter_limit_stock(context, data, stock_list)
#选取前N只股票放入“目标股票池”
stock_list = stock_list[:g.buy_stock_count]
return stock_list
def filter_paused_and_st_stock(stock_list):
current_data = get_current_data()
return [stock for stock in stock_list if not current_data[stock].paused
and not current_data[stock].is_st and 'ST' not in current_data[stock].
name and '*' not in current_data[stock].name and '退' not in current_data[stock].name]
def filter_gem_stock(context, stock_list):
return [stock for stock in stock_list if stock[0:3] != '300']
def filter_old_stock(context, stock_list):
tmpList = []
for stock in stock_list :
days_public=(context.current_dt.date() - get_security_info(stock).start_date).days
# 上市未超过1年
if days_public < 365 :
tmpList.append(stock)
return tmpList
def filter_limit_stock(context, data, stock_list):
tmpList = []
current_data = get_current_data()
for stock in stock_list:
# 未涨停,也未跌停
if (data[stock].low_limit < data[stock].close < data[stock].high_limit) and (current_data[stock].low_limit < data[stock].close < current_data[stock].high_limit): tmpList.append(stock) return tmpList def adjust_position(context, buy_stocks): # 现持仓的股票,如果不在“目标池”中,且未涨停,就卖出 if len(context.portfolio.positions)>0:
last_prices = history(1, '1m', 'close', security_list=context.portfolio.positions.keys())
for stock in context.portfolio.positions.keys():
if stock not in buy_stocks :
curr_data = get_current_data()
if last_prices[stock][-1] < curr_data[stock].high_limit: order_target_value(stock, 0) # 依次买入“目标池”中的股票 for stock in buy_stocks: position_count = len(context.portfolio.positions) if g.buy_stock_count > position_count:
value = context.portfolio.cash / (g.buy_stock_count - position_count)
if context.portfolio.positions[stock].total_amount == 0:
order_target_value(stock, value)
def shifttradingday(date,shift):
#获取N天前的交易日日期
# 获取所有的交易日,返回一个包含所有交易日的 list,元素值为 datetime.date 类型.
tradingday = get_all_trade_days()
# 得到date之后shift天那一天在列表中的行标号 返回一个数
shiftday_index = list(tradingday).index(date)+shift
# 根据行号返回该日日期 为datetime.date类型
return tradingday[shiftday_index]
def show_stock(stock):
'''
获取股票代码的显示信息
:param stock: 股票代码,例如: '603822.SH'
:return: str,例如:'603822 嘉澳环保'
'''
return u"%s %s" % (stock[:6], get_security_info(stock).display_name)
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
