plotguy 2.1.7__tar.gz → 2.1.8__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.1.7
3
+ Version: 2.1.8
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -11,14 +11,16 @@ import zlib
11
11
  import requests
12
12
  import pandas as pd
13
13
  import numpy as np
14
+ import io
14
15
 
15
16
  from .equity_curves import *
16
17
  from .signals import *
17
18
  from .aggregate import *
18
19
  from .components import *
19
20
  import itertools
21
+ from bs4 import BeautifulSoup
20
22
 
21
- def get_all_para_combination(para_dict, backtest_attribute, df_dict, sec_profile, manager_list):
23
+ def get_all_para_combination(para_dict, backtest_attribute, df_dict, sec_profile, manager_list, count_down=False):
22
24
 
23
25
  risk_free_rate = get_risk_free_rate(backtest_attribute['start_date'], backtest_attribute['end_date'])
24
26
 
@@ -60,11 +62,12 @@ def get_all_para_combination(para_dict, backtest_attribute, df_dict, sec_profile
60
62
 
61
63
  all_para_combination[ref_code] = para_combination
62
64
 
63
- print('5 second countdown before running backtest()')
64
- for i in range(5):
65
- print(5 - i)
66
- time.sleep(1)
67
- print(0)
65
+ if count_down:
66
+ print('5 second countdown before running backtest()')
67
+ for i in range(5):
68
+ print(5 - i)
69
+ time.sleep(1)
70
+ print(0)
68
71
 
69
72
  print(datetime.datetime.now().strftime('%H:%M:%S'), 'start running backtest()')
70
73
 
@@ -75,8 +78,6 @@ def generate_or_read_backtest_result(read_only, mp_mode, number_of_core, manager
75
78
 
76
79
  if read_only and os.path.isfile('backtest_result.parquet'):
77
80
  backtest_result_df = pd.read_parquet('backtest_result.parquet')
78
- #backtest_result_df = backtest_result_df[backtest_result_df.index.isin(all_para_combination.keys())]
79
-
80
81
  else:
81
82
  t1 = datetime.datetime.now()
82
83
  if mp_mode:
@@ -117,6 +118,7 @@ def save_backtest_result(df, para_combination_item):
117
118
  risk_free_rate = para_combination['risk_free_rate']
118
119
  default_market_price = para_combination['default_market_price']
119
120
  intraday = para_combination['intraday']
121
+ long_short = para_combination['long_short']
120
122
 
121
123
  total_commission = df['commission'].sum()
122
124
 
@@ -149,10 +151,10 @@ def save_backtest_result(df, para_combination_item):
149
151
 
150
152
  price_return_on_capital = price_net_profit / df_daily.at[df_daily.index[0], 'price']
151
153
  price_annualized_return = (np.sign(1 + price_return_on_capital) * np.abs(1 + price_return_on_capital)) ** (
152
- 365 / holding_period_day) - 1
154
+ 365 / holding_period_day) - 1
153
155
  price_annualized_std = price_pct_series.std() * math.sqrt(365)
154
156
  price_annualized_sr = (
155
- price_annualized_return - risk_free_rate / 100) / price_annualized_std if price_annualized_std != 0 else 0
157
+ price_annualized_return - risk_free_rate / 100) / price_annualized_std if price_annualized_std != 0 else 0
156
158
  price_net_profit_to_mdd = price_net_profit / price_mdd_dollar if price_mdd_dollar != 0 else 0
157
159
 
158
160
  price_return_on_capital = round(100 * price_return_on_capital, 2)
@@ -257,10 +259,10 @@ def save_backtest_result(df, para_combination_item):
257
259
 
258
260
  equity_return_on_capital = equity_net_profit / df.at[df.index[0], 'equity_value']
259
261
  equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (
260
- 365 / holding_period_day) - 1
262
+ 365 / holding_period_day) - 1
261
263
  equity_annualized_std = equity_pct_series.std() * math.sqrt(365)
262
264
  equity_annualized_sr = (
263
- equity_annualized_return - risk_free_rate / 100) / equity_annualized_std if equity_annualized_std != 0 else 0
265
+ equity_annualized_return - risk_free_rate / 100) / equity_annualized_std if equity_annualized_std != 0 else 0
264
266
  equity_net_profit_to_mdd = equity_net_profit / equity_mdd_dollar if equity_mdd_dollar != 0 else 0
