扩展指标
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
OHLCV bar aggregation utilities.
|
||||
|
||||
resample_ohlcv(open, high, low, close, volume, factor)
|
||||
Aggregate every `factor` bars into one OHLCV bar.
|
||||
open = first bar's open
|
||||
high = max of highs
|
||||
low = min of lows
|
||||
close = last bar's close
|
||||
volume = sum of volumes
|
||||
|
||||
resample_ohlcv_labels(n_bars, factor)
|
||||
Return an integer label array of length n_bars where label[i] = i // factor.
|
||||
Useful for aligning fine-bar signals with coarse-bar indicators.
|
||||
|
||||
align_to_coarse(coarse_values, factor, n_fine_bars)
|
||||
Broadcast a coarse-bar array back to fine-bar length by repeating each value `factor` times.
|
||||
Handles the case where n_fine_bars % factor != 0 (last group may be partial).
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import ArrayLike, NDArray
|
||||
|
||||
__all__ = ["resample_ohlcv", "resample_ohlcv_labels", "align_to_coarse"]
|
||||
|
||||
|
||||
def resample_ohlcv(
|
||||
open_: ArrayLike,
|
||||
high: ArrayLike,
|
||||
low: ArrayLike,
|
||||
close: ArrayLike,
|
||||
volume: ArrayLike,
|
||||
factor: int,
|
||||
) -> tuple[NDArray, NDArray, NDArray, NDArray, NDArray]:
|
||||
"""Aggregate fine-bar OHLCV into coarser bars.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
open_ : array-like
|
||||
Fine-bar open prices.
|
||||
high : array-like
|
||||
Fine-bar high prices.
|
||||
low : array-like
|
||||
Fine-bar low prices.
|
||||
close : array-like
|
||||
Fine-bar close prices.
|
||||
volume : array-like
|
||||
Fine-bar volume.
|
||||
factor : int
|
||||
Number of fine bars per coarse bar (e.g. 5 for 1-min -> 5-min).
|
||||
|
||||
Returns
|
||||
-------
|
||||
(open, high, low, close, volume) arrays of length ceil(n / factor).
|
||||
Only complete groups are returned — if n % factor != 0, trailing bars are dropped.
|
||||
"""
|
||||
if factor < 1:
|
||||
raise ValueError(f"factor must be >= 1, got {factor}")
|
||||
|
||||
o = np.asarray(open_, dtype=np.float64)
|
||||
h = np.asarray(high, dtype=np.float64)
|
||||
low_arr = np.asarray(low, dtype=np.float64)
|
||||
c = np.asarray(close, dtype=np.float64)
|
||||
v = np.asarray(volume, dtype=np.float64)
|
||||
|
||||
n = len(o)
|
||||
n_complete = (n // factor) * factor # truncate to complete bars
|
||||
|
||||
o = o[:n_complete].reshape(-1, factor)
|
||||
h = h[:n_complete].reshape(-1, factor)
|
||||
low_arr = low_arr[:n_complete].reshape(-1, factor)
|
||||
c = c[:n_complete].reshape(-1, factor)
|
||||
v = v[:n_complete].reshape(-1, factor)
|
||||
|
||||
return (
|
||||
o[:, 0], # open = first bar's open
|
||||
h.max(axis=1), # high = max of highs
|
||||
low_arr.min(axis=1), # low = min of lows
|
||||
c[:, -1], # close = last bar's close
|
||||
v.sum(axis=1), # volume = sum of volumes
|
||||
)
|
||||
|
||||
|
||||
def resample_ohlcv_labels(n_bars: int, factor: int) -> NDArray:
|
||||
"""Return coarse-bar index for each fine bar (i // factor).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n_bars : int
|
||||
Number of fine-resolution bars.
|
||||
factor : int
|
||||
Number of fine bars per coarse bar.
|
||||
|
||||
Returns
|
||||
-------
|
||||
NDArray of int64, shape (n_bars,), where label[i] = i // factor.
|
||||
"""
|
||||
if factor < 1:
|
||||
raise ValueError(f"factor must be >= 1, got {factor}")
|
||||
return np.arange(n_bars, dtype=np.int64) // factor
|
||||
|
||||
|
||||
def align_to_coarse(coarse_values: ArrayLike, factor: int, n_fine_bars: int) -> NDArray:
|
||||
"""Broadcast coarse-bar array back to fine-bar resolution.
|
||||
|
||||
Each coarse value is repeated `factor` times. If n_fine_bars % factor != 0,
|
||||
the last coarse value covers the partial group at the end.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
coarse_values : array-like
|
||||
Values at coarse resolution, shape (n_coarse,).
|
||||
factor : int
|
||||
Number of fine bars per coarse bar.
|
||||
n_fine_bars : int
|
||||
Total number of fine bars to produce.
|
||||
|
||||
Returns
|
||||
-------
|
||||
NDArray of shape (n_fine_bars,).
|
||||
"""
|
||||
if factor < 1:
|
||||
raise ValueError(f"factor must be >= 1, got {factor}")
|
||||
|
||||
coarse = np.asarray(coarse_values, dtype=np.float64)
|
||||
n_coarse = len(coarse)
|
||||
|
||||
# Build the full repeated array (may be longer than n_fine_bars if partial group exists)
|
||||
repeated = np.repeat(coarse, factor)
|
||||
|
||||
# If repeated is shorter than n_fine_bars (shouldn't happen with correct n_coarse,
|
||||
# but handle defensively), pad with last value
|
||||
if len(repeated) < n_fine_bars:
|
||||
pad = np.full(
|
||||
n_fine_bars - len(repeated), coarse[-1] if n_coarse > 0 else np.nan
|
||||
)
|
||||
repeated = np.concatenate([repeated, pad])
|
||||
|
||||
return repeated[:n_fine_bars]
|
||||
Reference in New Issue
Block a user