mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-07-24 13:10:26 +08:00
161 lines
4.6 KiB
Python
161 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
from functools import partial
|
|
from pandas import DataFrame, Series
|
|
from pandas.api.types import is_datetime64_any_dtype
|
|
from pandas_ta._typing import (
|
|
Float,
|
|
Int,
|
|
IntFloat,
|
|
List,
|
|
MaybeSeriesFrame,
|
|
Optional,
|
|
SeriesFrame
|
|
)
|
|
|
|
__all__ = [
|
|
'is_percent',
|
|
'v_bool',
|
|
'v_dataframe',
|
|
'v_float',
|
|
'v_int',
|
|
'v_str',
|
|
'v_ascending',
|
|
'v_datetime_ordered',
|
|
'v_drift',
|
|
'v_list',
|
|
'v_lowerbound',
|
|
'v_mamode',
|
|
'v_offset',
|
|
'v_pos_default',
|
|
'v_scalar',
|
|
'v_series',
|
|
'v_talib',
|
|
'v_tradingview',
|
|
'v_upperbound',
|
|
]
|
|
|
|
|
|
def is_percent(x: IntFloat) -> bool:
|
|
if isinstance(x, (int, float)):
|
|
return x is not None and 0 <= x <= 100
|
|
return False
|
|
|
|
def v_bool(var: bool, default: bool = True) -> bool:
|
|
"""Returns default=True if var is not a bool."""
|
|
if isinstance(var, bool):
|
|
return bool(var)
|
|
return default
|
|
|
|
def v_dataframe(obj: MaybeSeriesFrame) -> None:
|
|
if not isinstance(obj, (DataFrame, Series)):
|
|
print("[X] Requires a Pandas Series or DataFrame.")
|
|
|
|
def v_float(
|
|
var: IntFloat, default: IntFloat, ne: Optional[IntFloat] = 0.0
|
|
) -> Float:
|
|
"""Returns the default if var is not equal to the ne value."""
|
|
is_ne, is_var = isinstance(ne, (float, int)), isinstance(var, (float, int))
|
|
if is_ne and is_var and float(var) != float(ne):
|
|
return float(var)
|
|
return float(default)
|
|
|
|
def v_int(var: Int, default: Int, ne: Optional[Int] = 0) -> Int:
|
|
"""Returns the default if var is not equal to the ne value."""
|
|
is_ne, is_var = isinstance(ne, int), isinstance(var, int)
|
|
if is_ne and is_var and int(var) != int(ne):
|
|
return int(var)
|
|
return int(default)
|
|
|
|
def v_str(var: str, default: str) -> str:
|
|
""""Returns the default value if var is not a empty str"""
|
|
if isinstance(var, str) and len(var) > 0:
|
|
return f"{var}"
|
|
return f"{default}"
|
|
|
|
def v_ascending(var: bool) -> bool:
|
|
"""Returns True by default"""
|
|
return partial(v_bool, default=True)(var=var)
|
|
|
|
def v_datetime_ordered(df: SeriesFrame) -> bool:
|
|
if is_datetime64_any_dtype(df.index):
|
|
np_dt_index = df.index.to_numpy()
|
|
if np_dt_index[0] < np_dt_index[-1]:
|
|
return True
|
|
return False
|
|
|
|
def v_drift(var: Int) -> Int:
|
|
"""Defaults to 1"""
|
|
return partial(v_int, default=1, ne=0)(var=var)
|
|
|
|
def v_list(var: List, default: List = []) -> List:
|
|
"""Returns [] if not a valid list"""
|
|
if isinstance(var, list) and len(var) > 0:
|
|
return var
|
|
return default
|
|
|
|
def v_lowerbound(
|
|
var: IntFloat, bound: IntFloat = 0,
|
|
default: IntFloat = 0, strict: bool = True, complement: bool = False
|
|
) -> IntFloat:
|
|
"""Returns the default if var(iable) not greater(equal) than bound."""
|
|
var_type = None
|
|
if isinstance(var, float): var_type = float
|
|
if isinstance(var, int): var_type = int
|
|
|
|
if var_type is None:
|
|
return default
|
|
|
|
valid = False
|
|
if strict:
|
|
valid = var_type(var) > var_type(bound)
|
|
else:
|
|
valid = var_type(var) >= var_type(bound)
|
|
|
|
if complement: valid = not valid
|
|
|
|
if valid:
|
|
return var_type(var)
|
|
return default
|
|
|
|
def v_mamode(var: str, default: str) -> str: # Could be an alias.
|
|
return v_str(var, default)
|
|
|
|
def v_offset(var: Int) -> Int:
|
|
"""Defaults to 0"""
|
|
return partial(v_int, default=0, ne=0)(var=var)
|
|
|
|
def v_pos_default(
|
|
var: IntFloat, default: IntFloat = 0, strict: bool = True, complement: bool = False
|
|
) -> IntFloat:
|
|
return partial(v_lowerbound, bound=0) \
|
|
(var=var, default=default, strict=strict, complement=complement)
|
|
|
|
def v_scalar(var: IntFloat, default: Optional[IntFloat] = 1) -> Float:
|
|
"""Returns the default if var is not a float."""
|
|
if isinstance(var, (float, int)):
|
|
return float(var)
|
|
return float(default)
|
|
|
|
def v_series(series: Series, length: Optional[IntFloat] = 0) -> Optional[Series]:
|
|
"""Returns None if the Pandas Series does not meet the minimum length
|
|
required for the indicator."""
|
|
if series is not None and isinstance(series, Series):
|
|
if series.size >= v_pos_default(length, 0):
|
|
return series
|
|
return None
|
|
|
|
def v_talib(var: bool) -> bool:
|
|
"""Returns True by default"""
|
|
return partial(v_bool, default=True)(var=var)
|
|
|
|
def v_tradingview(var: bool) -> bool:
|
|
"""Returns True by default"""
|
|
return partial(v_bool, default=True)(var=var)
|
|
|
|
def v_upperbound(
|
|
var: IntFloat, bound: IntFloat = 0,
|
|
default: IntFloat = 0, strict: bool = True
|
|
) -> IntFloat:
|
|
return partial(v_lowerbound, complement=True)\
|
|
(var=var, bound=bound, default=default, strict=strict)
|