修改了一些内容:
1. 原策略在卖出后将现金均分为所有持仓数量再买入,会导致新买入股票的量严重偏小,修改后将卖出后的现金只买入新纳入股票池的股票;
2. 剔除了ST、涨停、跌停等股票;
3. 增加了止盈止损;
# 初始化代码
def initialize(context):
# 设置比较基准
set_benchmark('000300.XSHG')
# 设置股票交易佣金和印花税
set_order_cost(OrderCost(open_commission=0.00012, close_commission=0.00012, min_commission=5), type='stock')
# 开启动态复权(真实价格)模式
set_option('use_real_price', True)
run_daily(market_open, time='every_bar')
# 设定要交易的股票数量,用全局变量g
g.stocksnum = 20
# 设定策略每一次运行的间隔周期
g.period = 10
# 记录策略进行天数
g.days = 0
# 设置过滤条件,筛选出适合的标的
def filter_stock(context):
# 当天全市场股票列表
Total_list = get_all_securities(date= context.current_dt).index.tolist()
# 获取当前单位时间(当天/当前分钟)的涨跌停价, 是否停牌,当天的开盘价等
current_data = get_current_data()
# 剔除st/停牌/退市/涨跌停
deal_list = [stock for stock in Total_list if not (
current_data[stock].paused or current_data[stock].is_st or current_data[stock].last_price ==
current_data[stock].high_limit or current_data[stock].last_price == current_data[stock].low_limit)]
# 全市场股票中市值最小的前stocksnum个的股票,并转为list
my_query = query(valuation.code).filter(valuation.code.in_(deal_list)).order_by(valuation.market_cap.asc()).limit(
g.stocksnum)
# 得到市值最小的前stocksnum个的股票的财务数据,并取[code]列转换为list
df = get_fundamentals(my_query)
buy_list = list(df['code'])
return buy_list
# 设置交易策略
def market_open(context):
# 判断是否已到策略调整时间
if g.days % g.period == 0:
buylist = filter_stock(context)
# 判断账户中已持有的股票是否在上述buy_list,如果不在就卖出
count = 0
for stock in context.portfolio.positions:
if stock not in buylist:
order_target_value(stock, 0)
count += 1
print('卖出:', stock)
# 获取账户可用资金(同时判断可用资金),并设定买入金额
if count == 0:
position_per_stk = context.portfolio.cash/g.stocksnum
else:
position_per_stk = context.portfolio.cash/count
n_buylist = set(buylist).symmetric_difference(set(context.portfolio.positions))
for stock in n_buylist:
order_value(stock, position_per_stk)
# 非策略调整时间,则用来设置止损止盈
else:
for stock in context.portfolio.positions:
# 获得股票持仓成本
cost = context.portfolio.positions[stock].avg_cost
# 获得股票现价
now_price = context.portfolio.positions[stock].price
# 计算收益率
percentage = now_price / cost - 1
print(f'{stock}的收益率为{percentage}')
# 如果收益率小于20%,则清仓该只标的
if percentage < = -0.2:
order_target_value(stock, 0)
print(f'{stock}触发止损')
elif percentage >= 0.2:
order(stock,-(context.portfolio.positions[stock].closeable_amount/5))
print(f'{stock}触发止盈')
g.days += 1
2024-05-23