@@ -77,8 +77,8 @@ def get_daily_basic(sdt="20100101", edt="20240101"):
7777
7878 https://s0cqcxuy3p.feishu.cn/wiki/W5UYwk0qwiHWlxk2ngDcjxQKncg
7979 """
80- sdt = pd .to_datetime (sdt ). strftime ( "%Y%m%d" )
81- edt = pd .to_datetime (edt ). strftime ( "%Y%m%d" )
80+ sdt = pd .to_datetime (sdt )
81+ edt = pd .to_datetime (edt )
8282
8383 dates = czsc .get_trading_dates (sdt , edt )
8484 rows = []
@@ -129,6 +129,109 @@ def moneyflow_hsgt(start_date, end_date):
129129 return df
130130
131131
132+ def pro_bar_minutes (ts_code , sdt , edt , freq = "60min" , asset = "E" , adj = None ):
133+ """获取分钟线
134+
135+ https://tushare.pro/document/2?doc_id=109
136+
137+ :param ts_code: 标的代码
138+ :param sdt: 开始时间,精确到分钟
139+ :param edt: 结束时间,精确到分钟
140+ :param freq: 分钟周期,可选值 1min, 5min, 15min, 30min, 60min
141+ :param asset: 资产类别:E股票 I沪深指数 C数字货币 FT期货 FD基金 O期权 CB可转债(v1.2.39),默认E
142+ :param adj: 复权类型,None不复权,qfq:前复权,hfq:后复权
143+ :param raw_bar: 是否返回 RawBar 对象列表
144+ :return:
145+ """
146+ import tushare as ts
147+ from datetime import timedelta
148+ pro = dc
149+
150+ dt_fmt = "%Y%m%d"
151+
152+ sdt = pd .to_datetime (sdt ).strftime (dt_fmt )
153+ edt = pd .to_datetime (edt ).strftime (dt_fmt )
154+
155+ klines = []
156+ end_dt = pd .to_datetime (edt )
157+ dt1 = pd .to_datetime (sdt )
158+ delta = timedelta (days = 20 * int (freq .replace ("min" , "" )))
159+ dt2 = dt1 + delta
160+ while dt1 < end_dt :
161+ df = ts .pro_bar (
162+ ts_code = ts_code ,
163+ asset = asset ,
164+ freq = freq ,
165+ start_date = dt1 .strftime (dt_fmt ),
166+ end_date = dt2 .strftime (dt_fmt ),
167+ )
168+ klines .append (df )
169+ dt1 = dt2
170+ dt2 = dt1 + delta
171+ print (f"pro_bar_minutes: { ts_code } - { asset } - { freq } - { dt1 } - { dt2 } - { len (df )} " )
172+
173+ df_klines = pd .concat (klines , ignore_index = True )
174+ kline = df_klines .drop_duplicates ("trade_time" ).sort_values ("trade_time" , ascending = True , ignore_index = True )
175+ kline ["trade_time" ] = pd .to_datetime (kline ["trade_time" ], format = dt_fmt )
176+ kline ["dt" ] = kline ["trade_time" ]
177+ float_cols = ["open" , "close" , "high" , "low" , "vol" , "amount" ]
178+ kline [float_cols ] = kline [float_cols ].astype ("float32" )
179+ kline ["avg_price" ] = kline ["amount" ] / kline ["vol" ]
180+
181+ # 删除9:30的K线
182+ kline ["keep" ] = kline ["trade_time" ].apply (lambda x : 0 if x .hour == 9 and x .minute == 30 else 1 )
183+ kline = kline [kline ["keep" ] == 1 ]
184+
185+ # 删除没有成交量的K线
186+ kline = kline [kline ["vol" ] > 0 ]
187+ kline .drop (["keep" ], axis = 1 , inplace = True )
188+
189+ start_date = pd .to_datetime (sdt )
190+ end_date = pd .to_datetime (edt )
191+ kline = kline [(kline ["trade_time" ] >= start_date ) & (kline ["trade_time" ] <= end_date )]
192+ kline = kline .reset_index (drop = True )
193+ kline ["trade_date" ] = kline .trade_time .apply (lambda x : x .strftime (dt_fmt ))
194+
195+ if asset == "E" :
196+ # https://tushare.pro/document/2?doc_id=28
197+ factor = pro .adj_factor (ts_code = ts_code , start_date = sdt , end_date = edt )
198+ elif asset == "FD" :
199+ # https://tushare.pro/document/2?doc_id=199
200+ factor = pro .fund_adj (ts_code = ts_code , start_date = sdt , end_date = edt )
201+ else :
202+ factor = pd .DataFrame ()
203+
204+ if len (factor ) > 0 :
205+ # 处理复权因子缺失的情况:前值填充
206+ df1 = pd .DataFrame ({"trade_date" : kline ["trade_date" ].unique ().tolist ()})
207+ factor = df1 .merge (factor , on = ["trade_date" ], how = "left" ).ffill ().bfill ()
208+ factor = factor .sort_values ("trade_date" , ignore_index = True )
209+
210+ print (f"pro_bar_minutes: { ts_code } - { asset } - 复权因子长度 = { len (factor )} " )
211+
212+ # 复权行情说明:https://tushare.pro/document/2?doc_id=146
213+ if len (factor ) > 0 and adj and adj == "qfq" :
214+ # 前复权 = 当日收盘价 × 当日复权因子 / 最新复权因子
215+ latest_factor = factor .iloc [- 1 ]["adj_factor" ]
216+ adj_map = {row ["trade_date" ]: row ["adj_factor" ] for _ , row in factor .iterrows ()}
217+ for col in ["open" , "close" , "high" , "low" ]:
218+ kline [col ] = kline .apply (lambda x : x [col ] * adj_map [x ["trade_date" ]] / latest_factor , axis = 1 )
219+
220+ if len (factor ) > 0 and adj and adj == "hfq" :
221+ # 后复权 = 当日收盘价 × 当日复权因子
222+ adj_map = {row ["trade_date" ]: row ["adj_factor" ] for _ , row in factor .iterrows ()}
223+ for col in ["open" , "close" , "high" , "low" ]:
224+ kline [col ] = kline .apply (lambda x : x [col ] * adj_map [x ["trade_date" ]], axis = 1 )
225+
226+ if sdt :
227+ kline = kline [kline ["trade_time" ] >= pd .to_datetime (sdt )]
228+ if edt :
229+ kline = kline [kline ["trade_time" ] <= pd .to_datetime (edt )]
230+
231+ kline = kline .reset_index (drop = True )
232+ return kline
233+
234+
132235def get_symbols (step = "all" ):
133236 """获取标的代码"""
134237 stocks = dc .stock_basic (exchange = "" , list_status = "L" , fields = "ts_code,symbol,name,area,industry,list_date" )
0 commit comments