Skip to content

Commit 058d26b

Browse files
committed
Linting.
Add setuptools as dev dependency (mypy no longer bundles).
1 parent 26ebf04 commit 058d26b

File tree

8 files changed

+912
-869
lines changed

8 files changed

+912
-869
lines changed

poetry.lock

Lines changed: 868 additions & 833 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ isort = "^5.11.4"
2626
black = {extras = ["jupyter"], version = "^23.1.0"}
2727
docformatter = "^1.5.1"
2828
coverage = "^7.2.1"
29+
setuptools = "^69.0.3"
2930

3031
[tool.poetry.group.docs]
3132
optional = true

yabte/backtest/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# TODO: use absolute imports until mypyc fixes relative imports in __init__.py
22
# (https://github.com/mypyc/mypyc/issues/996)
3-
from yabte.backtest.asset import Asset, AssetDataFieldInfo, AssetName
3+
from yabte.backtest.asset import (
4+
ADFI_AVAILABLE_AT_CLOSE,
5+
ADFI_AVAILABLE_AT_OPEN,
6+
ADFI_REQUIRED,
7+
Asset,
8+
AssetDataFieldInfo,
9+
AssetName,
10+
)
411
from yabte.backtest.book import Book, BookMandate, BookName
512
from yabte.backtest.order import (
613
BasketOrder,
@@ -32,4 +39,7 @@
3239
"Trade",
3340
"Strategy",
3441
"StrategyRunner",
42+
"ADFI_AVAILABLE_AT_CLOSE",
43+
"ADFI_AVAILABLE_AT_OPEN",
44+
"ADFI_REQUIRED",
3545
]

yabte/backtest/asset.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from dataclasses import dataclass
22
from decimal import Decimal
3-
4-
# from enum import Flag, auto
53
from typing import TypeAlias
64

75
import pandas as pd
@@ -10,14 +8,11 @@
108
__all__ = ["Asset"]
119

1210

13-
# use normal class until mypy supports flags
14-
class AssetDataFieldInfo:
15-
AVAILABLE_AT_CLOSE: int = 1
16-
AVAILABLE_AT_OPEN: int = 2
17-
REQUIRED: int = 4
18-
19-
20-
_FI = AssetDataFieldInfo
11+
# use ints until mypyc supports IntFlag
12+
AssetDataFieldInfo = int
13+
ADFI_AVAILABLE_AT_CLOSE: int = 1
14+
ADFI_AVAILABLE_AT_OPEN: int = 2
15+
ADFI_REQUIRED: int = 4
2116

2217

2318
AssetName: TypeAlias = str
@@ -58,9 +53,12 @@ def round_quantity(self, quantity) -> Decimal:
5853
def intraday_traded_price(
5954
self, asset_day_data: pd.Series, size: Decimal | None = None
6055
) -> Decimal:
61-
"""Calculate price during market hours with given row of
62-
`asset_day_data` and the order `size`. The `size` can be used to
63-
determine a price from say, bid / ask spreads."""
56+
"""Calculate price during market hours with given row of `asset_day_data` and
57+
the order `size`.
58+
59+
The `size` can be used to
60+
determine a price from say, bid / ask spreads.
61+
"""
6462
raise NotImplementedError(
6563
"The intraday_traded_price method needs to be implemented."
6664
)
@@ -95,11 +93,11 @@ class Asset(AssetBase):
9593

9694
def data_fields(self) -> list[tuple[str, AssetDataFieldInfo]]:
9795
return [
98-
("High", _FI.AVAILABLE_AT_CLOSE),
99-
("Low", _FI.AVAILABLE_AT_CLOSE),
100-
("Open", _FI.AVAILABLE_AT_CLOSE | _FI.AVAILABLE_AT_OPEN),
101-
("Close", _FI.AVAILABLE_AT_CLOSE | _FI.REQUIRED),
102-
("Volume", _FI.AVAILABLE_AT_CLOSE),
96+
("High", ADFI_AVAILABLE_AT_CLOSE),
97+
("Low", ADFI_AVAILABLE_AT_CLOSE),
98+
("Open", ADFI_AVAILABLE_AT_CLOSE | ADFI_AVAILABLE_AT_OPEN),
99+
("Close", ADFI_AVAILABLE_AT_CLOSE | ADFI_REQUIRED),
100+
("Volume", ADFI_AVAILABLE_AT_CLOSE),
103101
]
104102

