refactor(common): rename package option_mcp_common → mcp_common

This commit is contained in:
AdrianoDev
2026-04-27 17:37:35 +02:00
parent 563f4fc965
commit e888fc373d
48 changed files with 2394 additions and 74 deletions
@@ -0,0 +1,139 @@
from __future__ import annotations
def sma(values: list[float], period: int) -> float | None:
if len(values) < period:
return None
return sum(values[-period:]) / period
def rsi(closes: list[float], period: int = 14) -> float | None:
if len(closes) < period + 1:
return None
gains: list[float] = []
losses: list[float] = []
for i in range(1, len(closes)):
delta = closes[i] - closes[i - 1]
gains.append(max(delta, 0.0))
losses.append(-min(delta, 0.0))
avg_gain = sum(gains[:period]) / period
avg_loss = sum(losses[:period]) / period
for i in range(period, len(gains)):
avg_gain = (avg_gain * (period - 1) + gains[i]) / period
avg_loss = (avg_loss * (period - 1) + losses[i]) / period
if avg_loss == 0:
return 100.0
rs = avg_gain / avg_loss
return 100.0 - (100.0 / (1.0 + rs))
def _ema_series(values: list[float], period: int) -> list[float]:
if len(values) < period:
return []
k = 2.0 / (period + 1)
seed = sum(values[:period]) / period
out = [seed]
for v in values[period:]:
out.append(out[-1] + k * (v - out[-1]))
return out
def macd(
closes: list[float],
fast: int = 12,
slow: int = 26,
signal: int = 9,
) -> dict[str, float | None]:
nothing: dict[str, float | None] = {"macd": None, "signal": None, "hist": None}
if len(closes) < slow + signal:
return nothing
ema_fast = _ema_series(closes, fast)
ema_slow = _ema_series(closes, slow)
offset = slow - fast
aligned_fast = ema_fast[offset:]
macd_line = [f - s for f, s in zip(aligned_fast, ema_slow, strict=False)]
if len(macd_line) < signal:
return nothing
signal_line = _ema_series(macd_line, signal)
if not signal_line:
return nothing
last_macd = macd_line[-1]
last_sig = signal_line[-1]
return {
"macd": last_macd,
"signal": last_sig,
"hist": last_macd - last_sig,
}
def atr(
highs: list[float],
lows: list[float],
closes: list[float],
period: int = 14,
) -> float | None:
if len(closes) < period + 1:
return None
trs: list[float] = []
for i in range(1, len(closes)):
tr = max(
highs[i] - lows[i],
abs(highs[i] - closes[i - 1]),
abs(lows[i] - closes[i - 1]),
)
trs.append(tr)
if len(trs) < period:
return None
avg = sum(trs[:period]) / period
for i in range(period, len(trs)):
avg = (avg * (period - 1) + trs[i]) / period
return avg
def adx(
highs: list[float],
lows: list[float],
closes: list[float],
period: int = 14,
) -> dict[str, float | None]:
nothing: dict[str, float | None] = {"adx": None, "+di": None, "-di": None}
if len(closes) < 2 * period + 1:
return nothing
trs: list[float] = []
plus_dms: list[float] = []
minus_dms: list[float] = []
for i in range(1, len(closes)):
tr = max(
highs[i] - lows[i],
abs(highs[i] - closes[i - 1]),
abs(lows[i] - closes[i - 1]),
)
up = highs[i] - highs[i - 1]
dn = lows[i - 1] - lows[i]
plus_dm = up if (up > dn and up > 0) else 0.0
minus_dm = dn if (dn > up and dn > 0) else 0.0
trs.append(tr)
plus_dms.append(plus_dm)
minus_dms.append(minus_dm)
atr_s = sum(trs[:period])
pdm_s = sum(plus_dms[:period])
mdm_s = sum(minus_dms[:period])
dxs: list[float] = []
pdi = mdi = 0.0
for i in range(period, len(trs)):
atr_s = atr_s - atr_s / period + trs[i]
pdm_s = pdm_s - pdm_s / period + plus_dms[i]
mdm_s = mdm_s - mdm_s / period + minus_dms[i]
pdi = 100.0 * pdm_s / atr_s if atr_s else 0.0
mdi = 100.0 * mdm_s / atr_s if atr_s else 0.0
s = pdi + mdi
dx = 100.0 * abs(pdi - mdi) / s if s else 0.0
dxs.append(dx)
if len(dxs) < period:
return nothing
adx_val = sum(dxs[:period]) / period
for i in range(period, len(dxs)):
adx_val = (adx_val * (period - 1) + dxs[i]) / period
return {"adx": adx_val, "+di": pdi, "-di": mdi}