265
267
 
266
268
  equity_return_on_capital = round(100 * equity_return_on_capital, 2)
@@ -269,7 +271,11 @@ def save_backtest_result(df, para_combination_item):
269
271
  equity_annualized_sr = round(equity_annualized_sr, 2)
270
272
  equity_net_profit_to_mdd = round(100 * equity_net_profit_to_mdd, 2)
271
273
 
272
- return_on_capital_diff = equity_annualized_return - price_annualized_return
274
+ if long_short == 'short':
275
+ return_on_capital_diff = equity_annualized_return - (-1) * price_annualized_return
276
+ else:
277
+ ### consider both long and long_short ###
278
+ return_on_capital_diff = equity_annualized_return - price_annualized_return
273
279
 
274
280
  if intraday:
275
281
  df = df[['price', 'equity_value']]
@@ -343,8 +349,11 @@ def get_risk_free_rate(start_date, end_date):
343
349
  else:
344
350
  risk_free_rate = get_geometric_mean_of_yearly_rate(start_date_year, end_date_year)
345
351
  except:
346
- risk_free_rate = 2 # if network error, set rate to 2 %
347
- print('Network error. Risk free rate: {:.2f} %'.format(risk_free_rate))
352
+ try:
353
+ risk_free_rate = get_geometric_mean_of_yearly_rate_backup(start_date_year, end_date_year)
354
+ except:
355
+ risk_free_rate = 2 # if network error, set rate to 2 %
356
+ print('Network error. Risk free rate: {:.2f} %'.format(risk_free_rate))
348
357
 
349
358
  return risk_free_rate
350
359
 
@@ -379,9 +388,9 @@ def get_latest_fed_fund_rate():
379
388
  return fed_funds_rate
380
389
 
381
390
 
382
- def get_geometric_mean_of_yearly_rate(start_year, end_year): # backtest period
391
+ def get_geometric_mean_of_yearly_rate(start_year, end_year):
383
392
  url = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=DTB3"
384
- response = requests.get(url)
393
+ response = requests.get(url, timeout=10)
385
394
  data = response.text.split("\n")[:-1]
386
395
  data = [row.split(",") for row in data]
387
396
  df = pd.DataFrame(data[1:], columns=data[0])
@@ -389,6 +398,35 @@ def get_geometric_mean_of_yearly_rate(start_year, end_year): # backtest period
389
398
  df["date"] = pd.to_datetime(df["date"])
390
399
  df["risk_free_rate"] = pd.to_numeric(df["risk_free_rate"], errors='coerce')
391
400
  df.dropna(subset=['risk_free_rate'], inplace=True)
401
+ print('Got Federal Funds Rate from stlouisfed.org')
402
+
403
+ risk_free_rate_history_yearly = df.resample("A", on="date").mean()
404
+ risk_free_rate_history_yearly = risk_free_rate_history_yearly.round(3)
405
+
406
+ # show only start between start_year and end_year
407
+ risk_free_rate_history_yearly = risk_free_rate_history_yearly[
408
+ risk_free_rate_history_yearly.index.year >= start_year]
409
+ risk_free_rate_history_yearly = risk_free_rate_history_yearly[risk_free_rate_history_yearly.index.year <= end_year]
410
+
411
+ fed_fund_rate_geometric_mean = np.exp(np.log(risk_free_rate_history_yearly["risk_free_rate"]).mean())
412
+ fed_fund_rate_geometric_mean = round(fed_fund_rate_geometric_mean, 2)
413
+ print("Federal Funds Rate Geometric mean from {} to {}: {} %".format(start_year, end_year,
414
+ fed_fund_rate_geometric_mean))
415
+
416
+ return fed_fund_rate_geometric_mean
417
+
418
+ def get_geometric_mean_of_yearly_rate_backup(start_year, end_year):
419
+ url = '/get_fred'
420
+ my_headers = {'token': '3f52e8c4-8c49-4c9a-8c57-1e4e9f6b0a40'}
421
+ my_main_url = "http://120.26.40.125:8080"
422
+ response = requests.get(f'{my_main_url}{url}', headers=my_headers)
423
+ data_str = response.content.decode('utf-8')
424
+ data_io = io.StringIO(data_str)
425
+ df = pd.read_csv(data_io)
426
+ df = df.rename(columns={'value' : 'risk_free_rate'})
427
+ df["date"] = pd.to_datetime(df["date"])
428
+ df.dropna(subset=['risk_free_rate'], inplace=True)
429
+ print('Got Federal Funds Rate from backup source')
392
430
 
