Skip to content

Commit 410c08c

Browse files
committed
#154 Refactor chaos and phase adjustment logic, fix tests.
1 parent 3664df2 commit 410c08c

File tree

2 files changed

+24
-59
lines changed

2 files changed

+24
-59
lines changed

tests/test_TradeRoutines.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ def test_EstimateTargetReachabilityCheckType(self):
12201220

12211221
# Test function call:
12221222
pIntegral, fIntegral = TradeRoutines.EstimateTargetReachability(
1223-
seriesLowTF, seriesHighTF, currentPrice, targetPrice, 12, 4, ddof=2
1223+
seriesLowTF, seriesHighTF, currentPrice, targetPrice, 12, 4, ddof=2, chaosTrust=1.0, phaseTrust=1.0
12241224
)
12251225

12261226
# Check return types:
@@ -1230,25 +1230,21 @@ def test_EstimateTargetReachabilityCheckType(self):
12301230

12311231
def test_EstimateTargetReachabilityPositive(self):
12321232
testCases = [
1233-
(self.GenerateSeries(150), self.GenerateSeries(40), 12, 3),
1234-
(self.GenerateSeries(300), self.GenerateSeries(60), 20, 5),
1235-
(self.GenerateSeries(1000), self.GenerateSeries(100), 15, 4),
1236-
(
1237-
self.GenerateSeries(250), self.GenerateSeries(80), 10, 3,
1238-
{"useChaos": True, "chaosModel": "hurst", "chaosTail": 100, "usePhase": True, "phaseDirection": "Buy"}
1239-
),
1233+
(self.GenerateSeries(150), self.GenerateSeries(40), 12, 3, 1.0, 1.0),
1234+
(self.GenerateSeries(300), self.GenerateSeries(60), 20, 5, 1.0, 0.9),
1235+
(self.GenerateSeries(1000), self.GenerateSeries(100), 15, 4, 0.9, 1.0),
1236+
(self.GenerateSeries(250), self.GenerateSeries(80), 10, 3, 0.9, 0.8),
12401237
]
12411238

12421239
for test in testCases:
1243-
seriesLowTF, seriesHighTF, horizonLowTF, horizonHighTF = test[:4]
1244-
kwargs = test[4] if len(test) > 4 else {}
1240+
seriesLowTF, seriesHighTF, horizonLowTF, horizonHighTF, chaosTrust, phaseTrust = test
12451241

12461242
currentPrice = seriesLowTF.iloc[-1]
12471243
targetPrice = currentPrice * 1.07
12481244

12491245
pIntegral, fIntegral = TradeRoutines.EstimateTargetReachability(
12501246
seriesLowTF, seriesHighTF, currentPrice, targetPrice,
1251-
horizonLowTF, horizonHighTF, ddof=2, **kwargs
1247+
horizonLowTF, horizonHighTF, ddof=2, chaosTrust=chaosTrust, phaseTrust=phaseTrust
12521248
)
12531249

12541250
# Probability must be within [0, 1]:
@@ -1271,11 +1267,11 @@ def test_EstimateTargetReachabilityNegative(self):
12711267
(emptySeries, emptySeries, 100, 110, 10, 5), # Empty Pandas series
12721268

12731269
# Edge cases with chaos/phase flags (should still return fallback):
1274-
([], [], 100, 110, 10, 5, {"useChaos": True, "chaosTail": 0}),
1275-
([100], [100], 100, 110, 10, 5, {"usePhase": True, "phaseDirection": "Sell"}),
1276-
(validSeries, validSeries, 100, 110, 10, 0, {"useChaos": True, "chaosTail": -100, "usePhase": True}),
1277-
(validSeries, validSeries, 100, 110, 10, 0, {"useChaos": True, "chaosTail": None, "usePhase": True}),
1278-
(validSeries, validSeries, 100, 110, 10, 0, {"useChaos": True, "chaosTail": 101, "usePhase": True}),
1270+
([], [], 100, 110, 10, 5, {"chaosTrust": 0, "phaseTrust": 0}),
1271+
([100], [100], 100, 110, 10, 5, {"chaosTrust": -1, "phaseTrust": -1}),
1272+
(validSeries, validSeries, 100, 110, 10, 0, {"chaosTrust": 0, "phaseTrust": -1}),
1273+
(validSeries, validSeries, 100, 110, 10, 0, {"chaosTrust": -1, "phaseTrust": 0}),
1274+
(validSeries, validSeries, 100, 110, 10, 0, {"chaosTrust": 100, "phaseTrust": 100}),
12791275
]
12801276

12811277
for test in testCases:
@@ -1305,13 +1301,7 @@ def test_EstimateTargetReachabilityPerformance(self):
13051301
targetPrice = currentPrice * 1.05
13061302

13071303
# Enable chaos and phase modifiers with tail slicing:
1308-
kwargs = {
1309-
"useChaos": True,
1310-
"chaosModel": "hurst",
1311-
"chaosTail": 1001,
1312-
"usePhase": True,
1313-
"phaseDirection": "Buy",
1314-
}
1304+
kwargs = {"chaosTrust": 0.8, "phaseTrust": 0.7}
13151305

