Skip to content

Commit 4c60488

Browse files
arkershawkernc
andauthored
BUG: Restore original scale in FractionalBacktest plot (#1247)
* Restore original unit of fractional backtest for results/plot. * Add pytest requirement. * Add modified values to test. * Revert "Add pytest requirement." This reverts commit 9092e19. * Add test for indicator scaling. * Test params for fractional backtest plot. * Refactor scaling of OHLC data to avoid duplication. * REF: Fractionalize data df JIT before bt.run * TST: Simplify test * TST: Simplify another test --------- Co-authored-by: arkershaw <[email protected]> Co-authored-by: Kernc <[email protected]>
1 parent ce74a34 commit 4c60488

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

backtesting/lib.py

+23-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from ._plotting import plot_heatmaps as _plot_heatmaps
2727
from ._stats import compute_stats as _compute_stats
28-
from ._util import SharedMemoryManager, _Array, _as_str, _batch, _tqdm
28+
from ._util import SharedMemoryManager, _Array, _as_str, _batch, _tqdm, patch
2929
from .backtesting import Backtest, Strategy
3030

3131
__pdoc__ = {}
@@ -533,10 +533,28 @@ def __init__(self,
533533
'Use `FractionalBacktest(..., fractional_unit=)`.',
534534
category=DeprecationWarning, stacklevel=2)
535535
fractional_unit = 1 / kwargs.pop('satoshi')
536-
data = data.copy()
537-
data[['Open', 'High', 'Low', 'Close']] *= fractional_unit
538-
data['Volume'] /= fractional_unit
539-
super().__init__(data, *args, **kwargs)
536+
self._fractional_unit = fractional_unit
537+
with warnings.catch_warnings(record=True):
538+
warnings.filterwarnings(action='ignore', message='frac')
539+
super().__init__(data, *args, **kwargs)
540+
541+
def run(self, **kwargs) -> pd.Series:
542+
data = self._data.copy()
543+
data[['Open', 'High', 'Low', 'Close']] *= self._fractional_unit
544+
data['Volume'] /= self._fractional_unit
545+
with patch(self, '_data', data):
546+
result = super().run(**kwargs)
547+
548+
trades: pd.DataFrame = result['_trades']
549+
trades['Size'] *= self._fractional_unit
550+
trades[['EntryPrice', 'ExitPrice', 'TP', 'SL']] /= self._fractional_unit
551+
552+
indicators = result['_strategy']._indicators
553+
for indicator in indicators:
554+
if indicator._opts['overlay']:
555+
indicator /= self._fractional_unit
556+
557+
return result
540558

541559

542560
# Prevent pdoc3 documenting __init__ signature of Strategy subclasses

backtesting/test/_test.py

+5
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,11 @@ def test_FractionalBacktest(self):
934934
ubtc_bt = FractionalBacktest(BTCUSD['2015':], SmaCross, fractional_unit=1 / 1e6, cash=100)
935935
stats = ubtc_bt.run(fast=2, slow=3)
936936
self.assertEqual(stats['# Trades'], 41)
937+
trades = stats['_trades']
938+
self.assertEqual(len(trades), 41)
939+
trade = trades.iloc[0]
940+
self.assertAlmostEqual(trade['EntryPrice'], 236.69)
941+
self.assertAlmostEqual(stats['_strategy']._indicators[0][trade['EntryBar']], 234.14)
937942

938943
def test_MultiBacktest(self):
939944
import backtesting

0 commit comments

Comments
 (0)