plotguy 2.3.0__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -0,0 +1 @@
1
+ from .Database import *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="plotguy",
8
- version="2.3.0",
8
+ version="2.3.2",
9
9
  author="Plotguy Team",
10
10
  author_email="plotguy.info@gmail.com",
11
11
  description="Plotguy",
@@ -1,545 +0,0 @@
1
- import warnings
2
- warnings.simplefilter("ignore", UserWarning)
3
- #warnings.simplefilter("ignore", RuntimeWarning)
4
-
5
- import datetime
6
- import os
7
- import sys
8
- import copy
9
- import multiprocessing as mp
10
- import time
11
- import zlib
12
- import requests
13
- import pandas as pd
14
- import numpy as np
15
- import io
16
- import re
17
-
18
- from .equity_curves import *
19
- from .signals import *
20
- from .aggregate import *
21
- from .components import *
22
- import itertools
23
- from bs4 import BeautifulSoup
24
-
25
- def get_all_para_combination(para_dict, backtest_attribute, df_dict, sec_profile, manager_list, count_down=False):
26
-
27
- risk_free_rate = get_risk_free_rate(backtest_attribute['start_date'], backtest_attribute['end_date'])
28
-
29
- freq = backtest_attribute['freq']
30
-
31
- intraday = True if freq != '1D' else False
32
- if intraday:
33
- if not 'summary_mode' in backtest_attribute:
34
- backtest_attribute['summary_mode'] = True
35
- backtest_attribute['intraday'] = True
36
- else:
37
- backtest_attribute['summary_mode'] = False
38
- backtest_attribute['intraday'] = False
39
-
40
- backtest_attribute['risk_free_rate'] = risk_free_rate
41
-
42
- para_keys = para_dict.keys()
43
- para_values = para_dict.values()
44
- para_list = list(itertools.product(*para_values))
45
- para_keys_str = '|'.join(para_keys)
46
-
47
- print('number of combination:', len(para_list))
48
-
49
- all_combinations = list(itertools.product(*para_values))
50
- all_para_combination = {}
51
-
52
- for combination in all_combinations:
53
- para_combination = dict(zip(para_keys, combination))
54
- para_combination.update(backtest_attribute)
55
- para_combination['manager_list'] = manager_list
56
-
57
- concatenated_values = ''.join(map(str, para_combination.values())).encode('utf-8')
58
- ref_code = zlib.crc32(concatenated_values)
59
-
60
- code = para_combination['code']
61
- para_combination['df'] = df_dict[code]
62
- para_combination['sec_profile'] = sec_profile
63
- para_combination['para_keys_str'] = para_keys_str
64
-
65
- all_para_combination[ref_code] = para_combination
66
-
67
- if count_down:
68
- print('5 second countdown before running backtest()')
69
- for i in range(5):
70
- print(5 - i)
71
- time.sleep(1)
72
- print(0)
73
-
74
- print(datetime.datetime.now().strftime('%H:%M:%S'), 'start running backtest()')
75
-
76
- return all_para_combination
77
-
78
- def generate_or_read_backtest_result(read_only, mp_mode, number_of_core, manager_list
79
- ,all_para_combination, backtest):
80
-
81
- if read_only and os.path.isfile('backtest_result.parquet'):
82
- backtest_result_df = pd.read_parquet('backtest_result.parquet')
83
- else:
84
- t1 = datetime.datetime.now()
85
- if mp_mode:
86
- pool = mp.Pool(processes=number_of_core)
87
- pool.map(backtest, all_para_combination.items())
88
- pool.close()
89
- else:
90
- for para_combination_item in all_para_combination.items():
91
- backtest(para_combination_item)
92
-
93
- backtest_result_df = pd.DataFrame(list(manager_list))
94
- backtest_result_df = backtest_result_df.set_index('ref_code')
95
-
96
- if os.path.isfile('backtest_result.parquet'):
97
- old_backtest_result_df = pd.read_parquet('backtest_result.parquet')
98
- backtest_result_df = pd.concat([backtest_result_df, old_backtest_result_df])
99
- backtest_result_df = backtest_result_df[~backtest_result_df.index.duplicated(keep='last')]
100
-
101
- backtest_result_df.to_parquet('backtest_result.parquet')
102
-
103
- print('backtest time used:', (datetime.datetime.now() - t1).seconds, 'seconds')
104
-
105
- backtest_result_df = backtest_result_df[backtest_result_df.index.isin(all_para_combination.keys())]
106
-
107
- return backtest_result_df
108
-
109
- def get_source_data_path(data_folder, code, freq):
110
- file_path = os.path.join(data_folder, code + '_' + freq + '.parquet')
111
- return file_path
112
-
113
-
114
- def save_backtest_result(df, para_combination_item):
115
-
116
- ref_code, para_combination = para_combination_item
117
-
118
- equity_curve_folder = para_combination['equity_curve_folder']
119
- manager_list = para_combination['manager_list']
120
- risk_free_rate = para_combination['risk_free_rate']
121
- default_market_price = para_combination['default_market_price']
122
- intraday = para_combination['intraday']
123
- long_short = para_combination['long_short']
124
-
125
- total_commission = df['commission'].sum()
126
-
127
- df = df[[default_market_price, 'action', 'trd_side', 'equity_value']]
128
- df = df.rename(columns={default_market_price: 'price'})
129
-
130
- eqiuty_curve_save_path = os.path.join('', equity_curve_folder, f'{ref_code}.parquet')
131
- ##############################################################
132
-
133
- if default_market_price == 'close':
134
- agg_price = 'last'
135
- elif default_market_price == 'open':
136
- agg_price = 'first'
137
- ### for intraday ###
138
- if intraday:
139
- df_daily = df.resample('D').agg({'price': agg_price})
140
- #df_daily = df.resample('D').agg({'price': agg_price, 'equity_value': agg_price})
141
- df_daily = df_daily[df_daily['price'].notna()]
142
- else:
143
- df_daily = df
144
-
145
- ########### price result ###############
146
- df_daily['running_max'] = df_daily['price'].cummax()
147
- df_daily['dd_dollar'] = df_daily['running_max'] - df_daily['price']
148
- df_daily['dd_pct'] = df_daily['dd_dollar'] / df_daily['running_max'] * 100
149
- price_mdd_dollar = df_daily['dd_dollar'].max()
150
- price_mdd_pct = df_daily['dd_pct'].max()
151
-
152
- price_pct_series = df_daily['price'].pct_change().dropna()
153
- price_net_profit = df_daily.at[df_daily.index[-1], 'price'] - df_daily.at[df_daily.index[0], 'price']
154
- holding_period_day = (df_daily.index[-1].date() - df_daily.index[0].date()).days
155
-
156
- price_return_on_capital = price_net_profit / df_daily.at[df_daily.index[0], 'price']
157
- price_annualized_return = (np.sign(1 + price_return_on_capital) * np.abs(1 + price_return_on_capital)) ** (
158
- 365 / holding_period_day) - 1
159
- price_annualized_std = price_pct_series.std() * math.sqrt(365)
160
- price_annualized_sr = (
161
- price_annualized_return - risk_free_rate / 100) / price_annualized_std if price_annualized_std != 0 else 0
162
- price_net_profit_to_mdd = price_net_profit / price_mdd_dollar if price_mdd_dollar != 0 else 0
163
-
164
- price_return_on_capital = round(100 * price_return_on_capital, 2)
165
- price_annualized_return = round(100 * price_annualized_return, 2)
166
- price_annualized_std = round(100 * price_annualized_std, 2)
167
- price_annualized_sr = round(price_annualized_sr, 2)
168
- price_net_profit_to_mdd = round(100 * price_net_profit_to_mdd, 2)
169
-
170
- last_action = df['action'].iloc[-1]
171
- if last_action == 'open':
172
- df = df.drop(df.index[-1])
173
- df_count = df[(df['trd_side'] == 'BUY') | (df['trd_side'] == 'SELL_SHORT')].copy()
174
-
175
- if len(df_count) == 0:
176
- num_of_trade = 0
177
- equity_net_profit = 0
178
- equity_return_on_capital = 0
179
- equity_annualized_return = 0
180
- equity_annualized_std = 0
181
- equity_annualized_sr = 0
182
- equity_net_profit_to_mdd = np.inf
183
- equity_mdd_dollar = 0
184
- equity_mdd_pct = 0
185
-
186
- num_of_win = 0
187
- num_of_trade = 0
188
- win_rate = 0
189
- yearly_stats_string = ''
190
-
191
- cov_return = 0
192
- cov_count = 0
193
- total_commission = 0
194
-
195
- start_year = df.index[0].year
196
- end_year = df.index[-1].year
197
-
198
- yearly_stats_string = ''
199
- for year in range(start_year, end_year + 1):
200
- yearly_stats_string += f'{year},year_trade_count:0.00,year_win_rate:00.00,year_return:-00.00|'
201
-
202
- yearly_stats_string = yearly_stats_string[:-1]
203
- correlation = 0
204
-
205
- elif len(df_count) > 0:
206
-
207
- ########### by year count, win rate and return ###############
208
- start_year = df.index[0].year
209
- end_year = df.index[-1].year
210
-
211
- num_of_trade = len(df_count)
212
- df_count = pd.concat([df_count, df[df['trd_side'] != ''].tail(1)])
213
- df_count['realized_pnl'] = df_count['equity_value'] - df_count['equity_value'].shift(1)
214
- df_count['win_trade'] = df_count['realized_pnl'] >= 0
215
-
216
- num_of_win = df_count['win_trade'].sum()
217
- win_rate = round(100 * num_of_win / num_of_trade, 2)
218
-
219
- yearly_stats = df_count.groupby(df_count.index.year).agg(
220
- year_pnl=('realized_pnl', 'sum'),
221
- year_win_count=('win_trade', 'sum'),
222
- year_trade_count=('realized_pnl', 'count'),
223
- year_start_equity_value=('equity_value', 'first'))
224
- yearly_stats['year_return'] = 100 * (yearly_stats['year_pnl'] / yearly_stats['year_start_equity_value'])
225
- yearly_stats['year_win_rate'] = 100 * (yearly_stats['year_win_count'] / yearly_stats['year_trade_count'])
226
-
227
- all_years = range(start_year, end_year + 1)
228
- current_years = yearly_stats.index
229
- missing_years = [year for year in all_years if year not in current_years]
230
-
231
- #if year_start_equity_value = df.at[df.index[0], 'equity_value'
232
- missing_rows = pd.DataFrame(
233
- { "year_pnl": 0,
234
- "year_win_count": 0,
235
- "year_trade_count": 0,
236
- "year_start_equity_value": 0,
237
- "year_return": 0,
238
- "year_win_rate": 0,
239
- }, index=missing_years)
240
- missing_rows.index.name = "datetime"
241
-
242
- yearly_stats = pd.concat([yearly_stats, missing_rows]).sort_index()
243
-
244
- cov_return = yearly_stats['year_return'].std() / yearly_stats['year_return'].mean() if yearly_stats['year_return'].mean() != 0 else 0
245
- cov_count = yearly_stats['year_trade_count'].std() / yearly_stats['year_trade_count'].mean() if yearly_stats['year_trade_count'].mean() != 0 else 0
246
-
247
- yearly_stats = yearly_stats.applymap(lambda x: f'{x:.2f}')
248
- formatted_rows = yearly_stats.apply(
249
- lambda
250
- row: f"{row.name},{'year_trade_count'}:{row['year_trade_count']},{'year_win_rate'}:{row['year_win_rate']},{'year_return'}:{row['year_return']}",
251
- axis=1)
252
-
253
- yearly_stats_string = "|".join(formatted_rows)
254
-
255
- ######## resample to daily #############
256
- if 'summary_mode' in para_combination:
257
- if para_combination['summary_mode']:
258
- eqiuty_curve_non_summary_save_path = os.path.join('', equity_curve_folder, f'{ref_code}_non-summary-intraday.parquet')
259
- df.to_parquet(eqiuty_curve_non_summary_save_path)
260
-
261
- ########### equity value result ###############
262
-
263
- ### for intraday ###
264
- if intraday:
265
- df = df_count.resample('D').agg({'equity_value': 'last'})
266
- df = pd.concat([df_daily, df], axis=1)
267
- df = df[df['price'].notna()]
268
- df['equity_value'] = df['equity_value'].ffill()
269
- df['equity_value'] = df['equity_value'].bfill()
270
-
271
- df['equity_value'] = df['equity_value'].astype(np.int32)
272
- ######################
273
-
274
- df['running_max'] = df['equity_value'].cummax()
275
- df['dd_dollar'] = df['running_max'] - df['equity_value']
276
- df['dd_pct'] = df['dd_dollar'] / df['running_max'] * 100
277
- equity_mdd_dollar = df['dd_dollar'].max()
278
- equity_mdd_pct = df['dd_pct'].max()
279
-
280
- holding_period_day = (df.index[-1].date() - df.index[0].date()).days
281
- equity_pct_series = df['equity_value'].pct_change().dropna()
282
- equity_net_profit = df.at[df.index[-1], 'equity_value'] - df.at[df.index[0], 'equity_value']
283
-
284
- equity_return_on_capital = equity_net_profit / df.at[df.index[0], 'equity_value']
285
- if 1 + equity_return_on_capital > 0:
286
- equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (365 / holding_period_day) - 1
287
- else:
288
- equity_annualized_return = -1
289
-
290
- equity_annualized_std = equity_pct_series.std() * math.sqrt(365)
291
- equity_annualized_sr = (
292
- equity_annualized_return - risk_free_rate / 100) / equity_annualized_std if equity_annualized_std != 0 else 0
293
- equity_net_profit_to_mdd = equity_net_profit / equity_mdd_dollar if equity_mdd_dollar != 0 else 0
294
-
295
- equity_return_on_capital = round(100 * equity_return_on_capital, 2)
296
- equity_annualized_return = round(100 * equity_annualized_return, 2)
297
- equity_annualized_std = round(100 * equity_annualized_std, 2)
298
- equity_annualized_sr = round(equity_annualized_sr, 2)
299
- equity_net_profit_to_mdd = round(100 * equity_net_profit_to_mdd, 2)
300
-
301
- df['equity_return'] = df['equity_value'].pct_change() * 100
302
- df['price_return'] = df['price'].pct_change() * 100
303
-
304
- correlation = df['equity_return'].corr(df['price_return'])
305
-
306
- if long_short == 'short':
307
- return_on_capital_diff = equity_annualized_return - (-1) * price_annualized_return
308
- correlation *= -1
309
- else:
310
- ### consider both long and long_short ###
311
- return_on_capital_diff = equity_annualized_return - price_annualized_return
312
-
313
- if intraday:
314
- df = df[['price', 'equity_value']]
315
- elif not intraday:
316
- df = df[['price', 'action', 'trd_side', 'equity_value']]
317
- df.to_parquet(eqiuty_curve_save_path)
318
- print('backtest is runnung...', eqiuty_curve_save_path)
319
-
320
- ####################################
321
- del para_combination['df']
322
- del para_combination['sec_profile']
323
- del para_combination['manager_list']
324
-
325
- cov_return = round(cov_return, 2)
326
- cov_count = round(cov_count, 2)
327
- total_commission = int(round(total_commission))
328
- correlation = round(correlation, 3)
329
-
330
- backtest_result_dict = {
331
- 'ref_code': ref_code,
332
- 'num_of_trade': num_of_trade,
333
-
334
- 'equity_net_profit': equity_net_profit,
335
- 'equity_return_on_capital': equity_return_on_capital,
336
- 'equity_annualized_return': equity_annualized_return,
337
- 'equity_annualized_std': equity_annualized_std,
338
- 'equity_annualized_sr': equity_annualized_sr,
339
- 'equity_net_profit_to_mdd': equity_net_profit_to_mdd,
340
- 'equity_mdd_dollar': equity_mdd_dollar,
341
- 'equity_mdd_pct': equity_mdd_pct,
342
-
343
- 'price_net_profit' : price_net_profit,
344
- 'price_return_on_capital': price_return_on_capital,
345
- 'price_annualized_return': price_annualized_return,
346
- 'price_annualized_std': price_annualized_std,
347
- 'price_annualized_sr': price_annualized_sr,
348
- 'price_net_profit_to_mdd': price_net_profit_to_mdd,
349
- 'price_mdd_dollar': price_mdd_dollar,
350
- 'price_mdd_pct': price_mdd_pct,
351
-
352
- 'return_on_capital_diff': return_on_capital_diff,
353
-
354
- 'num_of_win': num_of_win,
355
- 'num_of_trade': num_of_trade,
356
- 'win_rate': win_rate,
357
- 'yearly_stats_string': yearly_stats_string,
358
- 'cov_return': cov_return,
359
- 'cov_count': cov_count,
360
- 'correlation': correlation,
361
- 'total_commission': total_commission
362
- }
363
-
364
- para_combination.update(backtest_result_dict)
365
- manager_list.append(para_combination)
366
-
367
-
368
- ########################################################################################################
369
- ########################################################################################################
370
- ########################################################################################################
371
-
372
- def get_risk_free_rate(start_date, end_date):
373
-
374
- if '-' in start_date:
375
- start_date_year = datetime.datetime.strptime(start_date, '%Y-%m-%d').year
376
- end_date_year = datetime.datetime.strptime(end_date, '%Y-%m-%d').year
377
- else:
378
- start_date_year = datetime.datetime.strptime(start_date, '%Y%m%d').year
379
- end_date_year = datetime.datetime.strptime(end_date, '%Y%m%d').year
380
-
381
- try:
382
- if end_date_year == start_date_year and end_date_year == datetime.datetime.now().year:
383
- risk_free_rate = get_latest_fed_fund_rate()
384
- else:
385
- risk_free_rate = get_geometric_mean_of_yearly_rate(start_date_year, end_date_year)
386
- except:
387
- try:
388
- risk_free_rate = get_geometric_mean_of_yearly_rate_backup(start_date_year, end_date_year)
389
- except:
390
- risk_free_rate = 2 # if network error, set rate to 2 %
391
- print('Network error. Risk free rate: {:.2f} %'.format(risk_free_rate))
392
-
393
- return risk_free_rate
394
-
395
-
396
- # def plot_signal_analysis(py_filename, output_folder, start_date, end_date, para_dict, signal_settings):
397
- # app = signals.Signals(py_filename, output_folder, start_date, end_date, para_dict, generate_backtest_output_path,
398
- # signal_settings)
399
- #
400
- # return app
401
-
402
-
403
- def plot(mode, backtest_result_df = None, number_of_curves=20, filter_list= []):
404
-
405
- if mode == 'equity_curves':
406
- if len(filter_list) > 0: filter_list = convert_filter_list(filter_list)
407
- app = equity_curves.Plot(backtest_result_df, number_of_curves, filter_list)
408
-
409
- if mode == 'aggregate':
410
- app = aggregate.Aggregate()
411
-
412
- return app
413
-
414
- def convert_filter_list(filter_list):
415
- '''
416
- filter string as follows
417
- equity_return_on_capital eg: 50% --> 50
418
- equity_annualized_return eg: 50% --> 50
419
- return_on_capital_diff eg: 50% --> 50
420
- equity_annualized_sr eg: 0.9
421
- equity_mdd_pct eg: 50% --> 50
422
- num_of_trade eg: 10
423
- cov_count eg: 1
424
- cov_return eg: 1
425
- correlation eg: 0.5
426
- win_rate eg: 50% --> 50
427
- '''
428
-
429
- for i in range(len(filter_list)):
430
- filter = filter_list[i]
431
- pattern = r'([a-zA-Z_]+)([<>=]+)(-?\d+\.?\d*)'
432
- match = re.match(pattern, filter)
433
-
434
- filter_list[i] = [match.group(1), match.group(2), match.group(3)]
435
-
436
- return filter_list
437
-
438
- def get_latest_fed_fund_rate():
439
- url = "https://fred.stlouisfed.org/series/FEDFUNDS"
440
- page = requests.get(url)
441
- soup = BeautifulSoup(page.content, "html.parser")
442
-
443
- fed_funds_rate = soup.find("span", class_="series-meta-observation-value").text
444
- print("Latest Federal Funds Rate:", fed_funds_rate, '%')
445
- # fed_funds_rate = float(fed_funds_rate) / 100
446
- fed_funds_rate = round(float(fed_funds_rate), 2)
447
- return fed_funds_rate
448
-
449
-
450
- def get_geometric_mean_of_yearly_rate(start_year, end_year):
451
- url = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=DTB3"
452
- response = requests.get(url, timeout=10)
453
- data = response.text.split("\n")[:-1]
454
- data = [row.split(",") for row in data]
455
- df = pd.DataFrame(data[1:], columns=data[0])
456
- df.columns = ["date", "risk_free_rate"]
457
- df["date"] = pd.to_datetime(df["date"])
458
- df["risk_free_rate"] = pd.to_numeric(df["risk_free_rate"], errors='coerce')
459
- df.dropna(subset=['risk_free_rate'], inplace=True)
460
- print('Got Federal Funds Rate from stlouisfed.org')
461
-
462
- risk_free_rate_history_yearly = df.resample("A", on="date").mean()
463
- risk_free_rate_history_yearly = risk_free_rate_history_yearly.round(3)
464
-
465
- # show only start between start_year and end_year
466
- risk_free_rate_history_yearly = risk_free_rate_history_yearly[
467
- risk_free_rate_history_yearly.index.year >= start_year]
468
- risk_free_rate_history_yearly = risk_free_rate_history_yearly[risk_free_rate_history_yearly.index.year <= end_year]
469
-
470
- fed_fund_rate_geometric_mean = np.exp(np.log(risk_free_rate_history_yearly["risk_free_rate"]).mean())
471
- fed_fund_rate_geometric_mean = round(fed_fund_rate_geometric_mean, 2)
472
- print("Federal Funds Rate Geometric mean from {} to {}: {} %".format(start_year, end_year,
473
- fed_fund_rate_geometric_mean))
474
-
475
- return fed_fund_rate_geometric_mean
476
-
477
- def get_geometric_mean_of_yearly_rate_backup(start_year, end_year):
478
- url = '/get_fred'
479
- my_headers = {'token': '3f52e8c4-8c49-4c9a-8c57-1e4e9f6b0a40'}
480
- my_main_url = "http://120.26.40.125:8080"
481
- response = requests.get(f'{my_main_url}{url}', headers=my_headers)
482
- data_str = response.content.decode('utf-8')
483
- data_io = io.StringIO(data_str)
484
- df = pd.read_csv(data_io)
485
- df = df.rename(columns={'value' : 'risk_free_rate'})
486
- df["date"] = pd.to_datetime(df["date"])
487
- df.dropna(subset=['risk_free_rate'], inplace=True)
488
- print('Got Federal Funds Rate from backup source')
489
-
490
- risk_free_rate_history_yearly = df.resample("A", on="date").mean()
491
- risk_free_rate_history_yearly = risk_free_rate_history_yearly.round(3)
492
-
493
- # show only start between start_year and end_year
494
- risk_free_rate_history_yearly = risk_free_rate_history_yearly[
495
- risk_free_rate_history_yearly.index.year >= start_year]
496
- risk_free_rate_history_yearly = risk_free_rate_history_yearly[risk_free_rate_history_yearly.index.year <= end_year]
497
-
498
- fed_fund_rate_geometric_mean = np.exp(np.log(risk_free_rate_history_yearly["risk_free_rate"]).mean())
499
- fed_fund_rate_geometric_mean = round(fed_fund_rate_geometric_mean, 2)
500
- print("Federal Funds Rate Geometric mean from {} to {}: {} %".format(start_year, end_year,
501
- fed_fund_rate_geometric_mean))
502
-
503
- return fed_fund_rate_geometric_mean
504
-
505
- def su_table_converter():
506
- all_str_dir = []
507
- for folder_name in os.listdir():
508
- if os.path.isfile(os.path.join(folder_name, 'saved_strategies.parquet')):
509
- all_str_dir.append(folder_name)
510
-
511
- su_dict = {'backtest_name': [], 'code': [], 'freq': [], 'para_items_str': [], 'initial_capital': [],
512
- 'equity_mdd_pct': []}
513
-
514
- for str_dir in all_str_dir:
515
- saved_strategies_path = os.path.join(str_dir, 'saved_strategies.parquet')
516
- saved_strategies_df = pd.read_parquet(saved_strategies_path)
517
- saved_strategies_df = saved_strategies_df.reset_index(drop=True)
518
-
519
- if len(saved_strategies_df.columns) > 1:
520
- for i, row in saved_strategies_df.iterrows():
521
- backtest_name = row['backtest_name']
522
- freq = row['freq']
523
- para_keys_str = row['para_keys_str']
524
- equity_mdd_pct = row['equity_mdd_pct']
525
- initial_capital = row['initial_capital']
526
-
527
- para_items_str = ''
528
- para_keys_str_list = para_keys_str.split('|')
529
- for para_key in para_keys_str_list:
530
- para_value = str(saved_strategies_df.at[i, para_key])
531
- if para_key == 'code':
532
- code = para_value
533
- else:
534
- para_items_str += para_key + '=' + para_value + '|'
535
- para_items_str = para_items_str[:-1]
536
-
537
- su_dict['backtest_name'].append(backtest_name)
538
- su_dict['code'].append(code)
539
- su_dict['freq'].append(freq)
540
- su_dict['para_items_str'].append(para_items_str)
541
- su_dict['equity_mdd_pct'].append(equity_mdd_pct)
542
- su_dict['initial_capital'].append(initial_capital)
543
-
544
- su_table = pd.DataFrame(su_dict)
545
- return su_table
File without changes
File without changes
File without changes
File without changes
File without changes