393
431
  risk_free_rate_history_yearly = df.resample("A", on="date").mean()
394
432
  risk_free_rate_history_yearly = risk_free_rate_history_yearly.round(3)
@@ -316,7 +316,7 @@ class Components:
316
316
  result_df['equity_annualized_std'] = result_df['equity_annualized_std'].apply(lambda x: f"{x:,.2f} %")
317
317
  result_df['equity_annualized_sr'] = result_df['equity_annualized_sr'].apply(lambda x: f"{x:,.2f}")
318
318
 
319
- result_df['return_on_capital_diff'] = result_df['return_on_capital_diff'].apply(lambda x: f"{x:,.0f}")
319
+ result_df['return_on_capital_diff'] = result_df['return_on_capital_diff'].apply(lambda x: f"{x:,.0f} %")
320
320
 
321
321
  result_df['price_mdd_dollar'] = result_df['price_mdd_dollar'].apply(lambda x: f"{int(x):,}")
322
322
  result_df['price_mdd_pct'] = result_df['price_mdd_pct'].apply(lambda x: f"{x:,.2f} %")
@@ -798,73 +798,73 @@ class Components:
798
798
  saved_strategies_path = os.path.join(str_dir, 'saved_strategies.parquet')
799
799
  saved_strategies_df = pd.read_parquet(saved_strategies_path)
800
800
 
