Skip to content

Commit a46d72a

Browse files
committed
BUG: Fix pandas insertion error on Windos
Fixes #21
1 parent 5bcaafd commit a46d72a

File tree

2 files changed

+27
-35
lines changed

2 files changed

+27
-35
lines changed

backtesting/backtesting.py

+26-34
Original file line numberDiff line numberDiff line change
@@ -891,46 +891,38 @@ def _round_timedelta(value, _period=_data_period(df)):
891891
return value.ceil(resolution)
892892

893893
s = pd.Series()
894-
s['Start'] = df.index[0]
895-
s['End'] = df.index[-1]
896-
# Assigning Timedeltas needs the key to exist beforehand,
897-
# otherwise the value is interpreted as nanosec *int*. See:
898-
# https://github.com/pandas-dev/pandas/issues/22717
899-
s['Duration'] = 0
900-
s['Duration'] = s.End - s.Start
894+
s.loc['Start'] = df.index[0]
895+
s.loc['End'] = df.index[-1]
896+
s.loc['Duration'] = s.End - s.Start
901897
exits = df['Exit Entry'] # After reindexed
902898
durations = (exits.dropna().index - df.index[exits.dropna().values.astype(int)]).to_series()
903-
s['Exposure [%]'] = np.nan_to_num(durations.sum() / (s['Duration'] or np.nan) * 100)
904-
s['Equity Final [$]'] = equity[-1]
905-
s['Equity Peak [$]'] = equity.max()
906-
s['Return [%]'] = (equity[-1] - equity[0]) / equity[0] * 100
899+
s.loc['Exposure [%]'] = np.nan_to_num(durations.sum() / (s.loc['Duration'] or np.nan) * 100)
900+
s.loc['Equity Final [$]'] = equity[-1]
901+
s.loc['Equity Peak [$]'] = equity.max()
902+
s.loc['Return [%]'] = (equity[-1] - equity[0]) / equity[0] * 100
907903
c = data.Close.values
908-
s['Buy & Hold Return [%]'] = abs(c[-1] - c[0]) / c[0] * 100 # long OR short
909-
s['Max. Drawdown [%]'] = max_dd = -np.nan_to_num(dd.max()) * 100
910-
s['Avg. Drawdown [%]'] = -dd_peaks.mean() * 100
911-
s['Max. Drawdown Duration'] = 0
912-
s['Max. Drawdown Duration'] = _round_timedelta(dd_dur.max())
913-
s['Avg. Drawdown Duration'] = 0
914-
s['Avg. Drawdown Duration'] = _round_timedelta(dd_dur.mean())
915-
s['# Trades'] = n_trades = pl.count()
916-
s['Win Rate [%]'] = win_rate = np.nan if not n_trades else (pl > 0).sum() / n_trades * 100
917-
s['Best Trade [%]'] = returns.max() * 100
918-
s['Worst Trade [%]'] = returns.min() * 100
904+
s.loc['Buy & Hold Return [%]'] = abs(c[-1] - c[0]) / c[0] * 100 # long OR short
905+
s.loc['Max. Drawdown [%]'] = max_dd = -np.nan_to_num(dd.max()) * 100
906+
s.loc['Avg. Drawdown [%]'] = -dd_peaks.mean() * 100
907+
s.loc['Max. Drawdown Duration'] = _round_timedelta(dd_dur.max())
908+
s.loc['Avg. Drawdown Duration'] = _round_timedelta(dd_dur.mean())
909+
s.loc['# Trades'] = n_trades = pl.count()
910+
s.loc['Win Rate [%]'] = win_rate = np.nan if not n_trades else (pl > 0).sum() / n_trades * 100 # noqa: E501
911+
s.loc['Best Trade [%]'] = returns.max() * 100
912+
s.loc['Worst Trade [%]'] = returns.min() * 100
919913
mean_return = returns.mean()
920-
s['Avg. Trade [%]'] = mean_return * 100
921-
s['Max. Trade Duration'] = 0
922-
s['Max. Trade Duration'] = _round_timedelta(durations.max())
923-
s['Avg. Trade Duration'] = 0
924-
s['Avg. Trade Duration'] = _round_timedelta(durations.mean())
925-
s['Expectancy [%]'] = ((returns[returns > 0].mean() * win_rate -
926-
returns[returns < 0].mean() * (100 - win_rate)))
914+
s.loc['Avg. Trade [%]'] = mean_return * 100
915+
s.loc['Max. Trade Duration'] = _round_timedelta(durations.max())
916+
s.loc['Avg. Trade Duration'] = _round_timedelta(durations.mean())
917+
s.loc['Expectancy [%]'] = ((returns[returns > 0].mean() * win_rate -
918+
returns[returns < 0].mean() * (100 - win_rate)))
927919
pl = pl.dropna()
928-
s['SQN'] = np.sqrt(n_trades) * pl.mean() / pl.std()
929-
s['Sharpe Ratio'] = mean_return / (returns.std() or np.nan)
930-
s['Sortino Ratio'] = mean_return / (returns[returns < 0].std() or np.nan)
931-
s['Calmar Ratio'] = mean_return / ((-max_dd / 100) or np.nan)
920+
s.loc['SQN'] = np.sqrt(n_trades) * pl.mean() / pl.std()
921+
s.loc['Sharpe Ratio'] = mean_return / (returns.std() or np.nan)
922+
s.loc['Sortino Ratio'] = mean_return / (returns[returns < 0].std() or np.nan)
923+
s.loc['Calmar Ratio'] = mean_return / ((-max_dd / 100) or np.nan)
932924

933-
s['_strategy'] = strategy
925+
s.loc['_strategy'] = strategy
934926
s._trade_data = df # Private API
935927
return s
936928

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
install_requires=[
3333
'typing ; python_version < "3.5"',
3434
'numpy',
35-
'pandas >= 0.21.0, != 0.25.0',
35+
'pandas >= 0.25.0, != 0.25.0',
3636
'bokeh >= 1.1.0',
3737
],
3838
extras_require={

0 commit comments

Comments
 (0)