From 6baff2361f1fc438d76240dfd1bd0ce381a87dd3 Mon Sep 17 00:00:00 2001 From: mdeboute Date: Wed, 29 Jan 2025 11:09:47 +0100 Subject: [PATCH] refactor: apply uv run ruff check pystock/ --fix --- pystock/asset.py | 13 +++++++++++++ pystock/portfolio.py | 6 ++++++ pystock/quantitative.py | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/pystock/asset.py b/pystock/asset.py index 74485bf..4bcf866 100644 --- a/pystock/asset.py +++ b/pystock/asset.py @@ -14,6 +14,7 @@ def __init__(self, symbol: str, listed: bool = True) -> None: Args: symbol (str): Bloomberg ticker of the asset. listed (bool, optional): If the asset is listed on Yahoo Finance or not. Default to True. + """ self.symbol = symbol if listed: @@ -35,6 +36,7 @@ def name(self) -> str: Returns: str: The name of the asset. + """ return self.ticker.info[cst.SHORT_NAME] if self.listed else self.symbol # type: ignore @@ -54,6 +56,7 @@ def fetch_historical_data( Returns: pd.DataFrame | None: The historical data of the asset. + """ if not self.listed: print(f"{self.name} is not listed! You should provide the data.") @@ -75,6 +78,7 @@ def historical_data(self) -> pd.DataFrame | None: Returns: pd.DataFrame | None: The historical data of the asset. + """ return self.fetch_historical_data() @@ -84,6 +88,7 @@ def closes(self) -> pd.Series | None: Returns: pd.Series | None: The closing prices of the asset. + """ if self._closes is None: self._closes = self.historical_data[cst.CLOSE] # type: ignore @@ -95,6 +100,7 @@ def daily_returns(self) -> np.ndarray | None: Returns: np.ndarray | None: The daily returns of the asset. + """ if self._daily_returns is None: closes = self.historical_data[cst.CLOSE] # type: ignore @@ -108,6 +114,7 @@ def daily_returns(self, data: list[float]) -> None: Args: data (list[float]): The daily returns of the asset. + """ self._daily_returns = data @@ -117,6 +124,7 @@ def daily_log_returns(self) -> pd.Series | None: Returns: pd.Series | None: The daily log returns of the asset. + """ if self._daily_log_returns is None: closes = self.historical_data[cst.CLOSE] # type: ignore @@ -130,6 +138,7 @@ def daily_log_returns(self, data: list[float]) -> None: Args: data (list[float]): The daily log returns of the asset. + """ self._daily_log_returns = data @@ -139,6 +148,7 @@ def expected_log_return(self) -> float | None: Returns: float | None: The expected log return of the asset. + """ if self._expected_log_return is None: if self._expected_return is not None: @@ -155,6 +165,7 @@ def expected_log_return(self, value: float) -> None: Args: value (float): The expected log return of the asset. + """ self._expected_log_return = value @@ -164,6 +175,7 @@ def expected_return(self) -> float | None: Returns: float | None: The expected return of the asset. + """ if self._expected_return is None: self._expected_return = np.exp(self.expected_log_return) - 1 # type: ignore @@ -175,6 +187,7 @@ def expected_return(self, value: float) -> None: Args: value (float): The expected return of the asset. + """ self._expected_return = value diff --git a/pystock/portfolio.py b/pystock/portfolio.py index 527fa14..ce098ea 100644 --- a/pystock/portfolio.py +++ b/pystock/portfolio.py @@ -35,6 +35,7 @@ def from_xlsx_file(cls, file_path: str) -> "Portfolio": Raises: ValueError: If the columns `SYMBOL_COL` and `WEIGHT_COL` are not present in the file. + """ df = pd.read_excel(file_path) if cst.SYMBOL_COL not in df.columns or cst.WEIGHT_COL not in df.columns: @@ -52,6 +53,7 @@ def to_xlsx_file(self, file_path: str) -> None: Args: file_path (str): Path to the XLSX file. + """ data = { cst.SYMBOL_COL: [asset.symbol for asset in self.assets], @@ -76,6 +78,7 @@ def cov_matrix(self) -> np.ndarray: Returns: np.ndarray: The covariance matrix. + """ if self._cov_matrix is None: daily_returns = [ @@ -113,6 +116,7 @@ def variance(self) -> float: Returns: float: The variance of the portfolio. + """ return np.dot(self.weights, np.dot(self.cov_matrix, self.weights)) @@ -152,6 +156,7 @@ def add_asset(self, asset: Asset, weight: float) -> None: Args: asset (Asset): The asset to add. weight (float): The weight of the asset in the portfolio. + """ self.assets.append(asset) self.weights = np.append(self.weights, weight) @@ -167,6 +172,7 @@ def remove_asset(self, asset: Asset) -> None: Raises: ValueError: If the asset is not in the portfolio. + """ if asset not in self.assets: raise ValueError("The asset is not in the portfolio.") diff --git a/pystock/quantitative.py b/pystock/quantitative.py index 66e649f..c3b5021 100644 --- a/pystock/quantitative.py +++ b/pystock/quantitative.py @@ -43,6 +43,7 @@ def minimize_variance_with_return(self, desired_return: float) -> np.ndarray: Returns: np.ndarray: Optimal portfolio weights. + """ self.model.objective = pyo.Objective( expr=pyo.quicksum( @@ -100,6 +101,7 @@ def simulation( Returns: pd.DataFrame: Results of the simulation (returns, risk, Sharpe ratio, weights). + """ if num_simulations <= 0: raise ValueError("Number of simulations must be a positive integer.") @@ -125,6 +127,7 @@ def get_gareto_front(df: pd.DataFrame) -> pd.DataFrame: Returns: pd.DataFrame: DataFrame containing Pareto-optimal portfolios. + """ return df.sort_values("Risk").drop_duplicates("Returns", keep="first") @@ -137,6 +140,7 @@ def create_efficient_frontier(df: pd.DataFrame) -> go.Figure: Returns: px.scatter: Plotly scatter plot. + """ df["Weights"] = df["Weights"].apply(lambda x: str(x)) fig = px.scatter(