801
- if len(saved_strategies_df) > 1:
802
- for i, row in saved_strategies_df.iterrows():
803
- equity_path = os.path.join(str_dir, row["equity_curve_folder"], str(row['ref_code']) + '.parquet')
804
-
805
- yearly_stats_string = row['yearly_stats_string']
806
- para_keys_str = row['para_keys_str']
807
- para_keys_list = para_keys_str.split('|')
808
-
809
- parameters = {}
810
- for para_keys in para_keys_list:
811
- parameters[para_keys] = str(row[para_keys])
812
-
813
- equity_curve_dict = {}
814
-
815
- equity_curve_dict['folder'] = str_dir
816
- equity_curve_dict['backtest_name'] = row['backtest_name']
817
- equity_curve_dict['equity_path'] = equity_path
818
- equity_curve_dict['parameters'] = parameters
819
-
820
- equity_curve_dict['performance'] = {
821
- 'initial_capital': row['initial_capital'],
822
- 'sharpe_ratio': row['equity_annualized_sr'],
823
- 'annualized_return': row['equity_annualized_return'],
824
- 'net_profit_to_mdd': row['equity_net_profit_to_mdd'],
825
- 'net_profit': row['equity_net_profit'],
826
- 'mdd_dollar': row['equity_mdd_dollar'],
827
- 'mdd_pct': row['equity_mdd_pct'],
828
- 'num_of_trade': row['num_of_trade'],
829
- 'num_of_win': row['num_of_win'],
830
- 'return_on_capital': row['equity_return_on_capital'],
831
- 'total_commission': row['total_commission'],
832
- }
833
-
834
- ref_code = str(row['ref_code'])
835
- equity_curve_dict['ref_code'] = ref_code
836
-
837
- yearly_stats_dict = {}
838
- years_data = yearly_stats_string.split("|")
839
-
840
- for year_data in years_data:
841
- parts = year_data.split(",")
842
- year = parts[0]
843
- yearly_stats_dict[year] = {}
844
-
845
- for item in parts[1:]:
846
- key, value = item.split(":")
847
- yearly_stats_dict[year][key] = float(value)
848
-
849
- for idx, (year, value) in enumerate(yearly_stats_dict.items()):
850
- year_trade_count = value['year_trade_count']
851
- year_win_rate = value['year_win_rate']
852
- year_return = value['year_return']
853
-
854
- year_win_count = year_trade_count * year_win_rate * 0.01
855
-
856
- ### dont remove ###
857
- # year_trade_count = "{:d}".format(int(year_trade_count))
858
- # year_win_count = "{:d}".format(int(year_win_count))
859
- # year_win_rate = "{:d}%".format(int(year_win_rate))
860
- # year_return = "{:.2f} %".format(int(year_return))
861
-
862
- equity_curve_dict['performance'][f'{year} Count'] = year_trade_count
863
- equity_curve_dict['performance'][f'{year} Win Rate'] = year_win_rate
864
- equity_curve_dict['performance'][f'{year} Win Count'] = year_win_count
865
- equity_curve_dict['performance'][f'{year} Return'] = year_return
866
-
867
- equity_curves_dict_list.append(equity_curve_dict)
801
+ for i, row in saved_strategies_df.iterrows():
802
+ equity_path = os.path.join(str_dir, row["equity_curve_folder"], str(row['ref_code']) + '.parquet')
803
+ #df_equity = pd.read_parquet(equity_path)
804
+
805
+ yearly_stats_string = row['yearly_stats_string']
806
+ para_keys_str = row['para_keys_str']
807
+ para_keys_list = para_keys_str.split('|')
808
+
809
+ parameters = {}
810
+ for para_keys in para_keys_list:
811
+ parameters[para_keys] = str(row[para_keys])
812
+
813
+ equity_curve_dict = {}
814
+
815
+ equity_curve_dict['folder'] = str_dir
816
+ equity_curve_dict['backtest_name'] = row['backtest_name']
817
+ equity_curve_dict['equity_path'] = equity_path
818
+ equity_curve_dict['parameters'] = parameters
819
+
820
+ equity_curve_dict['performance'] = {
821
+ 'initial_capital': row['initial_capital'],
822
+ 'sharpe_ratio': row['equity_annualized_sr'],
823
+ 'annualized_return': row['equity_annualized_return'],
824
+ 'net_profit_to_mdd': row['equity_net_profit_to_mdd'],
825
+ 'net_profit': row['equity_net_profit'],
826
+ 'mdd_dollar': row['equity_mdd_dollar'],
827
+ 'mdd_pct': row['equity_mdd_pct'],
828
+ 'num_of_trade': row['num_of_trade'],
829
+ 'num_of_win': row['num_of_win'],
830
+ 'return_on_capital': row['equity_return_on_capital'],
831
+ 'total_commission': row['total_commission'],
832
+ }
833
+
834
+ ref_code = str(row['ref_code'])
835
+ equity_curve_dict['ref_code'] = ref_code
836
+
837
+ yearly_stats_dict = {}
838
+ years_data = yearly_stats_string.split("|")
839
+
840
+ for year_data in years_data:
841
+ parts = year_data.split(",")
842
+ year = parts[0]
843
+ yearly_stats_dict[year] = {}
844
+
845
+ for item in parts[1:]:
846
+ key, value = item.split(":")
847
+ yearly_stats_dict[year][key] = float(value)
848
+
849
+ for idx, (year, value) in enumerate(yearly_stats_dict.items()):
850
+ year_trade_count = value['year_trade_count']
851
+ year_win_rate = value['year_win_rate']
852
+ year_return = value['year_return']
853
+
854
+ year_win_count = year_trade_count * year_win_rate * 0.01
855
+
856
+ ### dont remove ###
857
+ # year_trade_count = "{:d}".format(int(year_trade_count))
858
+ # year_win_count = "{:d}".format(int(year_win_count))
859
+ # year_win_rate = "{:d}%".format(int(year_win_rate))
860
+ # year_return = "{:.2f} %".format(int(year_return))
861
+
862
+ equity_curve_dict['performance'][f'{year} Count'] = year_trade_count
863
+ equity_curve_dict['performance'][f'{year} Win Rate'] = year_win_rate
864
+ equity_curve_dict['performance'][f'{year} Win Count'] = year_win_count
865
+ equity_curve_dict['performance'][f'{year} Return'] = year_return
866
+
867
+ equity_curves_dict_list.append(equity_curve_dict)
868
868
 
869
869
  line_colour = []
870
870
  for c in range(len(equity_curves_dict_list)):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.1.7
3
+ Version: 2.1.8
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.1.7",
8
+ version="2.1.8",
9
9
  author="Plotguy Team",
10
10
  author_email="plotguy.info@gmail.com",
11
11
  description="Plotguy",
File without changes
File without changes
File without changes
File without changes