feat: funciones Python para core, cybersecurity, datascience y finance
Agrega funciones Python reutilizables organizadas por dominio: - core: composicion funcional (pipe, compose, map, filter, reduce, etc.) - cybersecurity: analisis de amenazas y puertos - datascience: estadisticas y deteccion de outliers - finance: indicadores tecnicos y analisis financiero
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: annualized_volatility
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def annualized_volatility(returns: list, periods_per_year: float) -> float"
|
||||
description: "Calcula la volatilidad anualizada de una serie de retornos."
|
||||
tags: [finance, volatility, risk, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [math]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
daily_returns = [0.01, -0.005, 0.008, 0.003, -0.002, 0.006, 0.004]
|
||||
vol = annualized_volatility(daily_returns, 252.0)
|
||||
# Volatilidad anualizada (std * sqrt(252))
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Formula: std_muestral(returns) * sqrt(periods_per_year).
|
||||
Usa desviacion estandar muestral (n-1) para ser consistente con la practica financiera.
|
||||
Retorna 0.0 si hay menos de 2 retornos o periods_per_year es menor o igual a cero.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: bollinger_bands
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def bollinger_bands(data: list, period: int, num_std: float) -> tuple"
|
||||
description: "Calcula las Bandas de Bollinger (upper, middle, lower) de una serie de precios."
|
||||
tags: [finance, bollinger, volatility, indicator, python]
|
||||
uses_functions: [sma_py_finance]
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
prices = [10, 11, 12, 13, 14, 15, 14, 13, 12, 11]
|
||||
upper, middle, lower = bollinger_bands(prices, 5, 2.0)
|
||||
# middle es la SMA(5), upper/lower son middle +/- 2*std
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Retorna tupla de tres listas (upper, middle, lower). Cada lista tiene len(data) - period + 1 elementos.
|
||||
La desviacion estandar se calcula sobre la ventana de tamanio period (poblacional, no muestral).
|
||||
Usa internamente la funcion sma para la banda media.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: ema
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def ema(data: list, period: int) -> list"
|
||||
description: "Calcula la media movil exponencial (EMA) de una serie de precios."
|
||||
tags: [finance, moving-average, exponential, indicator, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
prices = [10, 11, 12, 13, 14, 15]
|
||||
result = ema(prices, 3)
|
||||
# [11.0, 11.5, 12.25, 13.125]
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
El primer valor de la EMA es el SMA del primer periodo. El multiplicador es 2 / (period + 1).
|
||||
Retorna len(data) - period + 1 elementos. Lista vacia si period invalido.
|
||||
@@ -0,0 +1,137 @@
|
||||
"""Finance domain — pure functions for financial indicators and calculations."""
|
||||
|
||||
import math
|
||||
|
||||
|
||||
def sma(data: list, period: int) -> list:
|
||||
"""Calcula la media movil simple (SMA) de una serie de precios."""
|
||||
if period <= 0 or period > len(data):
|
||||
return []
|
||||
result = []
|
||||
for i in range(period - 1, len(data)):
|
||||
window = data[i - period + 1 : i + 1]
|
||||
result.append(sum(window) / period)
|
||||
return result
|
||||
|
||||
|
||||
def ema(data: list, period: int) -> list:
|
||||
"""Calcula la media movil exponencial (EMA) de una serie de precios."""
|
||||
if period <= 0 or period > len(data):
|
||||
return []
|
||||
multiplier = 2.0 / (period + 1)
|
||||
# Primer valor es SMA del primer periodo
|
||||
first_sma = sum(data[:period]) / period
|
||||
result = [first_sma]
|
||||
for i in range(period, len(data)):
|
||||
val = (data[i] - result[-1]) * multiplier + result[-1]
|
||||
result.append(val)
|
||||
return result
|
||||
|
||||
|
||||
def rsi(data: list, period: int) -> list:
|
||||
"""Calcula el Relative Strength Index (RSI) de una serie de precios."""
|
||||
if period <= 0 or len(data) < period + 1:
|
||||
return []
|
||||
deltas = [data[i] - data[i - 1] for i in range(1, len(data))]
|
||||
gains = [d if d > 0 else 0.0 for d in deltas]
|
||||
losses = [-d if d < 0 else 0.0 for d in deltas]
|
||||
|
||||
avg_gain = sum(gains[:period]) / period
|
||||
avg_loss = sum(losses[:period]) / period
|
||||
|
||||
result = []
|
||||
if avg_loss == 0:
|
||||
result.append(100.0)
|
||||
else:
|
||||
rs = avg_gain / avg_loss
|
||||
result.append(100.0 - 100.0 / (1.0 + rs))
|
||||
|
||||
for i in range(period, len(deltas)):
|
||||
avg_gain = (avg_gain * (period - 1) + gains[i]) / period
|
||||
avg_loss = (avg_loss * (period - 1) + losses[i]) / period
|
||||
if avg_loss == 0:
|
||||
result.append(100.0)
|
||||
else:
|
||||
rs = avg_gain / avg_loss
|
||||
result.append(100.0 - 100.0 / (1.0 + rs))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def bollinger_bands(data: list, period: int, num_std: float) -> tuple:
|
||||
"""Calcula las Bandas de Bollinger (upper, middle, lower)."""
|
||||
if period <= 0 or period > len(data):
|
||||
return ([], [], [])
|
||||
middle = sma(data, period)
|
||||
upper = []
|
||||
lower = []
|
||||
for i in range(len(middle)):
|
||||
window = data[i : i + period]
|
||||
mean = middle[i]
|
||||
variance = sum((x - mean) ** 2 for x in window) / period
|
||||
std = math.sqrt(variance)
|
||||
upper.append(mean + num_std * std)
|
||||
lower.append(mean - num_std * std)
|
||||
return (upper, middle, lower)
|
||||
|
||||
|
||||
def sharpe_ratio(returns: list, risk_free_rate: float, periods_per_year: float) -> float:
|
||||
"""Calcula el Sharpe Ratio anualizado."""
|
||||
if len(returns) == 0 or periods_per_year <= 0:
|
||||
return 0.0
|
||||
n = len(returns)
|
||||
mean_return = sum(returns) / n
|
||||
excess = mean_return - risk_free_rate / periods_per_year
|
||||
variance = sum((r - mean_return) ** 2 for r in returns) / n
|
||||
std = math.sqrt(variance)
|
||||
if std == 0:
|
||||
return 0.0
|
||||
return (excess / std) * math.sqrt(periods_per_year)
|
||||
|
||||
|
||||
def max_drawdown(values: list) -> tuple:
|
||||
"""Calcula el max drawdown y los indices de inicio y fin."""
|
||||
if len(values) < 2:
|
||||
return (0.0, 0, 0)
|
||||
peak = values[0]
|
||||
peak_idx = 0
|
||||
max_dd = 0.0
|
||||
dd_start = 0
|
||||
dd_end = 0
|
||||
for i in range(1, len(values)):
|
||||
if values[i] > peak:
|
||||
peak = values[i]
|
||||
peak_idx = i
|
||||
dd = (peak - values[i]) / peak if peak != 0 else 0.0
|
||||
if dd > max_dd:
|
||||
max_dd = dd
|
||||
dd_start = peak_idx
|
||||
dd_end = i
|
||||
return (max_dd, dd_start, dd_end)
|
||||
|
||||
|
||||
def vwap(prices: list, volumes: list) -> float:
|
||||
"""Calcula el Volume-Weighted Average Price (VWAP)."""
|
||||
if len(prices) == 0 or len(prices) != len(volumes):
|
||||
return 0.0
|
||||
total_volume = sum(volumes)
|
||||
if total_volume == 0:
|
||||
return 0.0
|
||||
return sum(p * v for p, v in zip(prices, volumes)) / total_volume
|
||||
|
||||
|
||||
def log_return(price_start: float, price_end: float) -> float:
|
||||
"""Calcula el retorno logaritmico entre dos precios."""
|
||||
if price_start <= 0 or price_end <= 0:
|
||||
return 0.0
|
||||
return math.log(price_end / price_start)
|
||||
|
||||
|
||||
def annualized_volatility(returns: list, periods_per_year: float) -> float:
|
||||
"""Calcula la volatilidad anualizada de una serie de retornos."""
|
||||
if len(returns) < 2 or periods_per_year <= 0:
|
||||
return 0.0
|
||||
n = len(returns)
|
||||
mean = sum(returns) / n
|
||||
variance = sum((r - mean) ** 2 for r in returns) / (n - 1)
|
||||
return math.sqrt(variance) * math.sqrt(periods_per_year)
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: log_return
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def log_return(price_start: float, price_end: float) -> float"
|
||||
description: "Calcula el retorno logaritmico entre dos precios."
|
||||
tags: [finance, return, logarithmic, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [math]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
r = log_return(100.0, 110.0)
|
||||
# 0.09531... (aprox 9.53%)
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Formula: ln(price_end / price_start).
|
||||
Retorna 0.0 si alguno de los precios es menor o igual a cero.
|
||||
Los retornos logaritmicos son aditivos en el tiempo, a diferencia de los retornos simples.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: max_drawdown
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def max_drawdown(values: list) -> tuple"
|
||||
description: "Calcula el maximo drawdown y los indices de inicio y fin del peor periodo."
|
||||
tags: [finance, drawdown, risk, performance, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
portfolio = [100, 110, 105, 95, 102, 108, 90, 95]
|
||||
dd, start, end = max_drawdown(portfolio)
|
||||
# dd = 0.1818..., start = 1, end = 6 (de 110 a 90)
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Retorna tupla (max_dd, start_idx, end_idx) donde max_dd es fraccion (0.0 a 1.0).
|
||||
start_idx es el indice del pico previo, end_idx es el indice del valle.
|
||||
Retorna (0.0, 0, 0) si la lista tiene menos de 2 elementos.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: rsi
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def rsi(data: list, period: int) -> list"
|
||||
description: "Calcula el Relative Strength Index (RSI) de una serie de precios."
|
||||
tags: [finance, rsi, momentum, indicator, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
prices = [44, 44.34, 44.09, 43.61, 44.33, 44.83, 45.10, 45.42, 45.84, 46.08,
|
||||
45.89, 46.03, 45.61, 46.28, 46.28, 46.00, 46.03, 46.41, 46.22, 45.64]
|
||||
result = rsi(prices, 14)
|
||||
# Lista de valores RSI entre 0 y 100
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Usa el metodo de suavizado de Wilder (media exponencial modificada).
|
||||
Requiere al menos period + 1 datos de entrada. Retorna len(data) - period valores.
|
||||
RSI = 100 si no hay perdidas en el periodo (avg_loss == 0).
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: sharpe_ratio
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def sharpe_ratio(returns: list, risk_free_rate: float, periods_per_year: float) -> float"
|
||||
description: "Calcula el Sharpe Ratio anualizado de una serie de retornos."
|
||||
tags: [finance, sharpe, risk, performance, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [math]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
daily_returns = [0.01, -0.005, 0.008, 0.003, -0.002, 0.006, 0.004]
|
||||
sr = sharpe_ratio(daily_returns, 0.02, 252.0)
|
||||
# Sharpe ratio anualizado
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
risk_free_rate es la tasa anual (ej: 0.02 para 2%). Se convierte a tasa por periodo internamente.
|
||||
periods_per_year indica la frecuencia de los retornos (252 para diarios, 12 para mensuales).
|
||||
Retorna 0.0 si la desviacion estandar es cero o la lista esta vacia.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: sma
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def sma(data: list, period: int) -> list"
|
||||
description: "Calcula la media movil simple (SMA) de una serie de precios."
|
||||
tags: [finance, moving-average, indicator, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
prices = [10, 11, 12, 13, 14, 15]
|
||||
result = sma(prices, 3)
|
||||
# [11.0, 12.0, 13.0, 14.0]
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Retorna lista mas corta que la entrada (len - period + 1 elementos).
|
||||
Si period es mayor que len(data) o menor/igual a 0, retorna lista vacia.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: vwap
|
||||
kind: function
|
||||
lang: py
|
||||
domain: finance
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def vwap(prices: list, volumes: list) -> float"
|
||||
description: "Calcula el Volume-Weighted Average Price (VWAP)."
|
||||
tags: [finance, vwap, volume, indicator, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/finance/finance.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
prices = [100.0, 101.0, 102.0, 101.5]
|
||||
volumes = [1000, 1500, 1200, 800]
|
||||
result = vwap(prices, volumes)
|
||||
# 101.0888...
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Formula: sum(price_i * volume_i) / sum(volume_i).
|
||||
Retorna 0.0 si las listas estan vacias, tienen distinto tamanio, o el volumen total es cero.
|
||||
Reference in New Issue
Block a user