mirror of
https://github.com/kernc/backtesting.py.git
synced 2024-01-28 15:29:30 +03:00
MNT: Replace flake8 with ruff
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
- run: pip install -U .[test]
|
||||
|
||||
- if: matrix.test-type == 'lint'
|
||||
run: flake8
|
||||
run: ruff backtesting
|
||||
- if: matrix.test-type == 'lint'
|
||||
run: mypy backtesting
|
||||
- if: matrix.test-type == 'lint'
|
||||
|
||||
@@ -53,10 +53,10 @@ itself find their way back to the community.
|
||||
# API Reference Documentation
|
||||
"""
|
||||
try:
|
||||
from ._version import version as __version__ # noqa: F401
|
||||
from ._version import version as __version__
|
||||
except ImportError:
|
||||
__version__ = '?.?.?' # Package not installed
|
||||
|
||||
from .backtesting import Backtest, Strategy # noqa: F401
|
||||
from . import lib # noqa: F401
|
||||
from ._plotting import set_bokeh_output # noqa: F401
|
||||
from .backtesting import Backtest, Strategy # noqa: F401
|
||||
|
||||
@@ -257,7 +257,7 @@ this.labels = this.labels || formatter.doFormat(ticks
|
||||
return this.labels[index] || "";
|
||||
''')
|
||||
|
||||
NBSP = '\N{NBSP}' * 4
|
||||
NBSP = '\N{NBSP}' * 4 # noqa: E999
|
||||
ohlc_extreme_values = df[['High', 'Low']].copy(deep=False)
|
||||
ohlc_tooltips = [
|
||||
('x, y', NBSP.join(('$index',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List, TYPE_CHECKING, Union
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import warnings
|
||||
from typing import Dict, List, Optional, Sequence, Union, cast
|
||||
from numbers import Number
|
||||
from typing import Dict, List, Optional, Sequence, Union, cast
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
@@ -9,11 +9,11 @@ import multiprocessing as mp
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from concurrent.futures import ProcessPoolExecutor, as_completed
|
||||
from copy import copy
|
||||
from functools import lru_cache, partial
|
||||
from itertools import repeat, product, chain, compress
|
||||
from itertools import chain, compress, product, repeat
|
||||
from math import copysign
|
||||
from numbers import Number
|
||||
from typing import Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
|
||||
@@ -29,7 +29,7 @@ except ImportError:
|
||||
def _tqdm(seq, **_):
|
||||
return seq
|
||||
|
||||
from ._plotting import plot
|
||||
from ._plotting import plot # noqa: I001
|
||||
from ._stats import compute_stats
|
||||
from ._util import _as_str, _Indicator, _Data, try_
|
||||
|
||||
@@ -75,7 +75,7 @@ class Strategy(metaclass=ABCMeta):
|
||||
setattr(self, k, v)
|
||||
return params
|
||||
|
||||
def I(self, # noqa: E741, E743
|
||||
def I(self, # noqa: E743
|
||||
func: Callable, *args,
|
||||
name=None, plot=True, overlay=None, color=None, scatter=False,
|
||||
**kwargs) -> np.ndarray:
|
||||
@@ -126,7 +126,7 @@ class Strategy(metaclass=ABCMeta):
|
||||
try:
|
||||
value = func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
raise RuntimeError(f'Indicator "{name}" errored with exception: {e}')
|
||||
raise RuntimeError(f'Indicator "{name}" error') from e
|
||||
|
||||
if isinstance(value, pd.DataFrame):
|
||||
value = value.values.T
|
||||
@@ -190,7 +190,7 @@ class Strategy(metaclass=ABCMeta):
|
||||
super().next()
|
||||
"""
|
||||
|
||||
class __FULL_EQUITY(float):
|
||||
class __FULL_EQUITY(float): # noqa: N801
|
||||
def __repr__(self): return '.9999'
|
||||
_FULL_EQUITY = __FULL_EQUITY(1 - sys.float_info.epsilon)
|
||||
|
||||
@@ -664,7 +664,7 @@ class Trade:
|
||||
if order:
|
||||
order.cancel()
|
||||
if price:
|
||||
kwargs = dict(stop=price) if type == 'sl' else dict(limit=price)
|
||||
kwargs = {'stop': price} if type == 'sl' else {'limit': price}
|
||||
order = self.__broker.new_order(-self.size, trade=self, **kwargs)
|
||||
setattr(self, attr, order)
|
||||
|
||||
@@ -1409,13 +1409,13 @@ class Backtest:
|
||||
Tuple[pd.Series, pd.Series, dict]]:
|
||||
try:
|
||||
from skopt import forest_minimize
|
||||
from skopt.space import Integer, Real, Categorical
|
||||
from skopt.utils import use_named_args
|
||||
from skopt.callbacks import DeltaXStopper
|
||||
from skopt.learning import ExtraTreesRegressor
|
||||
from skopt.space import Categorical, Integer, Real
|
||||
from skopt.utils import use_named_args
|
||||
except ImportError:
|
||||
raise ImportError("Need package 'scikit-optimize' for method='skopt'. "
|
||||
"pip install scikit-optimize")
|
||||
"pip install scikit-optimize") from None
|
||||
|
||||
nonlocal max_tries
|
||||
max_tries = (200 if max_tries is None else
|
||||
|
||||
@@ -12,18 +12,18 @@ Please raise ideas for additions to this collection on the [issue tracker].
|
||||
"""
|
||||
|
||||
from collections import OrderedDict
|
||||
from inspect import currentframe
|
||||
from itertools import compress
|
||||
from numbers import Number
|
||||
from inspect import currentframe
|
||||
from typing import Sequence, Optional, Union, Callable
|
||||
from typing import Callable, Optional, Sequence, Union
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from .backtesting import Strategy
|
||||
from ._plotting import plot_heatmaps as _plot_heatmaps
|
||||
from ._stats import compute_stats as _compute_stats
|
||||
from ._util import _Array, _as_str
|
||||
from .backtesting import Strategy
|
||||
|
||||
__pdoc__ = {}
|
||||
|
||||
@@ -461,8 +461,8 @@ class TrailingStrategy(Strategy):
|
||||
Set the lookback period for computing ATR. The default value
|
||||
of 100 ensures a _stable_ ATR.
|
||||
"""
|
||||
h, l, c_prev = self.data.High, self.data.Low, pd.Series(self.data.Close).shift(1)
|
||||
tr = np.max([h - l, (c_prev - h).abs(), (c_prev - l).abs()], axis=0)
|
||||
hi, lo, c_prev = self.data.High, self.data.Low, pd.Series(self.data.Close).shift(1)
|
||||
tr = np.max([hi - lo, (c_prev - hi).abs(), (c_prev - lo).abs()], axis=0)
|
||||
atr = pd.Series(tr).rolling(periods).mean().bfill().values
|
||||
self.__atr = atr
|
||||
|
||||
|
||||
@@ -18,21 +18,21 @@ from pandas.testing import assert_frame_equal
|
||||
|
||||
from backtesting import Backtest, Strategy
|
||||
from backtesting._stats import compute_drawdown_duration_peaks
|
||||
from backtesting._util import _Array, _as_str, _Indicator, try_
|
||||
from backtesting.lib import (
|
||||
OHLCV_AGG,
|
||||
SignalStrategy,
|
||||
TrailingStrategy,
|
||||
barssince,
|
||||
compute_stats,
|
||||
cross,
|
||||
crossover,
|
||||
quantile,
|
||||
SignalStrategy,
|
||||
TrailingStrategy,
|
||||
resample_apply,
|
||||
plot_heatmaps,
|
||||
quantile,
|
||||
random_ohlc_data,
|
||||
resample_apply,
|
||||
)
|
||||
from backtesting.test import GOOG, EURUSD, SMA
|
||||
from backtesting._util import _Indicator, _as_str, _Array, try_
|
||||
from backtesting.test import EURUSD, GOOG, SMA
|
||||
|
||||
SHORT_DATA = GOOG.iloc[:20] # Short data for fast tests with no indicator lag
|
||||
|
||||
@@ -146,7 +146,7 @@ class TestBacktest(TestCase):
|
||||
|
||||
assert float(self.data.Close) == self.data.Close[-1]
|
||||
|
||||
def next(self, FIVE_DAYS=pd.Timedelta('3 days')):
|
||||
def next(self, _FEW_DAYS=pd.Timedelta('3 days')): # noqa: N803
|
||||
assert self.equity >= 0
|
||||
|
||||
assert isinstance(self.sma, _Indicator)
|
||||
@@ -193,7 +193,7 @@ class TestBacktest(TestCase):
|
||||
assert self.position.size < 0
|
||||
|
||||
trade = self.trades[0]
|
||||
if self.data.index[-1] - self.data.index[trade.entry_bar] > FIVE_DAYS:
|
||||
if self.data.index[-1] - self.data.index[trade.entry_bar] > _FEW_DAYS:
|
||||
assert not trade.is_long
|
||||
assert trade.is_short
|
||||
assert trade.size < 0
|
||||
@@ -290,7 +290,7 @@ class TestBacktest(TestCase):
|
||||
except TypeError:
|
||||
return a == b
|
||||
|
||||
diff = {key: print(key) or value
|
||||
diff = {key: print(key) or value # noqa: T201
|
||||
for key, value in stats.filter(regex='^[^_]').items()
|
||||
if not almost_equal(value, expected[key])}
|
||||
self.assertDictEqual(diff, {})
|
||||
@@ -510,7 +510,7 @@ class TestStrategy(TestCase):
|
||||
class TestOptimize(TestCase):
|
||||
def test_optimize(self):
|
||||
bt = Backtest(GOOG.iloc[:100], SmaCross)
|
||||
OPT_PARAMS = dict(fast=range(2, 5, 2), slow=[2, 5, 7, 9])
|
||||
OPT_PARAMS = {'fast': range(2, 5, 2), 'slow': [2, 5, 7, 9]}
|
||||
|
||||
self.assertRaises(ValueError, bt.optimize)
|
||||
self.assertRaises(ValueError, bt.optimize, maximize='missing key', **OPT_PARAMS)
|
||||
@@ -556,7 +556,7 @@ class TestOptimize(TestCase):
|
||||
|
||||
def test_max_tries(self):
|
||||
bt = Backtest(GOOG.iloc[:100], SmaCross)
|
||||
OPT_PARAMS = dict(fast=range(2, 10, 2), slow=[2, 5, 7, 9])
|
||||
OPT_PARAMS = {'fast': range(2, 10, 2), 'slow': [2, 5, 7, 9]}
|
||||
for method, max_tries, random_state in (('grid', 5, 0),
|
||||
('grid', .3, 0),
|
||||
('skopt', 7, 0),
|
||||
@@ -589,7 +589,7 @@ class TestOptimize(TestCase):
|
||||
|
||||
def test_multiprocessing_windows_spawn(self):
|
||||
df = GOOG.iloc[:100]
|
||||
kw = dict(fast=[10])
|
||||
kw = {'fast': [10]}
|
||||
|
||||
stats1 = Backtest(df, SmaCross).optimize(**kw)
|
||||
with patch('multiprocessing.get_start_method', lambda **_: 'spawn'):
|
||||
@@ -633,7 +633,7 @@ class TestPlot(TestCase):
|
||||
bt = Backtest(GOOG.iloc[:100], SmaCross)
|
||||
bt.run()
|
||||
with _tempfile() as f:
|
||||
for p in dict(plot_volume=False,
|
||||
for p in dict(plot_volume=False, # noqa: C408
|
||||
plot_equity=False,
|
||||
plot_return=True,
|
||||
plot_pl=False,
|
||||
@@ -722,8 +722,8 @@ class TestPlot(TestCase):
|
||||
self.assertEqual(stats['Equity Final [$]'], 0)
|
||||
self.assertEqual(len(trades), 2)
|
||||
assert trades[['EntryTime', 'ExitTime']].equals(
|
||||
pd.DataFrame(dict(EntryTime=pd.to_datetime(['2006-11-01', '2008-11-14']),
|
||||
ExitTime=pd.to_datetime(['2007-10-31', '2009-09-21']))))
|
||||
pd.DataFrame({'EntryTime': pd.to_datetime(['2006-11-01', '2008-11-14']),
|
||||
'ExitTime': pd.to_datetime(['2007-10-31', '2009-09-21'])}))
|
||||
assert trades['PnL'].round().equals(pd.Series([23469., -34420.]))
|
||||
|
||||
with _tempfile() as f:
|
||||
|
||||
37
pyproject.toml
Normal file
37
pyproject.toml
Normal file
@@ -0,0 +1,37 @@
|
||||
[tool.ruff]
|
||||
exclude = [
|
||||
'.git',
|
||||
'.eggs',
|
||||
'__pycache__',
|
||||
'doc/examples',
|
||||
]
|
||||
ignore = [
|
||||
'U006',
|
||||
'U007',
|
||||
'U009',
|
||||
'N802',
|
||||
'N806',
|
||||
'C901',
|
||||
'B008',
|
||||
'B011',
|
||||
]
|
||||
line-length = 100
|
||||
select = [
|
||||
'I',
|
||||
'E',
|
||||
'F',
|
||||
'W',
|
||||
'U',
|
||||
'N',
|
||||
'C',
|
||||
'B',
|
||||
'T',
|
||||
'M',
|
||||
'YTT',
|
||||
]
|
||||
|
||||
[tool.ruff.pep8-naming]
|
||||
ignore-names = [
|
||||
'l',
|
||||
'h',
|
||||
]
|
||||
Reference in New Issue
Block a user