### Setup Environment Source: https://github.com/furechan/mintalib/blob/main/WORKFLOW.md Initializes the project environment using uv. ```bash uv sync ``` -------------------------------- ### Importing Mintalib Components Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Initial setup for using Mintalib indicators and sample data. ```python import pandas as pd import polars as pl from mintalib.samples import sample_prices from mintalib.indicators import SMA, EMA, MACD, RSI ``` -------------------------------- ### Setup Package Directories Source: https://github.com/furechan/mintalib/blob/main/scripts/make-indicators.ipynb Configures package and root directories for mintalib. Ensures the package directory exists. ```python from pathlib import Path PACKAGE = "mintalib" ROOTDIR = Path.cwd().parent PKGDIR = ROOTDIR.joinpath(f"src/{PACKAGE}").resolve(strict=True) if '__file__' in globals(): print(f"Running {__file__} ...") ``` -------------------------------- ### Install Mintalib Source: https://github.com/furechan/mintalib/blob/main/output/pypi-readme.md Install the mintalib package using pip. Ensure Python version is 3.10 or higher. ```console pip install mintalib ``` -------------------------------- ### Load Sample Prices with Mintalib Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb Imports the sample_prices function from mintalib and loads sample price data. Requires mintalib to be installed. ```python from mintalib.samples import sample_prices ``` ```python prices = sample_prices() ``` -------------------------------- ### Load and Display Sample Prices with Polars Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Loads sample price data using mintalib and converts it into a Polars DataFrame. Ensure Polars and mintalib are installed. ```python import polars as pl from mintalib.samples import sample_prices prices = sample_prices() prices = pl.from_pandas(prices, include_index=True, nan_to_null=True) prices ``` -------------------------------- ### Cython Imports and Setup Source: https://github.com/furechan/mintalib/blob/main/prototypes/cython-proto.ipynb Initializes Cython with specific language level and binding settings, and imports necessary libraries like sys, numpy, and functions for NaN checking. ```cython %%cython -c=-Wno-unreachable-code # cython: language_level=3, binding=True import sys import numpy as np from functools import wraps from libc.math cimport isnan ``` -------------------------------- ### Import yfinance Library Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Imports the necessary yfinance library for fetching financial data. Ensure yfinance is installed. ```python from pathlib import Path import yfinance as yf # type: ignore ``` -------------------------------- ### Fetch and Display Sample Prices Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Fetches daily prices for AAPL and displays the index. This is a basic usage example of the get_prices function. ```python SYMBOL = 'AAPL' prices = get_prices(SYMBOL, freq="daily") prices.index ``` -------------------------------- ### SMA Usage Examples Source: https://github.com/furechan/mintalib/blob/main/prototypes/cython-proto.ipynb Various ways to invoke SMA calculations and inspect results. ```python res = np_sma(prices.close.values, 5) print(type(res)) res ``` ```python res = calc_sma(prices.close, 3) print(type(res)) res ``` ```python res = calc_sma(prices.close, 3) print(type(res)) res ``` ```python help(calc_sma) ``` ```python SMA ``` ```python SMA(prices, 20) ``` -------------------------------- ### Example Output of calc_curve Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb Displays the resulting array from a `calc_curve` operation, showing calculated values and NaNs for initial periods. ```text Output: 526 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each) Result: array([ nan, nan, nan, ..., 0.04465194, 0.0498251 , 0.06051601]) ``` -------------------------------- ### Load and Display Sample Prices with Pandas Source: https://github.com/furechan/mintalib/blob/main/prototypes/pipe-operator.ipynb Loads sample price data into a Pandas DataFrame and displays it. This is a common starting point for time-series analysis. ```python prices = sample_prices() prices ``` -------------------------------- ### Load Sample Polars Prices Data Source: https://github.com/furechan/mintalib/blob/main/examples/experimental/polars-accessor.ipynb Loads sample price data into a Polars DataFrame using mintalib.samples. This DataFrame is used for subsequent examples. ```python from mintalib.samples import sample_prices prices = sample_prices(backend="polars") prices ``` -------------------------------- ### Cython Quadratic Regression (Simplified) Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb A simplified Cython implementation of quadratic regression, focusing on basic setup and constants. It includes definitions for curve and forecast options. ```cython %%cython -c=-Wno-unreachable-code import sys import numpy as np from libc.math cimport isnan from libc cimport math cdef double NAN = float('nan') from mintalib.core import wrap_result cdef enum: QUADREG_CURVE = 0 QUADREG_FORECAST = 1 QUADREG_BADOPTION = 2 def quadratic_regression(series, long period=20, *, int option=0, int offset=0, bint wrap=False): """ Quadratic Regression Args: period (int) : time period, default 20 """ if period < 2: raise ValueError(f"Invalid period {period}, should be greater than 2") if option < 0 or option > QUADREG_BADOPTION: raise ValueError(f"Invalid option {option}") cdef const double[:] ys = np.asarray(series, float) cdef long size = ys.size cdef object result = np.full(size, np.nan) cdef double[:] output = result if period >= size: return result cdef double x, y ``` -------------------------------- ### Update Sample Price CSV Files Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Downloads prices for AAPL across different frequencies and saves them as CSV files in the 'samples' directory. This ensures consistent data for examples. ```python SAMPLES = PKGDIR.joinpath("samples") for freq in INTERVAL.keys(): fname = f"{freq}-prices.csv" prices = get_prices(SYMBOL, freq=freq) data = prices.to_csv(lineterminator="\n") outfile = SAMPLES.joinpath(fname) print(f"Updating {outfile.name} ...") outfile.write_text(data) ``` -------------------------------- ### Generate Random Walk Prices Source: https://github.com/furechan/mintalib/blob/main/prototypes/random-prices.ipynb Simulates a single series of random walk prices. Allows customization of count, frequency, volatility, forward rate, and starting value. ```python def random_walk( count: int = 260, freq: str = "B", start_value: float = 100.0, volatility: float = 0.20, fwd_rate: float = 0.10, skip: int = 0, start_date=None, end_date=None, name=None, seed=None, ): """generates a single series of random walk prices""" generator = np.random.default_rng(seed) dates = date_range(count, freq=freq, start_date=start_date, end_date=end_date) days = (dates.max() - dates.min()).days sampling = 365.0 * count / days fwd = np.log(1 + fwd_rate) / sampling std = volatility / np.sqrt(sampling) change = generator.standard_normal(count - 1) * std + np.log(1 + fwd) prices = start_value * np.exp(np.r_[0.0, change.cumsum(0)]) if skip: prices[:skip] = np.nan result = pd.Series(prices, index=dates.values, name=name).rename_axis(index="date") return result ``` -------------------------------- ### Get Help for SMA Indicator Source: https://github.com/furechan/mintalib/blob/main/prototypes/indicator-repr.ipynb Display the help documentation for the SMA function, showing its parameters and their types. This is useful for understanding how to correctly use the function. ```python help(SMA) ``` -------------------------------- ### List Core Calculation Functions Source: https://github.com/furechan/mintalib/blob/main/scripts/make-functions.ipynb Retrieves a sorted list of all callable functions within the `mintalib.core` module that start with 'calc_'. This helps in identifying available calculation functions. ```python def core_functions(): return sorted(k for k, v in vars(core).items() if k.startswith("calc_") and callable(v)) core_functions() ``` -------------------------------- ### Initialize QuickStudy Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Create a QuickStudy instance with specified technical indicators. ```python study = QuickStudy(MACD(), sma20 = SMA(20), sma50 = SMA(50) ) study ``` -------------------------------- ### Get Tuple Type Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Returns the type object for 'tuple'. ```python tuple ``` -------------------------------- ### Define Project Directories Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Sets up the root and package directories for the project. The package directory is resolved strictly. ```python ROOTDIR = Path.cwd().parent PKGDIR = ROOTDIR.joinpath("src/mintalib").resolve(strict=True) ``` -------------------------------- ### Get information about a function Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Extracts the name and the first line of the docstring (description) from a given function. ```python def get_info(func): """information about function""" info = dict(Name=func.__name__) doc = func.__doc__ or "" description = doc.strip().partition("\n")[0] if description is not None: info.update(Description=description) return info ``` -------------------------------- ### Import mintalib functions Source: https://github.com/furechan/mintalib/blob/main/examples/functions.ipynb Initialize the module to access calculation functions. ```python import mintalib.functions as ta ``` -------------------------------- ### Backup README File Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Create a backup copy of the project's README.md file. ```python def backup_readme(verbose=True): readme = ROOTDIR.joinpath("README.md") if ROOTDIR.joinpath("archive").exists(): backup = ROOTDIR.joinpath("archive/README.bak") else: backup = ROOTDIR.joinpath("README.bak") if verbose: print(f"Backing up {readme.name} ...") shutil.copy(readme, backup) backup_readme() ``` -------------------------------- ### Build a Complete Trading Strategy Source: https://context7.com/furechan/mintalib/llms.txt Demonstrates creating a multi-indicator analysis system including MACD, Bollinger Bands, and Stochastic oscillators. ```python from mintalib.indicators import SMA, EMA, RSI, MACD, ATR, BBANDS, STOCH import pandas as pd # Sample price data (would typically load from data source) prices = pd.DataFrame({ 'open': [100 + i * 0.3 + (i % 5) * 0.2 for i in range(50)], 'high': [101 + i * 0.3 + (i % 5) * 0.3 for i in range(50)], 'low': [99 + i * 0.3 + (i % 5) * 0.1 for i in range(50)], 'close': [100.5 + i * 0.3 + (i % 5) * 0.25 for i in range(50)], 'volume': [1000 + (i % 10) * 100 for i in range(50)] }) # Build comprehensive analysis analysis = prices.assign( # Trend indicators sma_20=SMA(20), sma_50=SMA(50), ema_12=EMA(12), # Momentum indicators rsi=RSI(14), # Volatility atr=ATR(14) ) # Add MACD (multi-output) macd = MACD(12, 26, 9) @ prices analysis['macd'] = macd.macd analysis['macd_signal'] = macd.macdsignal analysis['macd_hist'] = macd.macdhist # Add Bollinger Bands bbands = BBANDS(20, 2.0) @ prices analysis['bb_upper'] = bbands.upperband analysis['bb_middle'] = bbands.middleband analysis['bb_lower'] = bbands.bb_lower # Add Stochastic stoch = STOCH(14, 3, 3) @ prices analysis['stoch_k'] = stoch.slowk analysis['stoch_d'] = stoch.slowd # Generate signals analysis['trend_bullish'] = analysis['sma_20'] > analysis['sma_50'] analysis['rsi_oversold'] = analysis['rsi'] < 30 analysis['rsi_overbought'] = analysis['rsi'] > 70 analysis['macd_bullish'] = analysis['macd'] > analysis['macd_signal'] ``` -------------------------------- ### Load Sample Prices Source: https://github.com/furechan/mintalib/blob/main/examples/experimental/pandas-accessor.ipynb Retrieve sample price data for testing indicators. ```python from mintalib.samples import sample_prices prices = sample_prices() prices ``` -------------------------------- ### Load and Verify Sample Prices Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Loads sample prices using the `sample_prices` utility function from mintalib and prints their length for different frequencies. This verifies the saved CSV data. ```python from mintalib.samples import sample_prices for freq in INTERVAL.keys(): prices = sample_prices(freq=freq, max_bars=5000) print(freq, len(prices)) ``` -------------------------------- ### Define root directory and pyproject.toml path Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Sets up the project's root directory and resolves the absolute path to the pyproject.toml file, ensuring it exists. ```python ROOTDIR = Path.cwd().parent PYPROJECT = ROOTDIR.joinpath("pyproject.toml").resolve(strict=True) ``` -------------------------------- ### Development Commands Source: https://github.com/furechan/mintalib/blob/main/WORKFLOW.md Standard commands for testing, linting, and type checking. ```bash uv run pytest # run tests uv run ruff check # lint uv run ty check # type check ``` -------------------------------- ### Load Sample Prices with Mintalib Source: https://github.com/furechan/mintalib/blob/main/prototypes/cython-proto.ipynb Loads sample price data using the `sample_prices` function from mintalib. This data is typically a pandas DataFrame. ```python from mintalib.samples import sample_prices %load_ext cython ``` ```python prices = sample_prices() prices.info() ``` -------------------------------- ### Define Price Fetching Function Source: https://github.com/furechan/mintalib/blob/main/scripts/update-samples.ipynb Defines a function to get historical stock prices with caching. It handles different frequencies and bar limits. Requires yfinance. ```python from functools import lru_cache INTERVAL = dict(daily="1d", hourly="1h", minute="1m") MAXPERIOD = dict(daily="max", hourly="2Y", minute="5d") @lru_cache def get_prices(symbol: str, *, freq="daily", max_bars=0): interval = INTERVAL[freq] period = MAXPERIOD[freq] prices = yf.Ticker(symbol).history(interval=interval, period=period, auto_adjust=True) prices = prices.filter(["Open", "High", "Low", "Close", "Volume"]) prices = prices.rename(columns=str.lower).rename_axis(index=str.lower) if freq == "daily": prices.index = prices.index.tz_localize(None) if max_bars > 0: prices = prices.tail(max_bars) return prices ``` -------------------------------- ### Get parameters from function signature Source: https://github.com/furechan/mintalib/blob/main/prototypes/inspect-signature.ipynb Extracts and displays the parameters of the calc_sma function from its signature object. This provides a detailed view of each parameter, including default values. ```python parameters = signature.parameters parameters ``` -------------------------------- ### Load Sample Prices with Pandas Source: https://github.com/furechan/mintalib/blob/main/examples/sample-prices.ipynb Retrieves hourly sample price data as a pandas DataFrame. ```python from mintalib.samples import sample_prices FREQ = "hourly" prices = sample_prices(FREQ) print(prices.index.dtype) prices ``` -------------------------------- ### Load sample price data Source: https://github.com/furechan/mintalib/blob/main/examples/functions.ipynb Retrieve sample price data for testing indicators. ```python from mintalib.samples import sample_prices prices = sample_prices() prices ``` -------------------------------- ### Configure Paths for Mintalib Generation Source: https://github.com/furechan/mintalib/blob/main/scripts/make-functions.ipynb Sets up the package directory path relative to the current working directory for script execution. ```python from pathlib import Path PACKAGE = "mintalib" ROOTDIR = Path.cwd().parent PKGDIR = ROOTDIR.joinpath(f"src/{PACKAGE}").resolve(strict=True) if '__file__' in globals(): print(f"Running {__file__} ...") ``` -------------------------------- ### Publishing Workflow Source: https://github.com/furechan/mintalib/blob/main/WORKFLOW.md Sequence of commands required to build, test, and publish a new version. ```bash inv make inv build inv dump tox inv publish inv bump git add pyproject.toml && git commit -m "Bump version" ``` -------------------------------- ### Implementing QuickStudy for Multi-Backend Support Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Provides a base class for studies that automatically dispatch to Pandas or Polars backends. ```python class QuickStudy(Study): """Update Study""" args: tuple = () kwargs: dict = {} def items(self): for arg in self.args: yield None, arg for kv in self.kwargs.items(): yield kv def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs def __repr__(self): cname = self.__class__.__name__ params = ", ".join(f"{k}={v!r}" if k else repr(v) for k, v in self.items()) return f"{cname}({params})" def __call__(self, prices): if not hasattr(prices, 'columns'): raise ValueError("DataFrame expected!") backend = getattr(prices, '__module__', None).partition('.')[0] if backend == "pandas": return self.apply_pandas(prices) if backend == "polars": return self.apply_polars(prices) raise ValueError(f"Unsupported DataFrame type: {backend}") def apply_pandas(self, prices): import pandas as pd columns = dict() for name, func in self.items(): result = func(prices) if hasattr(result, 'columns'): columns.update(result) elif name is not None: columns[name] = result elif hasattr(result, 'name'): columns[result.name] = result else: raise ValueError(f"Unexpected result type {type(result)!r} in positional args!") return pd.DataFrame(columns, index=prices.index) def apply_polars(self, prices): import polars as pl columns = dict() for name, func in self.items(): result = func(prices) ``` -------------------------------- ### Visualization of QSF Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb Plotting the close price and the calculated quadratic series forecast. ```python prices.tail(250).plot( y=["close", "qsf"], title="QSF", use_index=False, ); ``` -------------------------------- ### Import format_partial utility Source: https://github.com/furechan/mintalib/blob/main/prototypes/format-partial.ipynb Imports the format_partial function from the mintalib.utils module. This is a prerequisite for using the formatting utility. ```python from mintalib.utils import format_partial ``` -------------------------------- ### Import Mintalib Polars Accessor Source: https://github.com/furechan/mintalib/blob/main/examples/experimental/polars-accessor.ipynb Import mintalib.polars to activate the accessor. This also imports convenience expressions CLOSE and OHLC. ```python import polars as pl from mintalib.polars import CLOSE, OHLC # noqa ``` -------------------------------- ### Loading and Converting Sample Prices Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Retrieves sample price data and converts it into a Polars DataFrame. ```python prices = sample_prices() plprices = pl.from_dataframe(prices.reset_index()) plprices ``` -------------------------------- ### Define Module Prelude for Generated Functions Source: https://github.com/furechan/mintalib/blob/main/scripts/make-functions.ipynb Defines the documentation header and import recommendations for the generated functions module. ```python PRELUDE='''""" Calculation functions for technical analysis indicators. These functions are thin wrappers around core calculation routines that handle input and output type conversion. The function names are all lower case like `sma`, `ema`, etc. Some names like `abs`, `min`, `max`, `sum` shadow Python builtins. It is advised to import the module with a short alias rather than importing names directly: ```python import mintalib.functions as ta ``` """ ''' ``` -------------------------------- ### Apply QuickStudy to Pandas DataFrame Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Use the pipe method to apply the study to a pandas-based price object. ```python prices.pipe(study) ``` -------------------------------- ### Dynamically Create Function Module Source: https://github.com/furechan/mintalib/blob/main/scripts/make-functions.ipynb Builds a Python module string containing multiple function definitions from core calculation functions and then creates a module object from this code. This allows for dynamic loading of Mintalib functions. ```python from pprint import pformat import importlib.util def make_functions(cnames=None): if cnames is None: cnames = core_functions() output = PRELUDE + "\n\n" fnames = [] for cname in cnames: func = getattr(core, cname) name = cname.removeprefix("calc_").lower() code = make_function(func, name) fnames.append(name) output += code + "\n" return output output = make_functions() def new_module(name: str, code: str | None = None): spec = importlib.util.spec_from_loader(name, None) assert spec is not None module = importlib.util.module_from_spec(spec) if code: exec(code, module.__dict__) return module functions = new_module(f"{PACKAGE}.functions", output) ``` -------------------------------- ### Import Necessary Libraries Source: https://github.com/furechan/mintalib/blob/main/examples/indicators.ipynb Imports the required libraries and indicator classes from mintalib. ```python import numpy as np import pandas as pd from mintalib.samples import sample_prices from mintalib.indicators import EMA, SMA, ROC, RSI, EVAL, LOG ``` -------------------------------- ### Generate PyPI README Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Process the README and save the output to a specific directory for PyPI. ```python README = ROOTDIR.joinpath("README.md").resolve(strict=True) OUTDIR = ROOTDIR / "output" OUTDIR.mkdir(exist_ok=True) output = process_readme(README, verbose=True) outfile = OUTDIR.joinpath("pypi-readme.md").resolve() print(f"Updating {outfile.name} ...") outfile.write_text(output) ``` -------------------------------- ### Load Sample Prices with Polars Source: https://github.com/furechan/mintalib/blob/main/examples/sample-prices.ipynb Retrieves hourly sample price data as a polars DataFrame by specifying the backend. ```python plprices = sample_prices(FREQ, backend="polars") plprices ``` -------------------------------- ### Apply QuickStudy to Polars DataFrame Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Use the pipe method to apply the study to a Polars-based price object. ```python plprices.pipe(study) ``` -------------------------------- ### List core functions Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Retrieves a sorted list of available core calculation functions from the mintalib.core module. ```python def core_functions(exclude = ("calc_eval",)): names = sorted(k for k, v in vars(core).items() if k.startswith("calc_") and callable(v)) if exclude: names = [n for n in names if n not in exclude] return names core_functions() ``` -------------------------------- ### Import mintalib core functions Source: https://github.com/furechan/mintalib/blob/main/prototypes/inspect-signature.ipynb Imports the inspect module and the calc_sma function from mintalib.core. This is a prerequisite for using the library's core functionalities. ```python import inspect from mintalib.core import calc_sma ``` -------------------------------- ### List Core Functions in Mintalib Source: https://github.com/furechan/mintalib/blob/main/prototypes/pretty-print.ipynb Retrieves and prints a tuple of all uppercase, callable attributes from the mintalib.core module. This is useful for discovering available technical indicators and functions. ```python from mintalib import core from pprint import pprint, pformat from IPython.lib.pretty import pretty def core_functions(): """list of core functions""" return tuple(k for k, v in vars(core).items() if k.isupper() and callable(v)) print(core_functions()) ``` -------------------------------- ### Import SMA Indicator Source: https://github.com/furechan/mintalib/blob/main/prototypes/indicator-repr.ipynb Import the SMA indicator from the mintalib.indicators module. This is the first step before using the indicator. ```python from mintalib.indicators import SMA ``` -------------------------------- ### Import necessary libraries for mintalib Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Imports essential Python libraries for project management, configuration parsing, file operations, and data manipulation within the mintalib project. ```python import re import toml import shutil import posixpath from pathlib import Path import pandas as pd from mintalib import core ``` -------------------------------- ### Unpack Arguments with Splat Operator Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Demonstrates unpacking a tuple into a source string and a tuple of arguments using the splat operator. ```python args = "*", 10, 20 src, args = args[0], args[1:] src, args ``` -------------------------------- ### Use Mintalib Polars Expressions Source: https://context7.com/furechan/mintalib/llms.txt Utilize polars expression factories for native polars workflows. ```python import polars as pl from mintalib.expressions import SMA, EMA, ATR, RSI, ROC, MACD, BBANDS # Create sample polars DataFrame prices = pl.DataFrame({ 'open': [100.0, 101.5, 102.0, 101.0, 103.0, 104.5, 103.5, 105.0, 106.0, 105.5], 'high': [102.0, 103.0, 103.5, 102.5, 105.0, 106.0, 105.0, 107.0, 108.0, 107.0], 'low': [99.0, 100.5, 101.0, 100.0, 102.0, 103.5, 102.5, 104.0, 105.0, 104.5], 'close': [101.0, 102.5, 101.5, 102.0, 104.0, 104.0, 104.5, 106.0, 105.5, 106.5], 'volume': [1000, 1200, 800, 1500, 2000, 1800, 1100, 1600, 1400, 1300] }) ``` -------------------------------- ### Polars Expression Factory Prelude Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Defines the prelude for Polars expression factory methods in mintalib. This docstring explains the naming conventions, the optional 'src' parameter, and how multi-output indicators are handled. ```python PRELUDE='''""" Polars Expression Factory Methods Functions in this module are polars expression factories, typically named after the indicator in upper case as in `SMA`, `EMA`, `MACD`. The optional `src` keyword parameter allows overriding the default input column. For series-based indicators the default is `CLOSE` (i.e. `pl.col("close")`). For price-based indicators `src` is not applicable and should be left as `None`. Multi-output indicators like `MACD` and `BBANDS` return a polars struct expression that can be unpacked with `.unnest()`. """ ``` -------------------------------- ### Inspect the mintalib.indicators module Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Retrieves and displays all attributes of the mintalib.indicators module, providing insight into its structure and contents. ```python from mintalib import indicators vars(indicators) ``` -------------------------------- ### TYPPRICE Source: https://github.com/furechan/mintalib/blob/main/docs/mintalib.expressions.md Calculates the Typical Price. ```APIDOC ## TYPPRICE ### Description Calculates the Typical Price. Value of (high + low + close ) / 3. ### Method N/A (Function call within a library) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) - **polars.Expr**: The resulting Polars expression for Typical Price. #### Response Example N/A ### Args: - **src** (polars.Expr | str | None) : Source data expression or column name. Defaults to None. ``` -------------------------------- ### Use Mintalib Functions Interface Source: https://context7.com/furechan/mintalib/llms.txt Calculate indicators using plain functions that accept pandas series or dataframes. ```python import pandas as pd import numpy as np import mintalib.functions as ta # Create sample price data prices = pd.DataFrame({ 'open': [100.0, 101.5, 102.0, 101.0, 103.0, 104.5, 103.5, 105.0, 106.0, 105.5], 'high': [102.0, 103.0, 103.5, 102.5, 105.0, 106.0, 105.0, 107.0, 108.0, 107.0], 'low': [99.0, 100.5, 101.0, 100.0, 102.0, 103.5, 102.5, 104.0, 105.0, 104.5], 'close': [101.0, 102.5, 101.5, 102.0, 104.0, 104.0, 104.5, 106.0, 105.5, 106.5], 'volume': [1000, 1200, 800, 1500, 2000, 1800, 1100, 1600, 1400, 1300] }) # Calculate Simple Moving Average on close prices sma_5 = ta.sma(prices['close'], 5) # Output: [nan, nan, nan, nan, 102.2, 102.8, 103.2, 104.1, 104.8, 105.3] # Calculate Average True Range (volatility indicator) atr_5 = ta.atr(prices, 5) # Output: [nan, nan, nan, nan, 2.4, 2.32, 2.26, 2.41, 2.53, 2.22] # Calculate RSI (momentum oscillator) rsi_5 = ta.rsi(prices['close'], 5) # Output: momentum values between 0-100 ``` -------------------------------- ### Expected result of formatting Source: https://github.com/furechan/mintalib/blob/main/prototypes/format-partial.ipynb Shows the expected output string when format_partial is used with the XYZ function and the specified partial arguments. ```text Result: 'XYZ(10)' ``` -------------------------------- ### Indicator Prelude and Usage Source: https://github.com/furechan/mintalib/blob/main/scripts/make-indicators.ipynb Defines the prelude for indicator objects, explaining their composable interface and usage with pandas/numpy data. Supports direct application and the '@' operator for chaining. ```python PRELUDE='""" Indicators offer a composable interface where a calculation routine is bound with its parameters. An indicator instance is a callable and can be applied to prices or series data as if it were a function e.g. `SMA(50)(prices)`. Indicators also support the `@` operator to apply them to their input data e.g. `SMA(50) @ prices` or to chain them together e.g. `ROC(1) @ EMA(20)`. """ ``` -------------------------------- ### Generate Expressions from Core Functions Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Generates Python expressions from core functions in the mintalib library. Requires the 'core' module and a list of function names. ```python from pprint import pformat import importlib.util def make_expressions(cnames=None): if cnames is None: cnames = core_functions() output = PRELUDE fnames = [] for cname in cnames: func = getattr(core, cname) name = cname.removeprefix("calc_") code = make_expression(func) fnames.append(name) output += code + "\n" return output output = make_expressions() def new_module(name: str, code: str | None = None): spec = importlib.util.spec_from_loader(name, None) assert spec is not None module = importlib.util.module_from_spec(spec) if code: exec(code, module.__dict__) return module expressions = new_module(f"{PACKAGE}.expressions", output) ``` -------------------------------- ### Quadratic Regression Implementation Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb Core Cython implementation for calculating quadratic regression metrics including curve, slope, and intercept. ```cython cdef double s, sx, sx2, sx3, sx4, sy, sy2, sxy, sx2y cdef double vxy, vxx, vyy, vxx2, vx2y, vx2x2 cdef double denom, slope, curve, intercept, forecast cdef long i = 0, j = 0 s = sx = sx2 = sx3 = sx4 = sy = sy2 = sxy = sx2y = 0.0 for i in range(size): x, y = i, ys[i] if y != y: s = sx = sx2 = sx3 = sx4 = sy = sy2 = sxy = sx2y = 0.0 continue if s == 0: j = i s += 1 sx += x sx2 += x * x sx3 += x * x * x sx4 += x * x * x * x sy += y sy2 += y * y sxy += x * y sx2y += x * x * y if s < period: continue while s > period and j < size: x, y, j = j, ys[j], j+1 s -= 1 sx -= x sx2 -= x * x sx3 -= x * x * x sx4 -= x * x * x * x sy -= y sy2 -= y * y sxy -= x * y sx2y -= x * x * y vxy = (sxy / s - sx * sy / s / s) vxx = (sx2 / s - sx * sx / s / s) vyy = (sy2 / s - sy * sy / s / s) vxx2 = (sx3 / s - sx * sx2 / s / s) vx2y = (sx2y / s - sx2 * sy / s / s) vx2x2 = (sx4 / s - sx2 * sx2 / s / s) denom = vx2x2 * vxx - vxx2 * vxx2 curve = (vx2y * vxx - vxy * vxx2) / denom if denom > 0 else NAN slope = (vxy * vx2x2 - vxx2 * vx2y) / denom if denom > 0 else NAN intercept = (sy - slope * sx - curve * sx2) / s if s > 0 else NAN if option == QUADREG_CURVE: output[i] = curve continue if option == QUADREG_FORECAST: x = (i + offset) forecast = intercept + slope * x + curve * x * x output[i] = forecast continue if wrap: result = wrap_result(result, series) return result ``` -------------------------------- ### Security Update Workflow Source: https://github.com/furechan/mintalib/blob/main/WORKFLOW.md Process for addressing Dependabot security alerts and updating dependencies. ```bash inv depcheck git add uv.lock && git commit -m "Update dependencies to address security alerts" ``` -------------------------------- ### Extract project homepage URL from pyproject.toml Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Reads the pyproject.toml file to extract the project's homepage URL. Raises FileNotFoundError if pyproject.toml is not found. ```python def get_project_url(pyproject=PYPROJECT): """extract project url from project configuration""" if not pyproject.exists(): raise FileNotFoundError("pyproject.toml") config = toml.load(pyproject) return jquery(config, "project.urls.homepage") get_project_url() ``` -------------------------------- ### Format function call with partial arguments Source: https://github.com/furechan/mintalib/blob/main/prototypes/format-partial.ipynb Demonstrates how to use format_partial to create a string representation of a function call with specified partial arguments. The function XYZ is defined and then formatted with period=10 and flag=False. ```python def XYZ(prices, period: int = 20, *, flag: bool = False): pass format_partial(XYZ, dict(period=10, flag=False)) ``` -------------------------------- ### Load Cython Extension Source: https://github.com/furechan/mintalib/blob/main/prototypes/curve-proto.ipynb Loads the Cython extension for potential performance enhancements. This is a Jupyter Notebook/IPython magic command. ```python %load_ext cython ``` -------------------------------- ### Process README URLs Source: https://github.com/furechan/mintalib/blob/main/scripts/update-readme.ipynb Translate relative URLs in the README to absolute project URLs. ```python def process_readme(file, *, project_url=None, branch="main", verbose=True): """translate relative urls to full urls""" if project_url is None: project_url = get_project_url() def replace(m): exclam, alt, url = m.groups() ftype = "raw" if exclam else "blob" if url.startswith("/"): url = url.removeprefix("/") url = posixpath.join(project_url, ftype, branch, url) text = f"{exclam}[{alt}]({url})" if verbose: print("mapping", m.group(0), "->", text) else: text = m.group(0) return text source = file.read_text() result = re.sub( r"(\!?) \[ ([^]]*) \] \( ([^)]+) \)", replace, source, flags = re.VERBOSE ) return result ``` -------------------------------- ### Generate expression wrappers Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Utility to generate the source code for expression wrappers based on core calculation functions. ```python def make_expression(calc_func): cname = f"core.{calc_func.__name__}" fname = calc_func.__name__.removeprefix("calc_").upper() signature = make_signature(calc_func) buffer = f"@wrap_expression({cname})\n" buffer += f"def {fname}{signature}: ...\n" return buffer for cf in core.calc_sma, core.calc_macd, core.calc_atr: code = make_expression(cf) print(code) ``` -------------------------------- ### Indicator Usage Source: https://github.com/furechan/mintalib/blob/main/docs/mintalib.indicators.md How to apply indicators to price data using function calls or the @ operator. ```APIDOC ## Indicator Application ### Description Indicators are callable objects. They can be applied to price data using standard function syntax or the @ operator for chaining. ### Usage Examples - `SMA(50)(prices)` - `SMA(50) @ prices` - `ROC(1) @ EMA(20)` ``` -------------------------------- ### Use Mintalib Indicators Interface Source: https://context7.com/furechan/mintalib/llms.txt Apply composable indicator objects using the @ operator or standard function calls. ```python from mintalib.indicators import SMA, EMA, RSI, MACD, ATR, ROC, BBANDS import pandas as pd # Create sample OHLCV data prices = pd.DataFrame({ 'open': [100.0, 101.5, 102.0, 101.0, 103.0, 104.5, 103.5, 105.0, 106.0, 105.5], 'high': [102.0, 103.0, 103.5, 102.5, 105.0, 106.0, 105.0, 107.0, 108.0, 107.0], 'low': [99.0, 100.5, 101.0, 100.0, 102.0, 103.5, 102.5, 104.0, 105.0, 104.5], 'close': [101.0, 102.5, 101.5, 102.0, 104.0, 104.0, 104.5, 106.0, 105.5, 106.5], 'volume': [1000, 1200, 800, 1500, 2000, 1800, 1100, 1600, 1400, 1300] }) # Apply indicators using @ operator result = prices.assign( sma_5=SMA(5), # 5-period simple moving average ema_5=EMA(5), # 5-period exponential moving average rsi=RSI(14), # 14-period RSI atr=ATR(14), # 14-period Average True Range trend=ROC(1) @ EMA(5) # Rate of change applied to EMA (chained) ) # Multi-output indicator (returns named tuple) macd_result = MACD(12, 26, 9) @ prices # Access: macd_result.macd, macd_result.macdsignal, macd_result.macdhist # Bollinger Bands (multi-output) bbands_result = BBANDS(20, 2.0) @ prices # Access: bbands_result.upperband, bbands_result.middleband, bbands_result.lowerband # Alternative function-call syntax sma_values = SMA(5)(prices) # Equivalent to SMA(5) @ prices ``` -------------------------------- ### Generate and write module file in Python Source: https://github.com/furechan/mintalib/blob/main/scripts/make-functions.ipynb Updates a Python module file by writing generated content to the specified path. ```python functions = new_module(f"{PACKAGE}.functions", output) outfile = PKGDIR / "functions.py" print(f"Updating {outfile.name} ...") outfile.write_text(output) ``` -------------------------------- ### Recompile Cython Files Source: https://github.com/furechan/mintalib/blob/main/WORKFLOW.md Regenerates derived files after modifying .pxi source files. ```bash inv make ``` -------------------------------- ### Core Calculation Functions Source: https://github.com/furechan/mintalib/blob/main/scripts/make-expressions.ipynb Lists the available core calculation functions within the mintalib library, excluding specific internal functions. ```APIDOC ## Core Calculation Functions ### Description Provides a list of core calculation functions available in the mintalib library, used for generating technical indicators. ### Method N/A (Utility Function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```python core_functions() ``` ### Response #### Success Response (200) - **List of Strings** - Each string is the name of a core calculation function (e.g., 'calc_sma', 'calc_macd'). #### Response Example ```json [ "calc_abs", "calc_adx", "calc_alma", "calc_atr", "calc_avgprice", "calc_bbands", "calc_bbp", "calc_bbw", "calc_bop", "calc_cci", "calc_clag", "calc_cmf", "calc_crossover", "calc_crossunder", "calc_curve", "calc_dema", "calc_diff", "calc_dmi", "calc_ema", "calc_exp", "calc_flag", "calc_hma", "calc_kama", "calc_keltner", "calc_ker", "calc_lag", "calc_log", "calc_lroc", "calc_macd", "calc_macdv", "calc_mad", "calc_mav", "calc_max", "calc_mdi", "calc_mfi", "calc_midprice", "calc_min", "calc_natr", "calc_pdi", "calc_ppo", "calc_price", "calc_qsf", "calc_rma", "calc_roc", "calc_rsi", "calc_rvalue", "calc_sar", "calc_shift", "calc_sign", "calc_slope", "calc_sma" ] ``` ``` -------------------------------- ### Implementing Study and ChainedStudy Classes Source: https://github.com/furechan/mintalib/blob/main/prototypes/study-prototype.ipynb Defines the base Study interface and the ChainedStudy class for piping operations. ```python import functools from abc import ABCMeta, abstractmethod class Study(metaclass=ABCMeta): """callable/chainable with process method and composition""" __pandas_priority__ = 5000 @abstractmethod def __call__(self, prices): ... def __or__(self, other): """pipe into callable""" if not callable(other): return NotImplemented return self.pipe(other) def pipe(self, func, **kwargs): """pipe into callable with optional arguments""" if kwargs: func = functools.partial(func, **kwargs) return ChainedStudy(self, func) class ChainedStudy(Study): """chain of callables/studies""" funcs: tuple = () def __init__(self, *funcs): for func in funcs: if not callable(func): raise TypeError(f"Argument {func!r} is not callable!") self.funcs = funcs def __repr__(self): return " | ".join(repr(fn) for fn in self.funcs) def __call__(self, prices): result = prices for func in self.funcs: if result is None: return result = func(result) return result def pipe(self, func, **kwargs): """pipe into callable with optional arguments""" if kwargs: func = functools.partial(func, **kwargs) funcs = self.funcs + (func,) return self.__class__(*funcs) ```