// Independent model 08: three-state Bayesian forward filter on return horizons.
#include <default.c>
var HMPrice[110];
var HMProbability[3];
var HMTransition[9] = {0.94, 0.03, 0.03, 0.03, 0.94, 0.03, 0.03, 0.03, 0.94};
var HMMean[3] = {1., -1., 0.};
var HMVariance[3] = {0.75, 0.75, 0.2};
int HMForwardInference()
{
int T, State, From;
var Sigma, R, LongObservation, ShortObservation, Predicted, Error;
var Evidence, Total;
var Updated[3];
for (State = 0; State < 3; State++)
{
HMProbability[State] = 1. / 3.;
}
for (T = 0; T < 110; T++)
{
if (!(HMPrice[T] > 0.))
{
return 0;
}
}
Sigma = 0.;
for (T = 81; T <= 100; T++)
{
R = log(HMPrice[T] / HMPrice[T + 1]);
Sigma += R * R / 20.;
}
if (Sigma < 1.e-20)
{
return 0;
}
Sigma = sqrt(Sigma);
// Fixed emissions and transition priors; no fitted HMM or hindsight labels.
for (T = 80; T >= 0; T--)
{
ShortObservation = log(HMPrice[T] / HMPrice[T + 1]) / Sigma;
LongObservation = log(HMPrice[T] / HMPrice[T + 4]) / (4. * Sigma);
Total = 0.;
for (State = 0; State < 3; State++)
{
Predicted = 0.;
for (From = 0; From < 3; From++)
{
Predicted += HMProbability[From] * HMTransition[From * 3 + State];
}
Error = (ShortObservation - HMMean[State]) * (ShortObservation - HMMean[State]);
Error += (LongObservation - HMMean[State]) * (LongObservation - HMMean[State]);
Evidence = exp(max(-80., -Error / (2. * HMVariance[State]))) / HMVariance[State];
Updated[State] = Predicted * Evidence;
Total += Updated[State];
}
if (Total <= 1.e-100)
{
return 0;
}
for (State = 0; State < 3; State++)
{
HMProbability[State] = Updated[State] / Total;
}
}
if (HMProbability[0] > 0.85)
{
return 1;
}
if (HMProbability[1] > 0.85)
{
return -1;
}
return 0;
}
void HMCheckPosterior()
{
int T, Problems;
var Sum;
Problems = 0;
for (T = 0; T < 110; T++)
{
HMPrice[T] = 1.;
}
if (HMForwardInference() != 0)
{
Problems++;
}
for (T = 0; T < 110; T++)
{
HMPrice[T] = exp(-0.001 * T);
}
if (HMForwardInference() != 1)
{
Problems++;
}
Sum = HMProbability[0] + HMProbability[1] + HMProbability[2];
if (abs(Sum - 1.) > 1.e-6)
{
Problems++;
}
for (T = 0; T < 110; T++)
{
HMPrice[T] = 1. / HMPrice[T];
}
if (HMForwardInference() != -1)
{
Problems++;
}
file_write("Log/TS08_HiddenMarkovCurve_test.txt", strf("4 checks; %d failures\n", Problems), 0);
}
var HMPosteriorEntropy()
{
int State;
var H;
H = 0.;
for (State = 0; State < 3; State++)
{
if (HMProbability[State] > 1.e-20)
{
H -= HMProbability[State] * log(HMProbability[State]) / log(3.);
}
}
return H;
}
var HMFutureBullProbability(int Steps)
{
int Step, From, To;
var P[3];
var Next[3];
if (Steps < 0 || Steps > 64)
{
return 0.;
}
for (From = 0; From < 3; From++)
{
P[From] = HMProbability[From];
}
for (Step = 0; Step < Steps; Step++)
{
for (To = 0; To < 3; To++)
{
Next[To] = 0.;
for (From = 0; From < 3; From++)
{
Next[To] += P[From] * HMTransition[From * 3 + To];
}
}
for (To = 0; To < 3; To++)
{
P[To] = Next[To];
}
}
return P[0];
}
var HMTransitionUncertainty()
{
int S, T;
var Result, P;
Result = 0.;
for (S = 0; S < 3; S++)
{
for (T = 0; T < 3; T++)
{
P = HMTransition[S * 3 + T];
if (P > 0.)
{
Result -= HMProbability[S] * P * log(P);
}
}
}
return Result;
}
void HMResearchDiagnostics()
{
printf("\nHMM bull %.6g; bear %.6g; neutral %.6g", HMProbability[0], HMProbability[1],
HMProbability[2]);
printf("\nHMM entropy %.6g; bull4 %.6g", HMPosteriorEntropy(), HMFutureBullProbability(4));
printf("\nHMM transition uncertainty %.6g", HMTransitionUncertainty());
}
// ============================================================================
// EXTENDED REGRESSION SUITE: deterministic properties over market regimes
// These functions run ONLY under STX_SELFTEST; they never place orders.
// ============================================================================
int HMExtendedCount = 0;
int HMExtendedFailures = 0;
void HMExpect(int Passed, string Description)
{
HMExtendedCount++;
if (!Passed)
{
HMExtendedFailures++;
file_append("Log/TS08_HiddenMarkovCurve_extended.txt", strf("FAIL: %s\n", Description));
}
}
void HMCase_quiet_cycle()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.0005 * sin(0.17 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "quiet_cycle: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "quiet_cycle: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "quiet_cycle: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "quiet_cycle: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "quiet_cycle: missing price rejected");
}
void HMCase_mixed_cycles()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.003 * sin(0.23 * K) + 0.0007 * cos(0.81 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "mixed_cycles: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "mixed_cycles: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "mixed_cycles: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "mixed_cycles: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "mixed_cycles: missing price rejected");
}
void HMCase_persistent_upward()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(-0.001 * K + 0.0001 * sin(0.53 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "persistent_upward: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "persistent_upward: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "persistent_upward: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "persistent_upward: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "persistent_upward: missing price rejected");
}
void HMCase_persistent_downward()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.001 * K + 0.0001 * cos(0.47 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "persistent_downward: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "persistent_downward: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "persistent_downward: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "persistent_downward: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "persistent_downward: missing price rejected");
}
void HMCase_slow_curve()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.004 * cos(0.08 * K) + 0.0002 * sin(0.7 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "slow_curve: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "slow_curve: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "slow_curve: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "slow_curve: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "slow_curve: missing price rejected");
}
void HMCase_rough_curve()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.001 * sin(1.7 * K) + 0.0005 * cos(2.3 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "rough_curve: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "rough_curve: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "rough_curve: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "rough_curve: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "rough_curve: missing price rejected");
}
void HMCase_accelerating_path()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(-0.0001 * K - 0.000002 * K * K + 0.0002 * sin(0.41 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "accelerating_path: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "accelerating_path: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "accelerating_path: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "accelerating_path: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "accelerating_path: missing price rejected");
}
void HMCase_decelerating_path()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(-0.0008 * K + 0.000002 * K * K + 0.0002 * cos(0.31 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "decelerating_path: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "decelerating_path: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "decelerating_path: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "decelerating_path: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "decelerating_path: missing price rejected");
}
void HMCase_volatility_ramp()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp((0.0001 + K * 0.00001) * sin(0.37 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "volatility_ramp: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "volatility_ramp: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "volatility_ramp: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "volatility_ramp: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "volatility_ramp: missing price rejected");
}
void HMCase_volatility_decay()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.006 * exp(-0.02 * K) * cos(0.7 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "volatility_decay: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "volatility_decay: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "volatility_decay: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "volatility_decay: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "volatility_decay: missing price rejected");
}
void HMCase_cycle_with_drift()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(-0.0002 * K + 0.003 * sin(0.19 * K) + 0.0005 * cos(0.61 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "cycle_with_drift: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "cycle_with_drift: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "cycle_with_drift: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "cycle_with_drift: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "cycle_with_drift: missing price rejected");
}
void HMCase_near_zero_prices()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 0.0001 * exp(0.002 * sin(0.29 * K) + 0.001 * cos(0.13 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "near_zero_prices: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "near_zero_prices: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "near_zero_prices: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "near_zero_prices: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "near_zero_prices: missing price rejected");
}
void HMCase_large_price_units()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 10000.0 * exp(0.003 * sin(0.11 * K) + 0.0008 * cos(0.43 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "large_price_units: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "large_price_units: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "large_price_units: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "large_price_units: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "large_price_units: missing price rejected");
}
void HMCase_high_frequency_chop()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.0008 * cos(2.8 * K) + 0.001 * sin(0.23 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "high_frequency_chop: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "high_frequency_chop: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "high_frequency_chop: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "high_frequency_chop: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "high_frequency_chop: missing price rejected");
}
void HMCase_long_wave_trend()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(-0.0005 * K + 0.002 * cos(0.07 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "long_wave_trend: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "long_wave_trend: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "long_wave_trend: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "long_wave_trend: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "long_wave_trend: missing price rejected");
}
void HMCase_opposing_scales()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.005 * sin(0.09 * K) - 0.002 * sin(0.59 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "opposing_scales: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "opposing_scales: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "opposing_scales: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "opposing_scales: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "opposing_scales: missing price rejected");
}
void HMCase_nonlinear_curve()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.002 * sin(0.021 * K * K) + 0.001 * cos(0.33 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "nonlinear_curve: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "nonlinear_curve: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "nonlinear_curve: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "nonlinear_curve: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "nonlinear_curve: missing price rejected");
}
void HMCase_amplitude_modulation()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.002 * sin(0.3 * K) * cos(0.04 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "amplitude_modulation: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "amplitude_modulation: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "amplitude_modulation: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "amplitude_modulation: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "amplitude_modulation: missing price rejected");
}
void HMCase_decaying_event()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.01 * exp(-0.2 * K) + 0.0003 * sin(0.71 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "decaying_event: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "decaying_event: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "decaying_event: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "decaying_event: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "decaying_event: missing price rejected");
}
void HMCase_time_varying_frequency()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.002 * cos(0.004 * K * K + 0.11 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "time_varying_frequency: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "time_varying_frequency: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "time_varying_frequency: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "time_varying_frequency: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "time_varying_frequency: missing price rejected");
}
void HMCase_slow_fast_cancellation()
{
int K, Original, Again, Scaled, Reflected;
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1.0 * exp(0.004 * sin(0.07 * K) + 0.0013 * cos(0.97 * K));
}
Original = HMForwardInference();
HMExpect(Original >= -1 && Original <= 1, "slow_fast_cancellation: bounded direction");
Again = HMForwardInference();
HMExpect(Again == Original, "slow_fast_cancellation: repeatable estimate");
for (K = 0; K < 110; K++)
{
HMPrice[K] *= 7.;
}
Scaled = HMForwardInference();
HMExpect(Scaled == Original, "slow_fast_cancellation: price-unit invariance");
for (K = 0; K < 110; K++)
{
HMPrice[K] = 1. / HMPrice[K];
}
Reflected = HMForwardInference();
HMExpect(Reflected == -Original, "slow_fast_cancellation: directional reflection");
HMPrice[55] = 0.;
HMExpect(HMForwardInference() == 0, "slow_fast_cancellation: missing price rejected");
}
void HMExtendedTests()
{
HMExtendedCount = 0;
HMExtendedFailures = 0;
file_write("Log/TS08_HiddenMarkovCurve_extended.txt",
"TS08_HiddenMarkovCurve: extended properties\n", 0);
HMCase_quiet_cycle();
HMCase_mixed_cycles();
HMCase_persistent_upward();
HMCase_persistent_downward();
HMCase_slow_curve();
HMCase_rough_curve();
HMCase_accelerating_path();
HMCase_decelerating_path();
HMCase_volatility_ramp();
HMCase_volatility_decay();
HMCase_cycle_with_drift();
HMCase_near_zero_prices();
HMCase_large_price_units();
HMCase_high_frequency_chop();
HMCase_long_wave_trend();
HMCase_opposing_scales();
HMCase_nonlinear_curve();
HMCase_amplitude_modulation();
HMCase_decaying_event();
HMCase_time_varying_frequency();
HMCase_slow_fast_cancellation();
file_append("Log/TS08_HiddenMarkovCurve_extended.txt",
strf("RESULT: %d checks; %d failures\n", HMExtendedCount, HMExtendedFailures));
}
function run()
{
#ifdef STX_SELFTEST
if (is(INITRUN))
{
HMCheckPosterior();
HMExtendedTests();
quit("HMM tests complete");
}
return;
#endif
int T, Regime;
var Units, AtRisk;
BarPeriod = 60;
LookBack = 111;
Capital = 10000.;
StartDate = 20240101;
EndDate = 20241231;
MaxLong = 1;
MaxShort = 1;
Hedge = 0;
if (!asset("EUR/USD"))
{
return;
}
algo("HM08");
if (is(EXITRUN))
{
HMResearchDiagnostics();
return;
}
if (is(LOOKBACK))
{
return;
}
for (T = 0; T < 110; T++)
{
HMPrice[T] = priceClose(T + 1);
}
Regime = HMForwardInference();
if (NumOpenLong > 0 && HMProbability[0] < 0.45)
{
exitLong();
}
if (NumOpenShort > 0 && HMProbability[1] < 0.45)
{
exitShort();
}
if (Regime == 0 || NumOpenLong + NumOpenShort > 0)
{
return;
}
if (Balance <= 0. || Equity <= Balance * 0.85)
{
return;
}
if (MarginCost <= 0. || PIP <= 0. || PIPCost <= 0. || LotAmount <= 0.)
{
return;
}
Stop = 50. * PIP;
TakeProfit = 125. * PIP;
LifeTime = 32;
AtRisk = PIPCost * (Stop + Spread) / PIP + Commission * LotAmount / 10000.;
if (AtRisk <= 0.)
{
return;
}
Units = min(2000. / LotAmount, Balance * 0.005 / AtRisk);
Units = min(Units, max(0., Equity - MarginVal) * 0.8 / MarginCost);
if (Units < 1.)
{
return;
}
Lots = floor(Units);
Margin = 0.;
Risk = 0.;
if (Regime > 0)
{
enterLong();
}
else
{
enterShort();
}
}