105103
def intraday_traded_price(
@@ -119,7 +117,7 @@ def check_and_fix_data(self, data: pd.DataFrame) -> pd.DataFrame:
119117
# TODO: check volume >= 0
120118

121119
# check each asset has required fields
122-
required_fields = self._get_fields(_FI.REQUIRED)
120+
required_fields = self._get_fields(ADFI_REQUIRED)
123121
missing_req_fields = set(required_fields) - set(data.columns)
124122
if len(missing_req_fields):
125123
raise ValueError(
@@ -128,6 +126,6 @@ def check_and_fix_data(self, data: pd.DataFrame) -> pd.DataFrame:
128126
)
129127

130128
# reindex columns with expected fields + additional fields
131-
expected_fields = self._get_fields(_FI.AVAILABLE_AT_CLOSE)
129+
expected_fields = self._get_fields(ADFI_AVAILABLE_AT_CLOSE)
132130
other_fields = list(set(data.columns) - set(expected_fields))
133131
return data.reindex(expected_fields + other_fields, axis=1)

yabte/backtest/book.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ def test_trades(self, trades: Sequence[Trade]) -> bool:
8787
return True
8888

8989
def add_transactions(self, transactions: Sequence[Transaction]):
90-
"""Records the `transactions` and adjusts internal dictionary of
91-
positions and value of cash accordingly."""
90+
"""Records the `transactions` and adjusts internal dictionary of positions and
91+
value of cash accordingly."""
9292
for tran in transactions:
9393
if isinstance(tran, Trade):
9494
self.positions[tran.asset_name] += tran.quantity

yabte/backtest/order.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ def post_complete(self, trades: List[Trade]):
101101
def apply(
102102
self, ts: pd.Timestamp, day_data: pd.DataFrame, asset_map: Dict[str, Asset]
103103
):
104-
"""Applies order to `self.book` for time `ts` using provided `day_data`
105-
and dictionary of asset information `asset_map`."""
104+
"""Applies order to `self.book` for time `ts` using provided `day_data` and
105+
dictionary of asset information `asset_map`."""
106106
raise NotImplementedError("The apply methods needs to be implemented.")
107107

108108

@@ -192,8 +192,8 @@ class PositionalOrderCheckType(Enum):
192192
@mypyc_attr(allow_interpreted_subclasses=True)
193193
@dataclass(kw_only=True)
194194
class PositionalOrder(Order):
195-
"""Ensures current position is `size` and will close out existing positions
196-
to achieve this."""
195+
"""Ensures current position is `size` and will close out existing positions to
196+
achieve this."""
197197

198198
check_type: PositionalOrderCheckType = PositionalOrderCheckType.POS_TQ_DIFFER
199199
"""Condition type to determine if a trade is required."""
@@ -338,8 +338,8 @@ def apply(
338338
@mypyc_attr(allow_interpreted_subclasses=True)
339339
@dataclass(kw_only=True)
340340
class PositionalBasketOrder(BasketOrder):
341-
"""Similar to a :py:class:`BasketOrder` but will close out existing
342-
positions if they do not match requested weights."""
341+
"""Similar to a :py:class:`BasketOrder` but will close out existing positions if
342+
they do not match requested weights."""
343343

344344
check_type: PositionalOrderCheckType = PositionalOrderCheckType.POS_TQ_DIFFER
345345

yabte/backtest/strategy.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# (https://github.com/mypyc/mypyc/issues/1000)
1313
from pandas import DataFrame, Series, Timestamp # type: ignore
1414

15-
from .asset import Asset, AssetDataFieldInfo, AssetName
15+
from .asset import ADFI_AVAILABLE_AT_OPEN, Asset, AssetName
1616
from .book import Book, BookMandate, BookName
1717
from .order import Order, OrderBase, OrderStatus
1818

@@ -111,7 +111,7 @@ def _get_col_indexer(self):
111111
*[
112112
product(
113113
[asset.data_label],
114-
asset._get_fields(AssetDataFieldInfo.AVAILABLE_AT_OPEN),
114+
asset._get_fields(ADFI_AVAILABLE_AT_OPEN),
115115
)
116116
for asset_name, asset in self.assets.items()
117117
]
@@ -122,9 +122,8 @@ def _get_col_indexer(self):
122122

123123
@property
124124
def data(self) -> pd.DataFrame:
125-
"""Provides window of data available up to current timestamp `self.ts`
126-
and masks out data not availble at open (like high, low, close,
127-
volume)."""
125+
"""Provides window of data available up to current timestamp `self.ts` and masks
126+
out data not availble at open (like high, low, close, volume)."""
128127
if not self.ts:
129128
return self._data
130129
else:

yabte/utilities/strategy_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33

44
def crossover(series1: pd.Series, series2: pd.Series) -> bool:
5-
"""Determine if two series cross over one another. Returns `True` if
6-
`series1` just crosses above `series2`.
5+
"""Determine if two series cross over one another. Returns `True` if `series1` just
6+
crosses above `series2`.
77
88
>>> crossover(self.data.Close, self.sma)
99
True

0 commit comments

Comments
 (0)