求大神帮助,在直播间视频看到扒下来的,代码不全,能完善吗?
策略代码(不全)
1 import datetime
2 from collections import OrderedDict
3 import talib
4 #from MyOrder import *
5 from jqdata import *
6
7
8 # 初始化函数,设置基准和回测参数
9 def after_code_changed(context):
10 log.info(f'-------------after_code_changed----------------')
11 unschedule_all()
12
13 log.set_level('strategy' , 'info')
14 log.set_level("order'" , "error")
15 #设定基准
16 set_benchmark('000300.XSHG')
17 set_option('use_real_price',True) #开启动态复权模式
18 set_option("avoid_future_data",True)
19
20 #设定交易手续费
21 set_order_cost(ordercost(open_tax=0,close_tax=0.001,open_commisson=0.0003,close
22 close_today_commisson=0,min_commisson
23 set_order_cost(ordercost(open_tax=0,close_tax=0.001
24 close_today_commisson=0,min_commisson
25
26 g.stock_sum=4
27 g.max_industry_stocks=1
28 g.empty_position_day=[1215,1231,101,
29 #g.empty_position_day =[]
30
31 g.exclude_days=20 # 缓冲时间
32 g.limit_up_list =[]
33 g.sold_stock_record={} # 全局卖出记录
34 g.strategy_info ={'key':'0xiaosz','na
35
36 # run_monthly(adjustment,1,"10:50”)
37 run_daily(prepare,"9:28")
38 run_weekly(adjustment,1,"10:50")
39 run_weekly(adjustment,3,"14:20")
40 run_daily(check_limit_up,"14:50")
41 run_daily(print_position_info,"15:20")
42
43
44 def prepare(context):
45 log.info(f’-------开始处理 prepare----- 实际时间
46 hold_list =list(context.portfolio.positions.key
47 if hold_list:
48 df = get_price(hold_1ist, end_date=context.pl
49 fields=["close", "high_limit",
50 count=1,panel=False,fill_pal
51 g.limit_up_list =list(df[df["close"]== df[
52 else:
53 g.limit_up_list =[]
54
55 log.info(f'昨日涨停:{g.limit_up_list}')
56 #g.stock_sum=adjust_stock_num(context)
57
58
59 # 周调仓
60 def adjusrment(context):
61 log.info(f'-------开始处理 adjusrment-----实际')
62 #当前持仓
63 positions =context.portfolio.positions
64 log.info(f"当前持仓:{positions}”)
65
66 if empty_position_in_jan_apr(context):
67 return
68
69 stocks =[]
70
71 #Ⅰ= get_market_breadth(context)
72
73 stocks=select_stocks(context)
74 log.info(f"今日调仓代码:{stocks}”)
75
76 #卖出
77 for code in positions.keys():
78 if code not in stocks and code not in g.limit_up_list
79 close_position(context, code)
80
81 position_count =len(context.portfolio.position
82 if len(stocks)==0 or g.stock_sum - position_count==0:
83 return
84 buy_num =min(len(stocks),g.stock_sum -position_count)
85 value =context.portfolio.available_cash / buy_num
86 for security in stocks:
87 if security not in list(context.portfolio.positions.k
88 if open position(context.security.value):
89 if len(context.portfolio.position
90 break
91
92
93 def select_stocks(context):
94 month = context.current_dt.strftime("%Y-%m")
95 stocks = data_manager.get_data(
96 f"index_stocks_399101_{month}",
97 get_index_stocks,
98 "399101.XSHE",
99 context.current_dt
100 )
101 stocks =filter_basic_stock(context,stocks)
102 stocks =filter_recently_sold(context, stocks)
103 # stocks =filter_limitup_stock(context,, stocks)
105 q= query(
106 valuation.code
107 ).filter(
108 valuation.code.in_(stocks),
109 # indicator.adjusted_profit >0,
110 ).order_by(
111 valuation.market_cap.asc() # 根据市值从小到大排序
112 )
113 stocks = get_fundamentals(q)["code"].tolist()
114
115 #使用拆分后的函数
116 selected_stocks=filter_stocks_by_industry(contexe,stocks)
117 selected_stocks=selected_stocks[:g.stock_sum]
118 return selected_stocks
119
120
121 def filter_stocks_by_industry(context, stocks):
122 # if len(list(context.portfolio.positions.keys()))>=2:
123 # return stocks
124 industry_info = getstockIndustry(stocks)
125 selected_stocks =[]
126 industry_count ={}
127 for stock in stocks:
128 industry = industry_info[stock]
129 if industry not in industry_count:
130 industry_count[industry]=0
131 if industry_count[industry]< g.max_indus
132 selected_stocks.append(stock)
133 industry_count[industry]+=1
134 return selected_stocks
135
136
137 def getstockIndustry(stocks):
138 return pd.series({stock: info["sw_l1"]["industry_name:] for stock,
139 f"industry_{stocks}",get_industry, stocks
140 ).items()if"sw_l1" in info})
141
142
143 #1、4月空仓时============================
144 def empty_position_in_jan_apr(context):
145 current_month = context.current_dt.month
146 current_day = context.current_dt .day
147 current =current_month*100+ current_day
148 empty_day =g.empty_position_day
149 i=int(len(empty_day)/2)
150 for j in range(i):
151 if empty_day[j* 2]< = current< =e
152 for security in list(context.po
153 close_position(context, sec
154 return True
155 return False
156
157
158 #1-8 动态调仓代码
159 def adjust_stock_num(context):
160 ma_para=10 #设置MA参数
161 today = context.previous_date
162 start_date =today - datetime.timedelt
163 index_df = get_price('399101.XSHE',st
164 index_df['ma']= index_df['close'].ro
165 last_row=index_df.iloc[-1]
166 diff= last_row['close']- last_row['m
167 #根据差值结果返回数字
168 result=3 if diff >= 500 else\
169 3 if 200 < = diff < 500 else\
170 4 if -200 < = diff < 200 else\
171 5 if -500< = diff < -200 else\
172 6
173 return result
174
175
176 # 获取市场宽度
177 def get_market_breadth(context):
178 """
179 计算市场宽度指标:
180 1. 获取中证全指成分股
181 2. 计算20日均线
182 3. 统计行业偏离比例
183 4. 返回偏离度最高的行业
184 """
185
186 #指定日期防止未来数据
187 yesterday = context.previous_date
188 #获取初始列表
189 stocks = get_index_stocks("000985.xSHG")
190 count =1
191 h = get price(
192 stocks ,
193 end_date=yesterday,
194 frequency="ld"
195 fields=["close"],
196 count=count + 20,
197 pane]=False,
198 )
199 h["date"]= pd.DatetimeIndex(h.time).date
200 df_close =h.pivot(index="code",columns
201 #计算20日均线
202 df_ma20=df_close.rolling(window=20,ax
203 #计算偏离程度
204 df_bias =df_close.iloc[:,-count:]> df
205 df_bias["industry_name"]= getstockIndus
206 #计算行业偏离比例
207 df_ratio=((df bias.aroupbv("industry_name"
208 #获取偏离程度最高的行业
209 top_values = df_ratio.1oc[:, yesterday].
210 Ⅰ=top_values.index.tolist()
211
212 industries ={“银 行Ⅰ”,"煤炭Ⅰ”,"采掘Ⅰ",
213 return industries.intersection(Ⅰ)
214
215
216 def filter_basic_stock(context, stock_list):
217 current_data get_current_data()
218 stock_list =[
219 stock for stock in stock_list
220 if not(
221 stock.startswith(('3','68','4','8','9')
222 or current_data[stock].paused
223 or current_data[stock].is_st
224 or 'ST' in current_data[stock].name
225 or '*' in current_data[stock].name
226 or '退' in current_data[stock].name
227 or current_data[stock].day_open == current_data[stock].high_limit
228 or current_data[stock].day_open == current_data[stock].low_limit
229 or current_data[stock].1ast_price >= current_data[stock].high_limit
230 or current_data[stock],last_price < =current_data[stock].low_limit
231 or (context.current_dt.date()- get_security_info(stock).start_date
232 ) and current_data[stock].1ast_price < 30
233 ]
234 return stock_list
235
236
237 # 过滤20天内卖出的股票
238 def filter_recent1y_sold(context, stocks):
239 current_date = context.current_dt.date()
240 return[stock for stock in stocks if
241 stock not in g.sold_stock_record or
242
243
244 # 过滤近几日涨停的股票
245 def filter_limitup_stock(context,stock_list,day
246 df= get_price(
247 stock_list,
248 end_date=context.previous_date,
249 frequency="daily",
250 fields=["close", "high_limit"],
251 count=days,
252 panel=False,
253 )
254 df = df[df["close" == df["high_1imit"]]
255 filterd_stocks =df.code.drop_duplicates().tc
256 return[stock for stock in stock_list if stock
257
258
259 def filter_limitup_limitdown_stock(context, stock
260 current_data = get_current_data()
261 return [
262 stock
263 for stock in stock_list
264 if current_data[stock].last_price < current_data
265 current_data[stock].low_limit
266 ]
267
268
269 def check_limit_up(context):
270 sold_stocks =[]
271 if g.limit_up_list:
272 log.info(f'昨日有股票涨停:{g.limit_up_l
273 current_data = get_current_data()
274 for stock in g.limit_up_list:
275 if current_data[stock].last_price <
276 log.warn(f'{stock}涨停打开...
277 if close_position(context, stock)
278 sold_stocks.append(stock)
279
280 #卖出涨停后调仓
281 if sold_stocks:
282 position_count =len(context.portfolio.po
283 if g.stock_sum-position_count >0:
284 stocks=select_stocks(context)
285 log.info(f"今日调仓代码:{stocks}”)
286 if len(stocks)=0 or g.stock_sum -
287 return
288 buy_num = min(len(stocks),g.stock_su
289 value = context.portfolio.available_
290 for security in stocks:
291 if security not in list(context.p
292 if open_position(context, se
293 if len(context.portfolio.
294 break
295
296
297 def open_position(context, stock, value):
298 """买入执行"""
299 current_data = get_current_data()
300 price = current_data[stock].last_price
301 #计算可买数量
302 amount=int(value //price //100)*100 #
303 if amount< 100: #至少买1手
304 log.warn(f"资金不够买入{stock}{amount}!")
305 return
306
307 order =order_target(stock, amount)
308 log.warn(f"买入:{stock}{amount}股 @ {price
309 return order is not None and order.fi1led >0
310
311
312 def close_position(context, stock):
313 positions =context.portfolio.positions
314 current_price =positions[stock].price
315 avg_cost =positions[stock].avg_cost
316 order = order_target(stock, 0)
317 log.warn(f"卖出:{stock} 当前价:{current_pric
318 #更新全局卖出记录
319 g.so1d_stock_ecord[stock]= context .current_
320 return order is not None and order.filled ==
321
322
323 #复盘打印
324 def print_position_info(context):
325 print(f'{context.current_dt} s--------------------------
326 trades = get_trades()
327 for _trade in trades.values():
328 print('成交记录:’+str(_trade))
329 for position in list(context.portfolio.posit
330 securities =position.security
331 cost =position.avg_cost
332 price =position.price
333 ret=100*(price/cost-1)
334 value = position.value
335 amount = position.total_amount
336 print('代码:{}'.format(securities))
337 print('成本价:{}'.format(format(cost,
338 print('现价:{}'.format(price))
339 print('收益率:{}%'.format(format(ret,
340 print('持仓(股):{}'.format(amount))
341 print('市值:{}'.format(format(value,
342 print('--------------------------------------
343 print(f'{context.current_dt} e--------------
344
345
346 #中央数据管理器
347 class DataManager:
348 def _init_(self, max_cache_size=100):
349 self.cache =orderedpict()
350 self.max_cache_size = max_cache_size
351
352 def get_data(self, key, func,*args, **kwargs:
353 if key not in self.cache:
354 if len(self.cache)>= self.max_cache_
355 self.cache.popitem(last=False)
356 self.cache[key]= func(*args, **kwarg
357 se1f.cache.move_to_end(key)
358 return self.cache[key]
359
360
361 data_manager =DataManager()
362
2025-08-11