13161306
startTime = time.perf_counter()
13171307

tksbrokerapi/TradeRoutines.py

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,11 +1699,8 @@ def EstimateTargetReachability(
16991699
horizonHighTF: int,
17001700
ddof: int = 2,
17011701
cleanWithHampel: bool = False,
1702-
useChaos: bool = False,
1703-
chaosModel: str = "hurst",
1704-
chaosTail: Optional[int] = None,
1705-
usePhase: bool = False,
1706-
phaseDirection: Optional[str] = None,
1702+
chaosTrust: float = 1.0,
1703+
phaseTrust: float = 1.0,
17071704
**kwargs
17081705
) -> tuple[float, str]:
17091706
"""
@@ -1729,14 +1726,8 @@ def EstimateTargetReachability(
17291726
:param cleanWithHampel: If `True`, applies outlier cleaning to both input series before computing log returns
17301727
using `HampelCleaner()` (`False` by default). Recommended for real market data where spikes,
17311728
anomalies, or gaps may distort volatility and probability estimates.
1732-
:param useChaos: If `True`, modifies the final probability based on chaos confidence (Hurst, DFA, etc.).
1733-
:param chaosModel: Chaos model to use
1734-
- `hurst`: fast estimation of Hurst exponent using the rescaled range (R/S) method, `FastHurst()`;
1735-
- `sampen`: fast Sample Entropy for chaos estimation, see `FastSampEn()`;
1736-
- `dfa`: fast Detrended Fluctuation Analysis (DFA) estimator, see `FastDfa()`.
1737-
:param chaosTail: Optional tail length of the series `seriesLowTF` and `seriesHighTF` used for chaos estimation. If `None`, use the full series.
1738-
:param usePhase: If `True`, modifies the final probability based on Bollinger-band phase, see `FastBBands()`.
1739-
:param phaseDirection: Trade direction: `Buy` or `Sell` (required for phase confidence).
1729+
:param chaosTrust: Trust coefficient based on chaos metric ∈ [0.0, 1.0]. Default is `1.0` (no modification), see also `ChaosConfidence()`.
1730+
:param phaseTrust: Trust coefficient based on Bollinger-band phase ∈ [0.0, 1.0]. Default is` 1.0` (no modification), see also `PhaseConfidence()`.
17401731
:param kwargs: Optional keyword arguments are forwarded to `HampelCleaner()` if `cleanWithHampel` is `True`.
17411732
Supported options (with default values):
17421733
- `window` (5): Sliding window size for `HampelCleaner()`.
@@ -1815,31 +1806,15 @@ def EstimateTargetReachability(
18151806
# --- Formula (12): Final integrated probability:
18161807
pIntegral = alpha * pBayes + (1 - alpha) * pAverage
18171808

1818-
# --- Chaos trust modifier (if enabled):
1819-
chaosTrust = 1.0
1820-
if useChaos:
1821-
tailL = seriesLowTF.values[-chaosTail:] if chaosTail else seriesLowTF.values
1822-
tailH = seriesHighTF.values[-chaosTail:] if chaosTail else seriesHighTF.values
1823-
1824-
chaosL = ChaosMeasure(tailL, model=chaosModel)
1825-
confL = ChaosConfidence(chaosL, chaosModel)
1826-
1827-
chaosH = ChaosMeasure(tailH, model=chaosModel)
1828-
confH = ChaosConfidence(chaosH, chaosModel)
1829-
1830-
chaosTrust = alpha * confL + (1 - alpha) * confH
1831-
1832-
# --- Phase trust modifier (if enabled):
1833-
phaseTrust = 1.0
1834-
if usePhase and phaseDirection:
1835-
bbLower = min(seriesLowTF.values[-1], seriesHighTF.values[-1])
1836-
bbUpper = max(seriesLowTF.values[-1], seriesHighTF.values[-1])
1837-
phase = PhaseLocation(currentPrice, bbLower, bbUpper)
1809+
# --- Apply combined trust modifiers:
1810+
if chaosTrust == 1.0 and phaseTrust == 1.0:
1811+
pFinal = pIntegral
18381812

1839-
phaseTrust = PhaseConfidence(phase, phaseDirection)
1813+
elif not (0.0 <= chaosTrust <= 1.0 and 0.0 <= phaseTrust <= 1.0):
1814+
pFinal = pIntegral # Skip adjustment if trust coefficients are invalid.
18401815

1841-
# --- Apply combined trust modifiers:
1842-
pFinal = pIntegral if chaosTrust == phaseTrust == 1.0 else AdjustProbabilityByChaosAndPhaseTrust(pIntegral, chaosTrust, phaseTrust)
1816+
else:
1817+
pFinal = AdjustProbabilityByChaosAndPhaseTrust(pIntegral, chaosTrust, phaseTrust)
18431818

18441819
# --- Formula (15): Fuzzy classification of the final probability:
18451820
fFinal = FUZZY_SCALE.Fuzzy(pFinal)["name"]

0 commit comments

Comments
 (0)