huggingface112 commited on
Commit
48b892d
1 Parent(s): 65eba49

refactor fetch benchmark_profile

Browse files
Files changed (1) hide show
  1. api.py +25 -67
api.py CHANGED
@@ -183,7 +183,7 @@ def update_portfolio_profile(stocks: List[dict], current_p: pd.DataFrame = None)
183
  profile_df = pd.DataFrame(stocks)
184
  profile_df['sector'] = None
185
  profile_df['aggregate_sector'] = None
186
-
187
  # add display_name
188
  try:
189
  with create_engine(db_url).connect() as conn:
@@ -267,83 +267,41 @@ def fetch_stocks_price(**params):
267
  stocks_df.rename(columns={'code': 'ticker'}, inplace=True)
268
  return stocks_df
269
 
270
-
271
-
272
  @auth_api
273
- def update_benchmark_profile(start_date: datetime,
274
- end_date: datetime,
275
- benchmark="000905.XSHG",
276
- delta_time=timedelta(days=7),
277
- profile: pd.DataFrame = None
278
- ) -> tuple[pd.DataFrame, List[str]]:
279
- """
280
- update benchmark profile with available new update between start_date and end_date,
281
- if no profile is given, create a new profile for that duration
282
- the minimum period is 1 day
283
-
284
- return an updated dataframe if new update exist
285
-
286
- Returns:
287
- pd.DateFrame -- ticker | date | weight | sector | aggregate_sector | display_name | name
288
- date| weight | display_name | actual_data(the date in the api database) | ticker
289
- """
290
- error_message = []
291
  results = []
 
292
  while start_date < end_date:
293
  try:
294
  date_str = start_date.strftime('%Y-%m-%d')
295
  result = jq.get_index_weights(benchmark, date=date_str)
296
  results.append(result)
297
-
298
  except Exception as e:
299
- error_message.append(f'Error when fetching {benchmark}\n\
300
  update on {date_str} is missing\n\
301
  {e}')
302
-
303
  start_date += delta_time
304
- # inlcude end date
305
- try:
306
- date_str = end_date.strftime('%Y-%m-%d')
307
- result = jq.get_index_weights(benchmark, date=date_str)
308
- results.append(result)
309
- except Exception as e:
310
- error_message.append(f'Error when fetching {benchmark}\n\
311
- update on {date_str} is missing\n\
312
- {e}')
313
- # no update
314
- if len(results) == 0:
315
- return profile, error_message
316
-
317
- # concate all result
318
  update_df = pd.concat(results)
319
  update_df['ticker'] = update_df.index
320
- update_df['sector'] = None
321
- update_df['aggregate_sector'] = None
322
- update_df.reset_index(drop=True, inplace=True)
323
  update_df['date'] = pd.to_datetime(update_df['date'])
324
- # add display_name
325
- try:
326
- with create_engine(db_url).connect() as conn:
327
- info_df = pd.read_sql('all_stock_info', conn)
328
- update_df = pd.merge(
329
- update_df, info_df[['ticker', 'name']], on='ticker', how='left')
330
- except Exception as e:
331
- # if all_stock_info not exist then create a name column manually
332
- update_df['name'] = None
333
- error_message.append(f'create_portfolio \n{e}')
334
-
335
- # combine with existing profile if given
336
- if profile is not None:
337
- update_df = pd.concat([profile, update_df])
338
-
339
- # remove duplicate result
340
- update_df.drop_duplicates(
341
- subset=['ticker', 'date'], keep='last', inplace=True)
342
-
343
- # update deail
344
- merged_df = utils.add_details_to_stock_df(update_df)
345
- # error_message.extend(incoming_error)
346
-
347
- return merged_df, error_message
348
-
349
- # get_all_stocks_detail()
 
183
  profile_df = pd.DataFrame(stocks)
184
  profile_df['sector'] = None
185
  profile_df['aggregate_sector'] = None
186
+
187
  # add display_name
188
  try:
189
  with create_engine(db_url).connect() as conn:
 
267
  stocks_df.rename(columns={'code': 'ticker'}, inplace=True)
268
  return stocks_df
269
 
 
 
270
  @auth_api
271
+ def fetch_benchmark_profile(start_date: datetime, end_date: datetime, delta_time=timedelta(days=30), benchmark="000905.XSHG"):
272
+ '''
273
+ fetch benchmark profile from start_date to end_date with delta_time
274
+
275
+ Parameters
276
+ ----------
277
+ start_date : datetime
278
+ start date of the period include start date
279
+ end_date : datetime
280
+ end date of the period include end date
281
+ delta_time : timedelta, optional
282
+ the default is 30 days since the jq api only update index weight once every month
283
+ '''
284
+ if end_date < start_date:
285
+ raise Exception('end_date must be greater than start_date')
286
+
 
 
287
  results = []
288
+ # handle end_date == start_date
289
  while start_date < end_date:
290
  try:
291
  date_str = start_date.strftime('%Y-%m-%d')
292
  result = jq.get_index_weights(benchmark, date=date_str)
293
  results.append(result)
 
294
  except Exception as e:
295
+ print(f'Error when fetching {benchmark}\n\
296
  update on {date_str} is missing\n\
297
  {e}')
 
298
  start_date += delta_time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  update_df = pd.concat(results)
300
  update_df['ticker'] = update_df.index
 
 
 
301
  update_df['date'] = pd.to_datetime(update_df['date'])
302
+ update_df.rename({'date': 'time'}, inplace=True, axis=1)
303
+ # remove duplicate row
304
+ update_df = update_df.drop_duplicates(
305
+ subset=['ticker', 'time'], keep='last')
306
+ update_df.reset_index(drop=True, inplace=True)
307
+ return update_df