Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing pyproject.toml #30

Merged
merged 3 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CHANGELOG

## 1.3.1 (2024-09-27)

- discriminator="type" removed from strategy: list[StrategyLeg] = Field(..., min_length=1) in models.py, since
it was causing errors in new Pydantic versions.
- Changed StotckStrategy and OptionStrategy to Stock and Option in models.py, respectively.
- Changed BaseStrategy to BaseLeg in models.py.
- Changed Strategy to StrategyLeg in models.py.
- Removed premium field from Stock in models.py.
- Moved n field to BaseLeg in models.py.

## 1.3.0 (2024-09-13)

- Remove the deprecated `StrategyEngine` class (it remains commented in the code).
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The description of the input data follows:
- Maximum value of the stock in the stock price domain.

- `strategy` : list
- A list of `Strategy`.
- A list of strategy legs.

- `dividend_yield` : float, optional
- Annualized dividend yield. Default is 0.0.
Expand Down Expand Up @@ -115,10 +115,10 @@ The description of the input data follows:

---

The `strategy` attribute can be either of type `OptionStrategy`, `StockStrategy`, or
`ClosedPosition`.
The `strategy` attribute is a list of strategy legs, where each leg can be of type
`Option`, `Stock`, or `ClosedPosition`.

The `OptionStrategy` structure:
The `Option` structure:

---

Expand Down Expand Up @@ -149,7 +149,7 @@ The `OptionStrategy` structure:

---

`StockStrategy`:
`Stock`:

---

Expand Down
20 changes: 10 additions & 10 deletions optionlab/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typing


VERSION = "1.3.0"
VERSION = "1.3.1"


if typing.TYPE_CHECKING:
Expand All @@ -11,16 +11,16 @@
Inputs,
OptionType,
OptionInfo,
OptionStrategy,
Option,
Outputs,
ClosedPosition,
ProbabilityOfProfitArrayInputs,
ProbabilityOfProfitInputs,
BlackScholesInfo,
Distribution,
Strategy,
StrategyLeg,
StrategyType,
StockStrategy,
Stock,
Country,
Action,
)
Expand Down Expand Up @@ -53,16 +53,16 @@
"Inputs",
"OptionType",
"OptionInfo",
"OptionStrategy",
"Option",
"Outputs",
"ClosedPosition",
"ProbabilityOfProfitArrayInputs",
"ProbabilityOfProfitInputs",
"BlackScholesInfo",
"Distribution",
"Strategy",
"StrategyLeg",
"StrategyType",
"StockStrategy",
"Stock",
"Country",
"Action",
# engine
Expand Down Expand Up @@ -96,15 +96,15 @@
"Outputs": (__package__, ".models"),
"OptionType": (__package__, ".models"),
"OptionInfo": (__package__, ".models"),
"OptionStrategy": (__package__, ".models"),
"Option": (__package__, ".models"),
"ClosedPosition": (__package__, ".models"),
"ProbabilityOfProfitArrayInputs": (__package__, ".models"),
"ProbabilityOfProfitInputs": (__package__, ".models"),
"BlackScholesInfo": (__package__, ".models"),
"Distribution": (__package__, ".models"),
"Strategy": (__package__, ".models"),
"StrategyLeg": (__package__, ".models"),
"StrategyType": (__package__, ".models"),
"StockStrategy": (__package__, ".models"),
"Stock": (__package__, ".models"),
"Country": (__package__, ".models"),
"Action": (__package__, ".models"),
# engine
Expand Down
8 changes: 4 additions & 4 deletions optionlab/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from optionlab.models import (
Inputs,
Action,
OptionStrategy,
StockStrategy,
Option,
Stock,
ClosedPosition,
Outputs,
ProbabilityOfProfitInputs,
Expand Down Expand Up @@ -75,7 +75,7 @@ def _init_inputs(inputs: Inputs) -> EngineData:
for i, strategy in enumerate(inputs.strategy):
data.type.append(strategy.type)

if isinstance(strategy, OptionStrategy):
if isinstance(strategy, Option):
data.strike.append(strategy.strike)
data.premium.append(strategy.premium)
data.n.append(strategy.n)
Expand Down Expand Up @@ -110,7 +110,7 @@ def _init_inputs(inputs: Inputs) -> EngineData:
else:
raise ValueError("Expiration must be a date, an int or None.")

elif isinstance(strategy, StockStrategy):
elif isinstance(strategy, Stock):
data.n.append(strategy.n)
data.action.append(strategy.action)
data._previous_position.append(strategy.prev_pos or 0.0)
Expand Down
20 changes: 8 additions & 12 deletions optionlab/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@
]


class BaseStrategy(BaseModel):
class BaseLeg(BaseModel):
n: int = Field(gt=0)
action: Action
prev_pos: float | None = None


class StockStrategy(BaseStrategy):
class Stock(BaseLeg):
"""
"type" : string
It must be 'stock'. It is mandatory.
Expand All @@ -48,15 +49,12 @@ class StockStrategy(BaseStrategy):
negative, it means that the position is closed and the
difference between this price and the current price is
considered in the payoff calculation.

"""

type: Literal["stock"] = "stock"
n: int = Field(gt=0)
premium: float | None = None


class OptionStrategy(BaseStrategy):
class Option(BaseLeg):
"""
"type" : string
Either 'call' or 'put'. It is mandatory.
Expand All @@ -83,7 +81,6 @@ class OptionStrategy(BaseStrategy):
type: OptionType
strike: float = Field(gt=0)
premium: float = Field(gt=0)
n: int = Field(gt=0)
expiration: dt.date | int | None = None

@field_validator("expiration")
Expand All @@ -107,7 +104,7 @@ class ClosedPosition(BaseModel):
prev_pos: float


Strategy = StockStrategy | OptionStrategy | ClosedPosition
StrategyLeg = Stock | Option | ClosedPosition


class ProbabilityOfProfitInputs(BaseModel):
Expand Down Expand Up @@ -203,7 +200,7 @@ class Inputs(BaseModel):
interest_rate: float = Field(gt=0, le=0.2)
min_stock: float
max_stock: float
strategy: list[Strategy] = Field(..., min_length=1, discriminator="type")
strategy: list[StrategyLeg] = Field(..., min_length=1)
dividend_yield: float = 0.0
profit_target: float | None = None
loss_limit: float | None = None
Expand All @@ -221,7 +218,7 @@ class Inputs(BaseModel):

@field_validator("strategy")
@classmethod
def validate_strategy(cls, v: list[Strategy]) -> list[Strategy]:
def validate_strategy(cls, v: list[StrategyLeg]) -> list[StrategyLeg]:
types = [strategy.type for strategy in v]
if types.count("closed") > 1:
raise ValueError("Only one position of type 'closed' is allowed!")
Expand All @@ -232,8 +229,7 @@ def validate_dates(self) -> "Inputs":
expiration_dates = [
strategy.expiration
for strategy in self.strategy
if isinstance(strategy, OptionStrategy)
and isinstance(strategy.expiration, dt.date)
if isinstance(strategy, Option) and isinstance(strategy.expiration, dt.date)
]
if self.start_date and self.target_date:
if any(
Expand Down
Loading
Loading