#property strict #include "../Include/CMarketModelFeatures.mqh" int g_feature_failures=0,g_feature_checks=0; void FeatureCheck(bool passed,string label) { g_feature_checks++; if(!passed) {g_feature_failures++;Print("[MARKET-FEATURE FAIL] ",label);} } int OnInit() { // Synthetic values exist only to test the feature contract, never training. MqlRates rates[]; ArrayResize(rates,40); ArraySetAsSeries(rates,false); for(int i=0;i<40;i++) { ZeroMemory(rates[i]); rates[i].time=D'2025.01.01 00:00:00'+i*3600; rates[i].close=0.8+0.0002*i+0.0001*MathSin(i); rates[i].open=rates[i].close-0.00005; rates[i].high=rates[i].close+0.0002; rates[i].low=rates[i].open-0.0002; rates[i].spread=7; } datetime decision=rates[21].time; double buy[],sell[],after[]; FeatureCheck(MarketModelFeaturesFromRates(rates,20,0,0.00001,decision,buy),"BUY features available"); FeatureCheck(MarketModelFeaturesFromRates(rates,20,1,0.00001,decision,sell),"SELL features available"); FeatureCheck(ArraySize(buy)==12 && ArraySize(sell)==12,"Twelve-feature schema"); string names[]; MarketModelFeatureNames(names); FeatureCheck(ArraySize(names)==12 && names[0]=="mm_signed_logret1" && names[11]=="mm_atr14","Stable feature names/order"); if(ArraySize(buy)==12 && ArraySize(sell)==12) { for(int i=0;i<12;i++) { bool signed_feature=(i<=3 || i==6 || i==10); FeatureCheck(MathAbs(sell[i]-(signed_feature ? -buy[i] : buy[i]))<1e-12,"Direction symmetry feature "+IntegerToString(i)); } FeatureCheck(MathAbs(buy[0]-MathLog(rates[20].close/rates[19].close))<1e-12,"Return references completed bars"); FeatureCheck(MathAbs(buy[7]-7*0.00001/rates[20].close)<1e-12,"Recorded spread normalization"); for(int i=21;i<40;i++) {rates[i].close=9999;rates[i].open=1;rates[i].high=10000;rates[i].low=0.1;} FeatureCheck(MarketModelFeaturesFromRates(rates,20,0,0.00001,decision,after),"Future/current values ignored"); bool identical=ArraySize(after)==12; for(int i=0;i