// ArimaIndicatorMatrix_v03_feedback.c
#define NUM_MODULES 12
#define TF_M30 1
#define TF_H1 2
#define TF_H2 4
#define TF_H4 8
#define TF_D1 48
// -----------------------------------------------------------------------------
// ARIMA package interface
// -----------------------------------------------------------------------------
// UseARIMAFilter is the old close-price confirmation filter.
// The main strategy below does not rely on that old filter. It creates ARIMA
// forecasts of the module indicator series themselves.
// -----------------------------------------------------------------------------
#define PRAGMA_API init_auto_arima_result;AutoAri32!init_auto_arima_result
#define PRAGMA_API free_auto_arima_result;AutoAri32!free_auto_arima_result
#define PRAGMA_API auto_arima_forecast;AutoAri32!auto_arima_forecast
#define PRAGMA_API aa_validate_price_series;AutoAri32!aa_validate_price_series
int UseARIMAFilter = 0; // old close-price gate; indicator ARIMA is the main logic
int ARIMA_N = 160; // number of close prices used for the forecast
int ARIMA_MaxP = 3; // maximum AR order searched by auto_arima_forecast
int ARIMA_MaxQ = 3; // maximum MA order searched by auto_arima_forecast
var ARIMA_MinPips = 2.0; // minimum forecast edge in pips
int ARIMA_PlotForecast = 0; // plots old price forecast only if UseARIMAFilter is enabled
int UseARIMAIndicatorPrediction = 1;
var ARIMA_MinOscDelta = 0.75; // RSI/Stoch/Band position forecast delta
var ARIMA_MinTrendDelta = 0.60; // trend/pressure forecast delta
var ARIMA_MinWidthDelta = 0.00001;
// -----------------------------------------------------------------------------
// ARIMA meta-prediction layer
// -----------------------------------------------------------------------------
// This layer measures the previous success rate of every indicator forecast.
// It then applies auto_arima_forecast(...) to the hit/miss stream itself.
// The CSV output lets us later discover under which indicator conditions the
// ARIMA prediction stream was reliable.
//
// Hit stream scale:
// 80 = previous forecast direction was correct
// 20 = previous forecast direction was wrong
// 50 = previous forecast edge was too small / neutral
#define META_FIELD_SLOTS 28
#define META_SERIES_CAP 80
#define META_RATE_CAP 20
int UseARIMAMetaPrediction = 1;
int UseARIMAMetaLog = 1;
int ARIMA_MetaN = META_SERIES_CAP;
int ARIMA_MetaRateN = META_RATE_CAP;
var GMetaForecast[META_FIELD_SLOTS][META_SERIES_CAP];
var GMetaHit[META_FIELD_SLOTS][META_SERIES_CAP];
int GMetaInitialized[META_FIELD_SLOTS];
int GMetaLastBar[META_FIELD_SLOTS];
// v03 feedback-controller state.
// These parameters are changed from previous prediction quality before the
// next indicator ARIMA forecast is calculated.
int UseARIMAParameterFeedback = 1;
int ARIMA_MinAdaptiveN = 80;
int ARIMA_MaxAdaptiveN = 240;
int ARIMA_MaxAdaptiveOrder = 5;
var ARIMA_ReliabilityLow = 0.46;
var ARIMA_ReliabilityHigh = 0.62;
var ARIMA_ErrorHigh = 1.40;
int GMetaUseN[META_FIELD_SLOTS];
int GMetaUseP[META_FIELD_SLOTS];
int GMetaUseQ[META_FIELD_SLOTS];
var GMetaDeltaMult[META_FIELD_SLOTS];
var GMetaLastRate[META_FIELD_SLOTS];
var GMetaLastRel[META_FIELD_SLOTS];
var GMetaLastErr[META_FIELD_SLOTS];
var GMetaParamQuality[META_FIELD_SLOTS];
typedef struct AUTO_ARIMA_RESULT
{
int p;
int d;
int q;
int converged;
var sse;
var aicc;
var forecast;
var* ar;
var* ma;
int arCap;
int maCap;
} AUTO_ARIMA_RESULT;
AUTO_ARIMA_RESULT GArimaResult;
int GArimaInitialized = 0;
// ARIMA DLL imports.
// The README signature for auto_arima_forecast is:
// int auto_arima_forecast(vars Close,int N,var TickSize,int MaxP,int MaxQ,AUTO_ARIMA_RESULT* Result)
int auto_arima_forecast(vars Close,int N,var TickSize,int MaxP,int MaxQ,AUTO_ARIMA_RESULT* Result);
int aa_validate_price_series(vars Close,int N);
void init_auto_arima_result(AUTO_ARIMA_RESULT* R);
void free_auto_arima_result(AUTO_ARIMA_RESULT* R);
void InitARIMAOnce()
{
if(GArimaInitialized)
return;
init_auto_arima_result(&GArimaResult);
GArimaInitialized = 1;
}
void ResetARIMAResult()
{
if(!GArimaInitialized)
return;
free_auto_arima_result(&GArimaResult);
init_auto_arima_result(&GArimaResult);
}
int ARIMAAllowsDirection(int dir,vars C)
{
if(!UseARIMAFilter)
return 1;
if(ARIMA_N < 30)
return 1;
if(Bar < LookBack)
return 0;
InitARIMAOnce();
// Avoid accumulating result-owned coefficient arrays between calls.
ResetARIMAResult();
if(!aa_validate_price_series(C,ARIMA_N))
return 0;
int ok = auto_arima_forecast(C,ARIMA_N,PIP,ARIMA_MaxP,ARIMA_MaxQ,&GArimaResult);
if(!ok)
{
printf("\nARIMA forecast failed: Asset=%s Algo=%s Bar=%i",Asset,Algo,Bar);
return 0;
}
var Threshold = ARIMA_MinPips*PIP;
var Edge = GArimaResult.forecast - C[0];
int Signal = 0;
if(Edge > Threshold)
Signal = 1;
else if(Edge < -Threshold)
Signal = -1;
if(ARIMA_PlotForecast)
plot("ARIMA Forecast",GArimaResult.forecast,LINE,BLUE);
if(dir > 0 && Signal > 0)
return 1;
if(dir < 0 && Signal < 0)
return 1;
return 0;
}
var ARIMAForecastSeries(vars Data,int N,var TickSize,int MaxP,int MaxQ,int* OK)
{
*OK = 0;
if(!UseARIMAIndicatorPrediction)
{
*OK = 1;
return Data[0];
}
if(N < 30)
return Data[0];
if(Bar < LookBack)
return Data[0];
InitARIMAOnce();
ResetARIMAResult();
if(!aa_validate_price_series(Data,N))
return Data[0];
int Status = auto_arima_forecast(
Data,
N,
TickSize,
MaxP,
MaxQ,
&GArimaResult
);
if(!Status)
return Data[0];
if(!GArimaResult.converged)
return Data[0];
if(invalid(GArimaResult.forecast))
return Data[0];
*OK = 1;
return GArimaResult.forecast;
}
int ARIMAForecastUp(var Forecast,var CurrentValue,var MinDelta)
{
if(Forecast - CurrentValue > MinDelta)
return 1;
return 0;
}
int ARIMAForecastDown(var Forecast,var CurrentValue,var MinDelta)
{
if(CurrentValue - Forecast > MinDelta)
return 1;
return 0;
}
var ARIMAMetaRate(vars HitS,int N)
{
if(N < 1)
return 0.50;
var Sum = 0;
int i;
for(i=0;i<N;i++)
Sum += HitS[i];
return clamp((Sum/N)/100.0,0.,1.);
}
void InitMetaParams(int Slot)
{
if(Slot < 0 || Slot >= META_FIELD_SLOTS)
return;
GMetaUseN[Slot] = ARIMA_N;
GMetaUseP[Slot] = ARIMA_MaxP;
GMetaUseQ[Slot] = ARIMA_MaxQ;
GMetaDeltaMult[Slot] = 1.0;
GMetaLastRate[Slot] = 0.50;
GMetaLastRel[Slot] = 0.50;
GMetaLastErr[Slot] = 1.0;
GMetaParamQuality[Slot] = 0.50;
}
void ResetMetaState()
{
int i;
for(i=0;i<META_FIELD_SLOTS;i++)
{
GMetaInitialized[i] = 0;
GMetaLastBar[i] = -1;
InitMetaParams(i);
}
}
void AdaptMetaParams(int Slot,var Rate,var Rel,var ErrNorm,var DriftNorm)
{
if(Slot < 0 || Slot >= META_FIELD_SLOTS)
return;
if(!UseARIMAParameterFeedback)
{
InitMetaParams(Slot);
return;
}
var Quality = 0.50*Rate + 0.50*Rel;
int NewN = ARIMA_N;
int NewP = ARIMA_MaxP;
int NewQ = ARIMA_MaxQ;
var NewDeltaMult = 1.0;
// Good recent prediction stream: shorter memory, lower order, more responsive.
if(Quality >= ARIMA_ReliabilityHigh and ErrNorm < ARIMA_ErrorHigh)
{
NewN = ARIMA_N - 40;
NewP = ARIMA_MaxP - 1;
NewQ = ARIMA_MaxQ - 1;
NewDeltaMult = 0.85;
}
// Weak prediction stream: longer memory, more flexible model, stricter delta.
if(Quality <= ARIMA_ReliabilityLow)
{
NewN = ARIMA_N + 60;
NewP = ARIMA_MaxP + 1;
NewQ = ARIMA_MaxQ + 1;
NewDeltaMult = 1.25;
}
// High realized forecast error: make the next forecast more conservative.
if(ErrNorm > ARIMA_ErrorHigh)
{
NewN = NewN + 40;
NewP = NewP + 1;
NewQ = NewQ + 1;
NewDeltaMult += 0.20;
}
// Large recent forecast edge but poor quality: demand a bigger future edge.
if(abs(DriftNorm) > 2.0 and Quality < 0.55)
NewDeltaMult += 0.15;
if(NewN < ARIMA_MinAdaptiveN)
NewN = ARIMA_MinAdaptiveN;
if(NewN > ARIMA_MaxAdaptiveN)
NewN = ARIMA_MaxAdaptiveN;
if(NewP < 1)
NewP = 1;
if(NewQ < 1)
NewQ = 1;
if(NewP > ARIMA_MaxAdaptiveOrder)
NewP = ARIMA_MaxAdaptiveOrder;
if(NewQ > ARIMA_MaxAdaptiveOrder)
NewQ = ARIMA_MaxAdaptiveOrder;
GMetaUseN[Slot] = NewN;
GMetaUseP[Slot] = NewP;
GMetaUseQ[Slot] = NewQ;
GMetaDeltaMult[Slot] = clamp(NewDeltaMult,0.70,1.70);
GMetaLastRate[Slot] = Rate;
GMetaLastRel[Slot] = Rel;
GMetaLastErr[Slot] = ErrNorm;
GMetaParamQuality[Slot] = Quality;
}
int MetaFieldSlot(string ModuleName,string FieldName)
{
if(strstr(ModuleName,"AP1_BandOsc")) {
if(strstr(FieldName,"band")) return 0;
if(strstr(FieldName,"stoch")) return 1;
if(strstr(FieldName,"width")) return 2;
}
if(strstr(ModuleName,"AP2_RSIState")) {
if(strstr(FieldName,"band")) return 3;
if(strstr(FieldName,"rsi")) return 4;
}
if(strstr(ModuleName,"AP3_ChannelOsc")) {
if(strstr(FieldName,"kpos")) return 5;
if(strstr(FieldName,"stoch")) return 6;
}
if(strstr(ModuleName,"AP4_CloudFlow")) {
if(strstr(FieldName,"spread")) return 7;
if(strstr(FieldName,"cloud")) return 8;
if(strstr(FieldName,"stoch")) return 9;
}
if(strstr(ModuleName,"AP5_Pressure")) {
if(strstr(FieldName,"pressure")) return 10;
if(strstr(FieldName,"rsi")) return 11;
if(strstr(FieldName,"trend")) return 12;
}
if(strstr(ModuleName,"AP6_DriftADX")) {
if(strstr(FieldName,"ema")) return 13;
if(strstr(FieldName,"trend")) return 14;
if(strstr(FieldName,"di")) return 15;
if(strstr(FieldName,"adx")) return 16;
}
if(strstr(ModuleName,"AP7_RangeFlow")) {
if(strstr(FieldName,"pos")) return 17;
if(strstr(FieldName,"trend")) return 18;
}
if(strstr(ModuleName,"AP8_MacdFlow")) {
if(strstr(FieldName,"hist")) return 19;
if(strstr(FieldName,"trend")) return 20;
}
if(strstr(ModuleName,"AP9_RSIPath")) return 21;
if(strstr(ModuleName,"AP10_BandEnergy")) {
if(strstr(FieldName,"width")) return 22;
if(strstr(FieldName,"pos")) return 23;
}
if(strstr(ModuleName,"AP11_GreyPath")) {
if(strstr(FieldName,"grey")) return 24;
if(strstr(FieldName,"slope")) return 25;
}
if(strstr(ModuleName,"AP12_ShapePath")) {
if(strstr(FieldName,"pole")) return 26;
if(strstr(FieldName,"break")) return 27;
}
return -1;
}
void MetaShift(var* Data,int Count)
{
int i;
for(i=Count-1;i>0;i--)
Data[i] = Data[i-1];
}
void EnsureMetaSlot(int Slot,var ForecastValue)
{
int i;
if(Slot < 0 || Slot >= META_FIELD_SLOTS)
return;
if(!GMetaInitialized[Slot])
{
for(i=0;i<META_SERIES_CAP;i++)
{
GMetaForecast[Slot][i] = ForecastValue;
GMetaHit[Slot][i] = 50.;
}
GMetaInitialized[Slot] = 1;
GMetaLastBar[Slot] = Bar;
InitMetaParams(Slot);
return;
}
if(GMetaLastBar[Slot] != Bar)
{
MetaShift(&GMetaForecast[Slot][0],META_SERIES_CAP);
MetaShift(&GMetaHit[Slot][0],META_SERIES_CAP);
GMetaLastBar[Slot] = Bar;
}
}
var ARIMAMetaRel(vars ValueS,vars ForecastS,vars HitS,var MinDelta,int* OK)
{
*OK = 0;
if(!UseARIMAMetaPrediction)
{
*OK = 1;
return 1.0;
}
var PrevEdge = ForecastS[1] - ValueS[1];
var ActualMove = ValueS[0] - ValueS[1];
var Hit = 50.0;
if(abs(PrevEdge) > MinDelta)
{
if(PrevEdge * ActualMove > 0)
Hit = 80.0;
else
Hit = 20.0;
}
HitS[0] = Hit;
int HOk = 0;
var HF = ARIMAForecastSeries(HitS,ARIMA_MetaN,0.01,ARIMA_MaxP,ARIMA_MaxQ,&HOk);
if(!HOk)
return ARIMAMetaRate(HitS,ARIMA_MetaRateN);
*OK = 1;
return clamp(HF/100.0,0.,1.);
}
var ARIMAForecastMeta(string ModuleName,string FieldName,vars Data,int N,var TickSize,var MinDelta,int* OK)
{
int RawOK = 0;
int Slot = MetaFieldSlot(ModuleName,FieldName);
int MetaOK = 0;
int UseN = N;
int UseP = ARIMA_MaxP;
int UseQ = ARIMA_MaxQ;
var UseDelta = MinDelta;
var Rel = 1.0;
var Rate = 0.50;
var ErrNorm = 0.;
var DriftNorm = 0.;
var Quality = 0.50;
var DeltaMultLog = 1.0;
if(Slot >= 0)
{
EnsureMetaSlot(Slot,Data[0]);
// Step 1: evaluate the previous indicator forecast now that the actual
// current indicator value is known. This is causal: only previous
// forecast quality can influence the current forecast parameters.
var PrevForecast = GMetaForecast[Slot][1];
var PrevEdge = PrevForecast - Data[1];
var PrevError = abs(PrevForecast - Data[0]);
ErrNorm = PrevError / fix0(MinDelta*4.0);
DriftNorm = PrevEdge / fix0(MinDelta);
Rel = ARIMAMetaRel(Data,&GMetaForecast[Slot][0],&GMetaHit[Slot][0],MinDelta,&MetaOK);
Rate = ARIMAMetaRate(&GMetaHit[Slot][0],ARIMA_MetaRateN);
// Step 2: adapt the parameters for the next indicator ARIMA call.
AdaptMetaParams(Slot,Rate,Rel,ErrNorm,DriftNorm);
UseN = GMetaUseN[Slot];
UseP = GMetaUseP[Slot];
UseQ = GMetaUseQ[Slot];
UseDelta = MinDelta * GMetaDeltaMult[Slot];
Quality = GMetaParamQuality[Slot];
DeltaMultLog = GMetaDeltaMult[Slot];
}
// Step 3: current indicator forecast uses parameters already modified by
// the previous forecast-success model.
var F = ARIMAForecastSeries(Data,UseN,TickSize,UseP,UseQ,&RawOK);
if(Slot >= 0)
GMetaForecast[Slot][0] = F;
if(UseARIMAMetaLog)
{
file_append("Log\\ArimaIndicatorMeta.csv",
strf("%s,%i,%s,%s,%.6f,%.6f,%.6f,%.4f,%.4f,%i,%i,%i,%i,%i,%.4f,%.4f,%.4f\n",
Asset,Bar,ModuleName,FieldName,Data[0],F,F-Data[0],
Rate,Rel,RawOK,MetaOK,UseN,UseP,UseQ,DeltaMultLog,ErrNorm,Quality),0);
}
*OK = RawOK;
// Return the forecast. The caller still uses ARIMAForecastUp/Down, but now
// its MinDelta should be interpreted through the Slot's current delta
// multiplier. To keep module code stable, the forecast itself is adjusted
// toward Data[0] when the adaptive threshold is high.
if(Slot >= 0 and UseDelta > MinDelta)
{
var Shrink = clamp((UseDelta/MinDelta - 1.0)*0.50,0.,0.35);
F = Data[0] + (F-Data[0])*(1.0-Shrink);
}
return F;
}
void FreeARIMA()
{
if(!GArimaInitialized)
return;
free_auto_arima_result(&GArimaResult);
GArimaInitialized = 0;
}
// -----------------------------------------------------------------------------
// Global inputs
// -----------------------------------------------------------------------------
var RiskPercent = 2.0;
int ATR_Period = 14;
int UseSessionFilter = 1;
int SessionStartHour = 7;
int SessionEndHour = 20;
int UseFixedRiskBase = 1;
var FixedRiskBalance = 10000;
var MaxLotCap = 0; // not used directly; Zorro sizes through Risk/Margin/Lots.
int UseTrailing = 1;
int UseBreakeven = 1;
int UseRegimeDirection = 1;
int Regime_MA = 200;
int Regime_UseSlope = 1;
int Regime_NeutralAllowBoth = 1;
int AllowLongs = 1;
int AllowShorts = 0;
int UseTrendQualityGate = 1;
int TQ_ADX_Period = 14;
var TQ_ADX_Min = 18.0;
int UseRiskCap = 1;
var MaxPortfolioRiskPct = 15.0;
int MaxOpenPositions = 12;
int UseAdaptiveMults = 1;
int Adapt_FastATR = 14;
int Adapt_SlowATR = 100;
var Adapt_Min = 0.75;
var Adapt_Max = 1.50;
// Module master switches
int Use_BB_Stoch = 1; // M1
int Use_BB_RSI = 1; // M2
int Use_Keltner_Stoch = 1; // M3
int Use_Ichimoku_Stoch = 1; // M4
int Use_Supertrend_RSI = 1; // M5
int Use_EMA_ADX = 1; // M6
int Use_Donchian = 1; // M7
int Use_MACD_EMA = 1; // M8
int Use_RSI_MR = 1; // M9
int Use_BB_Squeeze = 1; // M10
int Use_Grey = 1; // M11
int Use_Flag = 1; // M12
// M1
int M1_BB_Period = 20; var M1_BB_Dev = 2.0;
int M1_Stoch_K = 14; int M1_Stoch_D = 3; int M1_Stoch_Slowing = 3;
var M1_Stoch_OS = 20.0; var M1_Stoch_OB = 80.0;
int M1_UseRangeFilter = 1; int M1_ADX_Period = 14; var M1_ADX_RangeMax = 25.0;
int M1_UseReversionConfirm = 1;
var M1_TrailMult = 1.0; var M1_TrailStart = 1.0;
var M1_BE_Mult = 1.0; var M1_SL_Mult = 1.5; var M1_TP_Mult = 1.5;
// M2
int M2_BB_Period = 20; var M2_BB_Dev = 2.0;
int M2_RSI_Period = 14; var M2_RSI_OS = 30.0; var M2_RSI_OB = 70.0;
int M2_UseRangeFilter = 1; int M2_ADX_Period = 14; var M2_ADX_RangeMax = 25.0;
int M2_UseReversionConfirm = 1;
int M2_TP_AtMid = 1;
int M2_StructuralSL = 1;
var M2_SL_Buffer = 0.5;
var M2_TrailMult = 1.0; var M2_TrailStart = 0.8;
var M2_BE_Mult = 1.0; var M2_SL_Mult = 1.5; var M2_TP_Mult = 2.0;
// M3
int M3_EMA_Period = 20; int M3_ATR_Period = 10; var M3_ATR_Mult = 2.0;
int M3_Stoch_K = 14; int M3_Stoch_D = 3; int M3_Stoch_Slowing = 3;
var M3_Stoch_OS = 20.0; var M3_Stoch_OB = 80.0;
int M3_UseRangeFilter = 0; int M3_ADX_Period = 14; var M3_ADX_RangeMax = 25.0;
var M3_TrailMult = 1.5; var M3_TrailStart = 1.0;
var M3_BE_Mult = 1.0; var M3_SL_Mult = 1.5; var M3_TP_Mult = 2.5;
// M4
int M4_Tenkan = 9; int M4_Kijun = 26; int M4_Senkou = 52;
int M4_Stoch_K = 14; int M4_Stoch_D = 3; int M4_Stoch_Slowing = 3;
var M4_Stoch_OS = 40.0; var M4_Stoch_OB = 60.0;
int M4_UseADXFilter = 0; int M4_ADX_Period = 14; var M4_ADX_Min = 20.0;
var M4_TrailMult = 2.0; var M4_TrailStart = 1.5;
var M4_BE_Mult = 1.0; var M4_SL_Mult = 1.5; var M4_TP_Mult = 3.0;
// M5
int M5_ATR_Period = 10; var M5_ATR_Mult = 3.0;
int M5_RSI_Period = 14; var M5_RSI_OS = 35.0; var M5_RSI_OB = 65.0;
var M5_RSI_BuyLo = 40.0; var M5_RSI_SellHi = 60.0;
int M5_UseADXFilter = 1; int M5_ADX_Period = 14; var M5_ADX_Min = 25.0;
int M5_UseTrendAlign = 1; int M5_TrendEMA = 100;
int M5_MomConfirm = 1;
var M5_TrailMult = 2.5; var M5_TrailStart = 1.5;
var M5_BE_Mult = 1.0; var M5_SL_Mult = 1.5; var M5_TP_Mult = 3.0;
// M6
int M6_EMA_Fast = 9; int M6_EMA_Slow = 21; int M6_EMA_Trend = 50;
int M6_ADX_Period = 14; var M6_ADX_Min = 25.0; var M6_DI_Sep = 3.0;
int M6_RequirePullback = 0; int M6_UseSlopeFilter = 1;
var M6_TrailMult = 2.0; var M6_TrailStart = 1.5;
var M6_BE_Mult = 1.0; var M6_SL_Mult = 1.5; var M6_TP_Mult = 3.0;
// M7
int M7_Donch_Period = 20;
int M7_UseADXFilter = 1; int M7_ADX_Period = 14; var M7_ADX_Min = 30.0;
int M7_UseTrendAlign = 1; int M7_TrendEMA = 100;
int M7_UseSlopeFilter = 1;
var M7_MaxExtATR = 1.0;
var M7_TrailMult = 2.5; var M7_TrailStart = 1.5;
var M7_BE_Mult = 1.0; var M7_SL_Mult = 1.5; var M7_TP_Mult = 3.5;
// M8
int M8_MACD_Fast = 12; int M8_MACD_Slow = 26; int M8_MACD_Signal = 9;
int M8_TrendEMA = 100;
int M8_RequireZeroSide = 1;
int M8_UseSlopeFilter = 0;
int M8_UseADXFilter = 1; int M8_ADX_Period = 14; var M8_ADX_Min = 20.0;
var M8_TrailMult = 2.0; var M8_TrailStart = 1.5;
var M8_BE_Mult = 1.0; var M8_SL_Mult = 1.5; var M8_TP_Mult = 3.0;
// M9
int M9_RSI_Period = 14; var M9_RSI_OS = 35.0; var M9_RSI_OB = 65.0;
int M9_UseRangeFilter = 1; int M9_ADX_Period = 14; var M9_ADX_RangeMax = 25.0;
int M9_RequireSustain = 1;
var M9_TrailMult = 1.0; var M9_TrailStart = 0.8;
var M9_BE_Mult = 1.0; var M9_SL_Mult = 1.5; var M9_TP_Mult = 1.8;
// M10
int M10_BB_Period = 20; var M10_BB_Dev = 2.0; var M10_SqueezeRatio = 0.8;
int M10_UseADXFilter = 1; int M10_ADX_Period = 14; var M10_ADX_Min = 30.0;
int M10_UseTrendAlign = 1; int M10_TrendEMA = 100;
var M10_TrailMult = 2.5; var M10_TrailStart = 1.5;
var M10_BE_Mult = 1.0; var M10_SL_Mult = 1.5; var M10_TP_Mult = 3.5;
// M11
int M11_Period = 24;
int M11_Filter = 250;
int M11_UseTrendFilter = 1; int M11_TrendEMA = 100;
int M11_RequirePersist = 1;
var M11_TrailMult = 2.0; var M11_TrailStart = 1.5;
var M11_BE_Mult = 1.0; var M11_SL_Mult = 1.5; var M11_TP_Mult = 3.0;
// M12
int M12_PoleBars = 5;
var M12_PoleATRMult = 1.8;
int M12_FlagBars = 5;
var M12_FlagMaxATR = 1.6;
int M12_UseTrendFilter = 1; int M12_MA_Period = 200;
var M12_SL_PoleMult = 1.0;
var M12_TP_PoleMult = 1.5;
var M12_TrailMult = 2.5; var M12_TrailStart = 1.5;
var M12_BE_Mult = 1.0;
// Zorro asset names. Adjust to your Assets*.csv / broker mapping.
// lite-C can be picky with global string-array initializers, so use a function
// instead of: string Symbols[3] = { "EUR/USD", "GBP/USD", "XAU/USD" };
#define NUM_SYMBOLS 3
int Use_EURUSD = 1;
int Use_GBPUSD = 0; // enable after importing GBPUSD history files
int Use_XAUUSD = 0; // enable after importing XAUUSD history files
string SymbolName(int Index)
{
if(Index == 0) return "EUR/USD";
if(Index == 1) return "GBP/USD";
if(Index == 2) return "XAU/USD";
return "";
}
int SymbolEnabled(int Index)
{
if(Index == 0) return Use_EURUSD;
if(Index == 1) return Use_GBPUSD;
if(Index == 2) return Use_XAUUSD;
return 0;
}
// -----------------------------------------------------------------------------
// Utility
// -----------------------------------------------------------------------------
int contains(string s,string token)
{
if(strstr(s,token) != 0) return 1;
return 0;
}
int isForexAsset()
{
if(contains(Asset,"EUR")) return 1;
if(contains(Asset,"GBP")) return 1;
if(contains(Asset,"USD") && !contains(Asset,"XAU")) return 1;
return 0;
}
int isMetalAsset()
{
if(contains(Asset,"XAU")) return 1;
if(contains(Asset,"XAG")) return 1;
if(contains(Asset,"GOLD")) return 1;
if(contains(Asset,"SILVER")) return 1;
return 0;
}
int ModuleRuns(int idx)
{
if(idx == 0 && !Use_BB_Stoch) return 0;
if(idx == 1 && !Use_BB_RSI) return 0;
if(idx == 2 && !Use_Keltner_Stoch) return 0;
if(idx == 3 && !Use_Ichimoku_Stoch) return 0;
if(idx == 4 && !Use_Supertrend_RSI) return 0;
if(idx == 5 && !Use_EMA_ADX) return 0;
if(idx == 6 && !Use_Donchian) return 0;
if(idx == 7 && !Use_MACD_EMA) return 0;
if(idx == 8 && !Use_RSI_MR) return 0;
if(idx == 9 && !Use_BB_Squeeze) return 0;
if(idx == 10 && !Use_Grey) return 0;
if(idx == 11 && !Use_Flag) return 0;
// v8.11 logic from the uploaded EA:
// FOREX = M3 + M9 only.
if(isForexAsset())
{
if(idx == 2) return 1;
if(idx == 8) return 1;
return 0;
}
// METALS = M3,M5,M6,M7,M8,M9,M10,M12.
if(isMetalAsset())
{
if(idx == 2) return 1;
if(idx == 4) return 1;
if(idx == 5) return 1;
if(idx == 6) return 1;
if(idx == 7) return 1;
if(idx == 8) return 1;
if(idx == 9) return 1;
if(idx == 11) return 1;
return 0;
}
return 1;
}
int IsModuleBar(int tf)
{
if(tf <= 1) return 1;
if(Bar % tf == 0) return 1;
return 0;
}
int SessionOK(int tf)
{
if(!UseSessionFilter) return 1;
if(tf >= TF_D1) return 1;
if(hour(0) >= SessionStartHour && hour(0) < SessionEndHour) return 1;
return 0;
}
int CountTotalOpen()
{
int n = 0;
for(open_trades)
n++;
return n;
}
int CurrentAlgoHasOpen()
{
int n = 0;
for(current_trades)
n++;
if(n > 0) return 1;
return 0;
}
var clampv(var x,var lo,var hi)
{
if(x < lo) return lo;
if(x > hi) return hi;
return x;
}
var highestS(vars Data,int offset,int period)
{
var h = Data[offset];
int i;
for(i=offset+1;i<offset+period;i++)
if(Data[i] > h) h = Data[i];
return h;
}
var lowestS(vars Data,int offset,int period)
{
var l = Data[offset];
int i;
for(i=offset+1;i<offset+period;i++)
if(Data[i] < l) l = Data[i];
return l;
}
var smaAt(vars Data,int offset,int period)
{
var sum = 0;
int i;
for(i=offset;i<offset+period;i++)
sum += Data[i];
return sum/period;
}
var stdAt(vars Data,int offset,int period)
{
var m = smaAt(Data,offset,period);
var sum = 0;
int i;
for(i=offset;i<offset+period;i++)
sum += (Data[i]-m)*(Data[i]-m);
return sqrt(sum/period);
}
var emaAt(vars Data,int offset,int period)
{
int start = offset + period*3;
var a = 2.0/(period+1.0);
var e = Data[start];
int i;
for(i=start-1;i>=offset;i--)
e = a*Data[i] + (1.0-a)*e;
return e;
}
void bbAt(vars C,int period,var dev,int offset,var* mid,var* upper,var* lower)
{
*mid = smaAt(C,offset,period);
var sd = stdAt(C,offset,period);
*upper = *mid + dev*sd;
*lower = *mid - dev*sd;
}
var atrAt(vars H,vars L,vars C,int offset,int period)
{
var sum = 0;
int i;
for(i=offset;i<offset+period;i++)
{
var a = H[i]-L[i];
var b = abs(H[i]-C[i+1]);
var c = abs(L[i]-C[i+1]);
var tr = max(a,max(b,c));
sum += tr;
}
return sum/period;
}
var rsiAt(vars C,int offset,int period)
{
var up = 0;
var dn = 0;
int i;
for(i=offset;i<offset+period;i++)
{
var d = C[i]-C[i+1];
if(d > 0) up += d;
else dn -= d;
}
if(dn <= 0) return 100;
var rs = up/dn;
return 100.0 - 100.0/(1.0+rs);
}
void stochAt(vars H,vars L,vars C,int kPeriod,int dPeriod,int offset,var* kOut,var* dOut)
{
var hh = highestS(H,offset,kPeriod);
var ll = lowestS(L,offset,kPeriod);
if(hh == ll)
*kOut = 50;
else
*kOut = 100.0*(C[offset]-ll)/(hh-ll);
var sum = 0;
int j;
for(j=0;j<dPeriod;j++)
{
var h2 = highestS(H,offset+j,kPeriod);
var l2 = lowestS(L,offset+j,kPeriod);
var k2 = 50;
if(h2 != l2) k2 = 100.0*(C[offset+j]-l2)/(h2-l2);
sum += k2;
}
*dOut = sum/dPeriod;
}
var adxApprox(vars H,vars L,vars C,int offset,int period,var* diPlus,var* diMinus)
{
var trsum = 0;
var pdm = 0;
var mdm = 0;
int i;
for(i=offset;i<offset+period;i++)
{
var upMove = H[i]-H[i+1];
var dnMove = L[i+1]-L[i];
if(upMove > dnMove && upMove > 0) pdm += upMove;
if(dnMove > upMove && dnMove > 0) mdm += dnMove;
var tr = max(H[i]-L[i],max(abs(H[i]-C[i+1]),abs(L[i]-C[i+1])));
trsum += tr;
}
if(trsum <= 0)
{
*diPlus = 0;
*diMinus = 0;
return 0;
}
*diPlus = 100.0*pdm/trsum;
*diMinus = 100.0*mdm/trsum;
var den = *diPlus + *diMinus;
if(den <= 0) return 0;
return 100.0*abs(*diPlus-*diMinus)/den;
}
var macdLineAt(vars C,int offset,int fast,int slow)
{
return emaAt(C,offset,fast)-emaAt(C,offset,slow);
}
var macdSignalAt(vars C,int offset,int fast,int slow,int sig)
{
var tmp[100];
int i;
int n = sig*3;
if(n > 90) n = 90;
for(i=0;i<n;i++)
tmp[i] = macdLineAt(C,offset+i,fast,slow);
var a = 2.0/(sig+1.0);
var e = tmp[n-1];
for(i=n-2;i>=0;i--)
e = a*tmp[i] + (1.0-a)*e;
return e;
}
int trendQualityOK(vars H,vars L,vars C,int regime)
{
if(!UseTrendQualityGate) return 1;
if(regime != -1) return 1;
var p,m;
var adx = adxApprox(H,L,C,0,TQ_ADX_Period,&p,&m);
if(adx >= TQ_ADX_Min) return 1;
return 0;
}
var adaptFactor(vars H,vars L,vars C)
{
if(!UseAdaptiveMults) return 1.0;
var fast = atrAt(H,L,C,0,Adapt_FastATR);
var slow = atrAt(H,L,C,0,Adapt_SlowATR);
if(slow <= 0) return 1.0;
return clampv(fast/slow,Adapt_Min,Adapt_Max);
}
int directionBlocked(int dir,vars C)
{
int isBuy = 0;
if(dir > 0) isBuy = 1;
if(UseRegimeDirection)
{
// Uses current module's timeframe as a practical approximation.
// For a strict D1 regime filter, move this calculation into a dedicated D1 TimeFrame block.
var ma0 = smaAt(C,0,Regime_MA);
var ma1 = smaAt(C,1,Regime_MA);
int slopeUp = 0;
int slopeDn = 0;
if(ma0 > ma1) slopeUp = 1;
if(ma0 < ma1) slopeDn = 1;
if(C[0] > ma0 && (!Regime_UseSlope || slopeUp))
{
if(!isBuy) return 1;
return 0;
}
if(C[0] < ma0 && (!Regime_UseSlope || slopeDn))
{
if(isBuy) return 1;
return 0;
}
if(Regime_NeutralAllowBoth) return 0;
return 1;
}
if(isBuy && !AllowLongs) return 1;
if(!isBuy && !AllowShorts) return 1;
return 0;
}
void openTradeDir(int dir,string name,var slDist,var tpDist,var trailMult,var trailStart,var beMult,vars C)
{
if(slDist <= 0 || tpDist <= 0) return;
if(directionBlocked(dir,C)) return;
if(!ARIMAAllowsDirection(dir,C)) return;
if(UseRiskCap && MaxOpenPositions > 0 && CountTotalOpen() >= MaxOpenPositions) return;
algo(name);
if(CurrentAlgoHasOpen()) return;
Stop = slDist;
TakeProfit = tpDist;
// Zorro has no global BreakEven variable.
// Breakeven-style behavior is approximated through TrailLock.
// TrailLock = 1 moves the stop to about entry/breakeven once the Trail trigger is reached.
// IMPORTANT: reset all trail-related globals before every new trade so values do not leak
// from one module/component into the next.
Trail = 0;
TrailSlope = 100;
TrailLock = 0;
TrailStep = 0;
if(UseTrailing)
Trail = trailMult*slDist;
if(UseBreakeven && Trail > 0)
TrailLock = 1;
var base = FixedRiskBalance;
if(!UseFixedRiskBase) base = Balance;
Risk = base*RiskPercent/100.0;
if(dir > 0)
enterLong();
else
enterShort();
}
// -----------------------------------------------------------------------------
// M11 Grey estimator
// -----------------------------------------------------------------------------
var greyMA(vars O,int offset,int period)
{
if(period < 3) period = 3;
var grey[80];
var rez[1600];
int j,k,cnt;
if(period > 40) period = 40;
for(j=0;j<period;j++)
grey[j] = O[offset+j];
for(j=period-2;j>=0;j--)
grey[j] = grey[j] + grey[j+1];
cnt = 0;
for(j=period-2;j>=0;j--)
{
for(k=j+1;k<period;k++)
{
rez[cnt] = (grey[j]-grey[k])/(k-j);
cnt++;
}
}
// simple ascending sort
int a,b;
for(a=0;a<cnt-1;a++)
{
for(b=a+1;b<cnt;b++)
{
if(rez[b] < rez[a])
{
var t = rez[a];
rez[a] = rez[b];
rez[b] = t;
}
}
}
int i1 = cnt/2;
int i2 = i1;
if(cnt%2 == 0) i2 = i1 + 1;
if(i2 >= cnt) i2 = cnt-1;
return (rez[i1]+rez[i2])/2.0;
}
// -----------------------------------------------------------------------------
// Modules
// -----------------------------------------------------------------------------
void Module1_BB_Stoch()
{
if(!ModuleRuns(0)) return;
TimeFrame = TF_M30;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars BandPosS = series(0,ARIMA_MaxAdaptiveN);
vars StochKS = series(0,ARIMA_MaxAdaptiveN);
vars WidthS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_M30)) return;
if(!SessionOK(TF_M30)) return;
if(!trendQualityOK(H,L,C,1)) return;
var dip,dim;
if(M1_UseRangeFilter)
if(adxApprox(H,L,C,0,M1_ADX_Period,&dip,&dim) >= M1_ADX_RangeMax) return;
var m1,u1,l1,m2,u2,l2;
bbAt(C,M1_BB_Period,M1_BB_Dev,0,&m1,&u1,&l1);
bbAt(C,M1_BB_Period,M1_BB_Dev,1,&m2,&u2,&l2);
var k1,d1;
stochAt(H,L,C,M1_Stoch_K,M1_Stoch_D,0,&k1,&d1);
var bandRange = u1-l1;
if(bandRange <= 0) return;
var bandPos = 100.0*(C[0]-l1)/bandRange;
bandPos = clampv(bandPos,1.,99.);
var widthNow = (u1-l1)/fix0(m1);
if(widthNow <= 0) widthNow = 0.0001;
BandPosS[0] = bandPos;
StochKS[0] = clampv(k1,1.,99.);
WidthS[0] = widthNow;
int BOk = 0;
int SOk = 0;
int WOk = 0;
var bandF = ARIMAForecastMeta("AP1_BandOsc","band",BandPosS,ARIMA_N,0.01,ARIMA_MinOscDelta,&BOk);
var stochF = ARIMAForecastMeta("AP1_BandOsc","stoch",StochKS,ARIMA_N,0.01,ARIMA_MinOscDelta,&SOk);
var widthF = ARIMAForecastMeta("AP1_BandOsc","width",WidthS,ARIMA_N,0.0001,ARIMA_MinWidthDelta,&WOk);
int buy = 0;
int sell = 0;
if(BOk && SOk && WOk)
{
if(bandPos < 40. and ARIMAForecastUp(bandF,bandPos,ARIMA_MinOscDelta)
and ARIMAForecastUp(stochF,k1,ARIMA_MinOscDelta)
and widthF <= widthNow*1.08)
buy = 1;
if(bandPos > 60. and ARIMAForecastDown(bandF,bandPos,ARIMA_MinOscDelta)
and ARIMAForecastDown(stochF,k1,ARIMA_MinOscDelta)
and widthF <= widthNow*1.08)
sell = 1;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP1_BandOsc",M1_SL_Mult*af*atr,M1_TP_Mult*af*atr,M1_TrailMult,M1_TrailStart,M1_BE_Mult,C);
if(sell) openTradeDir(-1,"AP1_BandOsc",M1_SL_Mult*af*atr,M1_TP_Mult*af*atr,M1_TrailMult,M1_TrailStart,M1_BE_Mult,C);
}
void Module2_BB_RSI()
{
if(!ModuleRuns(1)) return;
TimeFrame = TF_H2;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars BandPosS = series(0,ARIMA_MaxAdaptiveN);
vars RSIS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H2)) return;
if(!SessionOK(TF_H2)) return;
var dip,dim;
if(M2_UseRangeFilter)
if(adxApprox(H,L,C,0,M2_ADX_Period,&dip,&dim) >= M2_ADX_RangeMax) return;
var m1,u1,l1,m2,u2,l2;
bbAt(C,M2_BB_Period,M2_BB_Dev,0,&m1,&u1,&l1);
bbAt(C,M2_BB_Period,M2_BB_Dev,1,&m2,&u2,&l2);
var r0 = rsiAt(C,0,M2_RSI_Period);
var bandRange = u1-l1;
if(bandRange <= 0) return;
var bandPos = 100.0*(C[0]-l1)/bandRange;
bandPos = clampv(bandPos,1.,99.);
BandPosS[0] = bandPos;
RSIS[0] = clampv(r0,1.,99.);
int BOk = 0;
int ROk = 0;
var bandF = ARIMAForecastMeta("AP2_RSIState","band",BandPosS,ARIMA_N,0.01,ARIMA_MinOscDelta,&BOk);
var rF = ARIMAForecastMeta("AP2_RSIState","rsi",RSIS,ARIMA_N,0.01,ARIMA_MinOscDelta,&ROk);
int buy = 0;
int sell = 0;
if(BOk && ROk)
{
if(bandPos < 42. and r0 < M2_RSI_OS+10.
and ARIMAForecastUp(bandF,bandPos,ARIMA_MinOscDelta)
and ARIMAForecastUp(rF,r0,ARIMA_MinOscDelta))
buy = 1;
if(bandPos > 58. and r0 > M2_RSI_OB-10.
and ARIMAForecastDown(bandF,bandPos,ARIMA_MinOscDelta)
and ARIMAForecastDown(rF,r0,ARIMA_MinOscDelta))
sell = 1;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
var slDist = M2_SL_Mult*af*atr;
var tpDist = M2_TP_Mult*af*atr;
if(M2_TP_AtMid)
{
if(buy)
{
tpDist = max(m1-priceClose(0),0.8*af*atr);
if(M2_StructuralSL)
slDist = max(priceClose(0)-(min(L[0],L[1])-M2_SL_Buffer*af*atr),0.5*af*atr);
openTradeDir(1,"AP2_RSIState",slDist,tpDist,M2_TrailMult,M2_TrailStart,M2_BE_Mult,C);
}
if(sell)
{
tpDist = max(priceClose(0)-m1,0.8*af*atr);
if(M2_StructuralSL)
slDist = max((max(H[0],H[1])+M2_SL_Buffer*af*atr)-priceClose(0),0.5*af*atr);
openTradeDir(-1,"AP2_RSIState",slDist,tpDist,M2_TrailMult,M2_TrailStart,M2_BE_Mult,C);
}
}
else
{
if(buy) openTradeDir(1,"AP2_RSIState",slDist,tpDist,M2_TrailMult,M2_TrailStart,M2_BE_Mult,C);
if(sell) openTradeDir(-1,"AP2_RSIState",slDist,tpDist,M2_TrailMult,M2_TrailStart,M2_BE_Mult,C);
}
}
void Module3_Keltner_Stoch()
{
if(!ModuleRuns(2)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars KPosS = series(0,ARIMA_MaxAdaptiveN);
vars StochS = series(0,ARIMA_MaxAdaptiveN);
var dip,dim;
if(M3_UseRangeFilter)
if(adxApprox(H,L,C,0,M3_ADX_Period,&dip,&dim) >= M3_ADX_RangeMax) return;
var ema0 = emaAt(C,0,M3_EMA_Period);
var atrK0 = atrAt(H,L,C,0,M3_ATR_Period);
if(atrK0 <= 0) return;
var k0,d0;
stochAt(H,L,C,M3_Stoch_K,M3_Stoch_D,0,&k0,&d0);
var kPos = 50.0 + 50.0*(C[0]-ema0)/fix0(M3_ATR_Mult*atrK0);
kPos = clampv(kPos,1.,99.);
KPosS[0] = kPos;
StochS[0] = clampv(k0,1.,99.);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
int KOk = 0;
int SOk = 0;
var kPosF = ARIMAForecastMeta("AP3_ChannelOsc","kpos",KPosS,ARIMA_N,0.01,ARIMA_MinOscDelta,&KOk);
var stF = ARIMAForecastMeta("AP3_ChannelOsc","stoch",StochS,ARIMA_N,0.01,ARIMA_MinOscDelta,&SOk);
int buy = 0;
int sell = 0;
if(KOk && SOk)
{
if(kPos < 45. and ARIMAForecastUp(kPosF,kPos,ARIMA_MinOscDelta)
and ARIMAForecastUp(stF,k0,ARIMA_MinOscDelta))
buy = 1;
if(kPos > 55. and ARIMAForecastDown(kPosF,kPos,ARIMA_MinOscDelta)
and ARIMAForecastDown(stF,k0,ARIMA_MinOscDelta))
sell = 1;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP3_ChannelOsc",M3_SL_Mult*af*atr,M3_TP_Mult*af*atr,M3_TrailMult,M3_TrailStart,M3_BE_Mult,C);
if(sell) openTradeDir(-1,"AP3_ChannelOsc",M3_SL_Mult*af*atr,M3_TP_Mult*af*atr,M3_TrailMult,M3_TrailStart,M3_BE_Mult,C);
}
void Module4_Ichimoku_Stoch()
{
if(!ModuleRuns(3)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars SpreadS = series(0,ARIMA_MaxAdaptiveN);
vars CloudS = series(0,ARIMA_MaxAdaptiveN);
vars StochS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var dip,dim;
if(M4_UseADXFilter)
if(adxApprox(H,L,C,0,M4_ADX_Period,&dip,&dim) < M4_ADX_Min) return;
var tenkan0 = (highestS(H,0,M4_Tenkan)+lowestS(L,0,M4_Tenkan))/2.0;
var kijun0 = (highestS(H,0,M4_Kijun)+lowestS(L,0,M4_Kijun))/2.0;
var senkouA = (tenkan0+kijun0)/2.0;
var senkouB = (highestS(H,0,M4_Senkou)+lowestS(L,0,M4_Senkou))/2.0;
var top = max(senkouA,senkouB);
var bot = min(senkouA,senkouB);
var cloudMid = (top+bot)/2.0;
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
if(top-bot < atr*0.3) return;
var k,d;
stochAt(H,L,C,M4_Stoch_K,M4_Stoch_D,0,&k,&d);
var spreadScore = 50.0 + 20.0*(tenkan0-kijun0)/atr;
var cloudScore = 50.0 + 20.0*(C[0]-cloudMid)/atr;
spreadScore = clampv(spreadScore,1.,99.);
cloudScore = clampv(cloudScore,1.,99.);
SpreadS[0] = spreadScore;
CloudS[0] = cloudScore;
StochS[0] = clampv(k,1.,99.);
int SpOk = 0;
int ClOk = 0;
int StOk = 0;
var spF = ARIMAForecastMeta("AP4_CloudFlow","spread",SpreadS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&SpOk);
var clF = ARIMAForecastMeta("AP4_CloudFlow","cloud",CloudS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&ClOk);
var stF = ARIMAForecastMeta("AP4_CloudFlow","stoch",StochS,ARIMA_N,0.01,ARIMA_MinOscDelta,&StOk);
int buy = 0;
int sell = 0;
if(SpOk && ClOk && StOk)
{
if(spF > 52. and clF > 52.
and ARIMAForecastUp(spF,spreadScore,ARIMA_MinTrendDelta)
and ARIMAForecastUp(clF,cloudScore,ARIMA_MinTrendDelta)
and stF > k)
buy = 1;
if(spF < 48. and clF < 48.
and ARIMAForecastDown(spF,spreadScore,ARIMA_MinTrendDelta)
and ARIMAForecastDown(clF,cloudScore,ARIMA_MinTrendDelta)
and stF < k)
sell = 1;
}
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP4_CloudFlow",M4_SL_Mult*af*atr,M4_TP_Mult*af*atr,M4_TrailMult,M4_TrailStart,M4_BE_Mult,C);
if(sell) openTradeDir(-1,"AP4_CloudFlow",M4_SL_Mult*af*atr,M4_TP_Mult*af*atr,M4_TrailMult,M4_TrailStart,M4_BE_Mult,C);
}
int superDir(vars H,vars L,vars C,int atrPeriod,var mult,int offset)
{
var atr = atrAt(H,L,C,offset,atrPeriod);
var mid = (H[offset]+L[offset])/2.0;
if(C[offset] > mid + mult*atr*0.25) return 1;
if(C[offset] < mid - mult*atr*0.25) return -1;
return 0;
}
void Module5_Supertrend_RSI()
{
if(!ModuleRuns(4)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars PressureS = series(0,ARIMA_MaxAdaptiveN);
vars RSIS = series(0,ARIMA_MaxAdaptiveN);
vars TrendS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var dip,dim;
if(M5_UseADXFilter)
if(adxApprox(H,L,C,0,M5_ADX_Period,&dip,&dim) < M5_ADX_Min) return;
var atrST = atrAt(H,L,C,0,M5_ATR_Period);
if(atrST <= 0) return;
var mid = (H[0]+L[0])/2.0;
var pressure = 50.0 + 20.0*(C[0]-mid)/fix0(M5_ATR_Mult*atrST);
pressure = clampv(pressure,1.,99.);
var r0 = rsiAt(C,0,M5_RSI_Period);
var emaT = emaAt(C,0,M5_TrendEMA);
var trendScore = 50.0 + 20.0*(C[0]-emaT)/fix0(atrST);
trendScore = clampv(trendScore,1.,99.);
PressureS[0] = pressure;
RSIS[0] = clampv(r0,1.,99.);
TrendS[0] = trendScore;
int POk = 0;
int ROk = 0;
int TOk = 0;
var pF = ARIMAForecastMeta("AP5_Pressure","pressure",PressureS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&POk);
var rF = ARIMAForecastMeta("AP5_Pressure","rsi",RSIS,ARIMA_N,0.01,ARIMA_MinOscDelta,&ROk);
var tF = ARIMAForecastMeta("AP5_Pressure","trend",TrendS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&TOk);
int buy = 0;
int sell = 0;
if(POk && ROk && TOk)
{
if(pF > 52. and tF > 52. and rF > M5_RSI_BuyLo
and ARIMAForecastUp(pF,pressure,ARIMA_MinTrendDelta)
and ARIMAForecastUp(rF,r0,ARIMA_MinOscDelta))
buy = 1;
if(pF < 48. and tF < 48. and rF < M5_RSI_SellHi
and ARIMAForecastDown(pF,pressure,ARIMA_MinTrendDelta)
and ARIMAForecastDown(rF,r0,ARIMA_MinOscDelta))
sell = 1;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
if(buy)
openTradeDir(1,"AP5_Pressure",M5_SL_Mult*af*atr,M5_TP_Mult*af*atr,M5_TrailMult,M5_TrailStart,M5_BE_Mult,C);
if(sell)
openTradeDir(-1,"AP5_Pressure",M5_SL_Mult*af*atr,M5_TP_Mult*af*atr,M5_TrailMult,M5_TrailStart,M5_BE_Mult,C);
}
void Module6_EMA_ADX()
{
if(!ModuleRuns(5)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars EmaS = series(0,ARIMA_MaxAdaptiveN);
vars TrendS = series(0,ARIMA_MaxAdaptiveN);
vars DiS = series(0,ARIMA_MaxAdaptiveN);
vars AdxS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var eF0 = emaAt(C,0,M6_EMA_Fast);
var eS0 = emaAt(C,0,M6_EMA_Slow);
var eT0 = emaAt(C,0,M6_EMA_Trend);
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
var dp,dm;
var adx0 = adxApprox(H,L,C,0,M6_ADX_Period,&dp,&dm);
var emaScore = 50.0 + 20.0*(eF0-eS0)/atr;
var trendScore = 50.0 + 20.0*(C[0]-eT0)/atr;
var diScore = 50.0 + (dp-dm);
emaScore = clampv(emaScore,1.,99.);
trendScore = clampv(trendScore,1.,99.);
diScore = clampv(diScore,1.,99.);
EmaS[0] = emaScore;
TrendS[0] = trendScore;
DiS[0] = diScore;
AdxS[0] = clampv(adx0,1.,99.);
int EOk = 0;
int TOk = 0;
int DOk = 0;
int AOk = 0;
var eF = ARIMAForecastMeta("AP6_DriftADX","ema",EmaS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&EOk);
var tF = ARIMAForecastMeta("AP6_DriftADX","trend",TrendS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&TOk);
var dF = ARIMAForecastMeta("AP6_DriftADX","di",DiS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&DOk);
var aF = ARIMAForecastMeta("AP6_DriftADX","adx",AdxS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&AOk);
int buy = 0;
int sell = 0;
if(EOk && TOk && DOk && AOk)
{
if(eF > 52. and tF > 52. and dF > 52. and aF > M6_ADX_Min
and ARIMAForecastUp(eF,emaScore,ARIMA_MinTrendDelta))
buy = 1;
if(eF < 48. and tF < 48. and dF < 48. and aF > M6_ADX_Min
and ARIMAForecastDown(eF,emaScore,ARIMA_MinTrendDelta))
sell = 1;
}
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP6_DriftADX",M6_SL_Mult*af*atr,M6_TP_Mult*af*atr,M6_TrailMult,M6_TrailStart,M6_BE_Mult,C);
if(sell) openTradeDir(-1,"AP6_DriftADX",M6_SL_Mult*af*atr,M6_TP_Mult*af*atr,M6_TrailMult,M6_TrailStart,M6_BE_Mult,C);
}
void Module7_Donchian()
{
if(!ModuleRuns(6)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars PosS = series(0,ARIMA_MaxAdaptiveN);
vars TrendS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var dp,dm;
if(M7_UseADXFilter)
if(adxApprox(H,L,C,0,M7_ADX_Period,&dp,&dm) < M7_ADX_Min) return;
var dHi = highestS(H,1,M7_Donch_Period);
var dLo = lowestS(L,1,M7_Donch_Period);
var width = dHi-dLo;
if(width <= 0) return;
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
var pos = 100.0*(C[0]-dLo)/width;
pos = clampv(pos,1.,99.);
var eT0 = emaAt(C,0,M7_TrendEMA);
var trendScore = 50.0 + 20.0*(C[0]-eT0)/atr;
trendScore = clampv(trendScore,1.,99.);
PosS[0] = pos;
TrendS[0] = trendScore;
int POk = 0;
int TOk = 0;
var pF = ARIMAForecastMeta("AP7_RangeFlow","pos",PosS,ARIMA_N,0.01,ARIMA_MinOscDelta,&POk);
var tF = ARIMAForecastMeta("AP7_RangeFlow","trend",TrendS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&TOk);
int buy = 0;
int sell = 0;
if(POk && TOk)
{
if(pF > 80. and tF > 52.
and ARIMAForecastUp(pF,pos,ARIMA_MinOscDelta))
buy = 1;
if(pF < 20. and tF < 48.
and ARIMAForecastDown(pF,pos,ARIMA_MinOscDelta))
sell = 1;
}
if(M7_MaxExtATR > 0 && atr > 0)
{
if(buy && (C[0]-dHi) > M7_MaxExtATR*atr) buy = 0;
if(sell && (dLo-C[0]) > M7_MaxExtATR*atr) sell = 0;
}
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP7_RangeFlow",M7_SL_Mult*af*atr,M7_TP_Mult*af*atr,M7_TrailMult,M7_TrailStart,M7_BE_Mult,C);
if(sell) openTradeDir(-1,"AP7_RangeFlow",M7_SL_Mult*af*atr,M7_TP_Mult*af*atr,M7_TrailMult,M7_TrailStart,M7_BE_Mult,C);
}
void Module8_MACD_EMA()
{
if(!ModuleRuns(7)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars HistS = series(0,ARIMA_MaxAdaptiveN);
vars TrendS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var dp,dm;
if(M8_UseADXFilter)
if(adxApprox(H,L,C,0,M8_ADX_Period,&dp,&dm) < M8_ADX_Min) return;
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
var macd0 = macdLineAt(C,0,M8_MACD_Fast,M8_MACD_Slow);
var sig0 = macdSignalAt(C,0,M8_MACD_Fast,M8_MACD_Slow,M8_MACD_Signal);
var hist = macd0-sig0;
var histScore = 50.0 + 50.0*hist/atr;
histScore = clampv(histScore,1.,99.);
var eT0 = emaAt(C,0,M8_TrendEMA);
var trendScore = 50.0 + 20.0*(C[0]-eT0)/atr;
trendScore = clampv(trendScore,1.,99.);
HistS[0] = histScore;
TrendS[0] = trendScore;
int HOk = 0;
int TOk = 0;
var hF = ARIMAForecastMeta("AP8_MacdFlow","hist",HistS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&HOk);
var tF = ARIMAForecastMeta("AP8_MacdFlow","trend",TrendS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&TOk);
int buy = 0;
int sell = 0;
if(HOk && TOk)
{
if(hF > 52. and tF > 52.
and ARIMAForecastUp(hF,histScore,ARIMA_MinTrendDelta))
buy = 1;
if(hF < 48. and tF < 48.
and ARIMAForecastDown(hF,histScore,ARIMA_MinTrendDelta))
sell = 1;
}
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP8_MacdFlow",M8_SL_Mult*af*atr,M8_TP_Mult*af*atr,M8_TrailMult,M8_TrailStart,M8_BE_Mult,C);
if(sell) openTradeDir(-1,"AP8_MacdFlow",M8_SL_Mult*af*atr,M8_TP_Mult*af*atr,M8_TrailMult,M8_TrailStart,M8_BE_Mult,C);
}
void Module9_RSI_MR()
{
if(!ModuleRuns(8)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars RSIS = series(0,ARIMA_MaxAdaptiveN);
var dp,dm;
if(M9_UseRangeFilter)
if(adxApprox(H,L,C,0,M9_ADX_Period,&dp,&dm) >= M9_ADX_RangeMax) return;
var r0 = rsiAt(C,0,M9_RSI_Period);
var r2 = rsiAt(C,2,M9_RSI_Period);
RSIS[0] = clampv(r0,1.,99.);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
int ROk = 0;
var rF = ARIMAForecastMeta("AP9_RSIPath","rsi",RSIS,ARIMA_N,0.01,ARIMA_MinOscDelta,&ROk);
int buy = 0;
int sell = 0;
if(ROk)
{
if(r0 < 45. and ARIMAForecastUp(rF,r0,ARIMA_MinOscDelta))
buy = 1;
if(r0 > 55. and ARIMAForecastDown(rF,r0,ARIMA_MinOscDelta))
sell = 1;
}
if(M9_RequireSustain)
{
if(buy && r2 > 50.) buy = 0;
if(sell && r2 < 50.) sell = 0;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP9_RSIPath",M9_SL_Mult*af*atr,M9_TP_Mult*af*atr,M9_TrailMult,M9_TrailStart,M9_BE_Mult,C);
if(sell) openTradeDir(-1,"AP9_RSIPath",M9_SL_Mult*af*atr,M9_TP_Mult*af*atr,M9_TrailMult,M9_TrailStart,M9_BE_Mult,C);
}
void Module10_BB_Squeeze()
{
if(!ModuleRuns(9)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars WidthS = series(0,ARIMA_MaxAdaptiveN);
vars PosS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var dp,dm;
if(M10_UseADXFilter)
if(adxApprox(H,L,C,0,M10_ADX_Period,&dp,&dm) < M10_ADX_Min) return;
var m0,u0,l0;
bbAt(C,M10_BB_Period,M10_BB_Dev,0,&m0,&u0,&l0);
var range = u0-l0;
if(range <= 0) return;
var avgW = 0;
int i;
for(i=1;i<21;i++)
{
var mi,ui,li;
bbAt(C,M10_BB_Period,M10_BB_Dev,i,&mi,&ui,&li);
avgW += (ui-li)/fix0(mi);
}
avgW /= 20.0;
var widthNow = range/fix0(m0);
if(widthNow <= 0) widthNow = 0.0001;
var bandPos = 100.0*(C[0]-l0)/range;
bandPos = clampv(bandPos,1.,99.);
WidthS[0] = widthNow;
PosS[0] = bandPos;
int WOk = 0;
int POk = 0;
var wF = ARIMAForecastMeta("AP10_BandEnergy","width",WidthS,ARIMA_N,0.0001,ARIMA_MinWidthDelta,&WOk);
var pF = ARIMAForecastMeta("AP10_BandEnergy","pos",PosS,ARIMA_N,0.01,ARIMA_MinOscDelta,&POk);
int buy = 0;
int sell = 0;
if(WOk && POk)
{
if(widthNow < avgW*1.05 and wF > widthNow + ARIMA_MinWidthDelta
and pF > 62. and ARIMAForecastUp(pF,bandPos,ARIMA_MinOscDelta))
buy = 1;
if(widthNow < avgW*1.05 and wF > widthNow + ARIMA_MinWidthDelta
and pF < 38. and ARIMAForecastDown(pF,bandPos,ARIMA_MinOscDelta))
sell = 1;
}
if(M10_UseTrendAlign)
{
var e = emaAt(C,0,M10_TrendEMA);
if(C[0] <= e) buy = 0;
if(C[0] >= e) sell = 0;
}
var atr = atrAt(H,L,C,0,ATR_Period);
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP10_BandEnergy",M10_SL_Mult*af*atr,M10_TP_Mult*af*atr,M10_TrailMult,M10_TrailStart,M10_BE_Mult,C);
if(sell) openTradeDir(-1,"AP10_BandEnergy",M10_SL_Mult*af*atr,M10_TP_Mult*af*atr,M10_TrailMult,M10_TrailStart,M10_BE_Mult,C);
}
void Module11_Grey()
{
if(!ModuleRuns(10)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars O = series(priceOpen());
vars H = series(priceHigh());
vars L = series(priceLow());
vars GreyS = series(0,ARIMA_MaxAdaptiveN);
vars SlopeS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
var g0 = greyMA(O,0,M11_Period);
var g1 = greyMA(O,1,M11_Period);
var greyScore = 50.0 + 20.0*(g0-O[0])/atr;
var greySlope = 50.0 + 20.0*(g0-g1)/atr;
greyScore = clampv(greyScore,1.,99.);
greySlope = clampv(greySlope,1.,99.);
GreyS[0] = greyScore;
SlopeS[0] = greySlope;
int GOk = 0;
int SOk = 0;
var gF = ARIMAForecastMeta("AP11_GreyPath","grey",GreyS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&GOk);
var sF = ARIMAForecastMeta("AP11_GreyPath","slope",SlopeS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&SOk);
int buy = 0;
int sell = 0;
if(GOk && SOk)
{
if(gF > 52. and sF > 52.
and ARIMAForecastUp(gF,greyScore,ARIMA_MinTrendDelta))
buy = 1;
if(gF < 48. and sF < 48.
and ARIMAForecastDown(gF,greyScore,ARIMA_MinTrendDelta))
sell = 1;
}
if(M11_UseTrendFilter)
{
var e = emaAt(C,0,M11_TrendEMA);
if(O[0] <= e) buy = 0;
if(O[0] >= e) sell = 0;
}
var af = adaptFactor(H,L,C);
if(buy) openTradeDir(1,"AP11_GreyPath",M11_SL_Mult*af*atr,M11_TP_Mult*af*atr,M11_TrailMult,M11_TrailStart,M11_BE_Mult,C);
if(sell) openTradeDir(-1,"AP11_GreyPath",M11_SL_Mult*af*atr,M11_TP_Mult*af*atr,M11_TrailMult,M11_TrailStart,M11_BE_Mult,C);
}
void Module12_Flag()
{
if(!ModuleRuns(11)) return;
TimeFrame = TF_H4;
vars C = series(priceClose());
vars H = series(priceHigh());
vars L = series(priceLow());
vars PoleS = series(0,ARIMA_MaxAdaptiveN);
vars BreakS = series(0,ARIMA_MaxAdaptiveN);
if(!IsModuleBar(TF_H4)) return;
if(!SessionOK(TF_H4)) return;
if(!trendQualityOK(H,L,C,-1)) return;
var atr = atrAt(H,L,C,0,ATR_Period);
if(atr <= 0) return;
int fB = M12_FlagBars;
int pB = M12_PoleBars;
int pNew = fB+1;
int pOld = fB+pB;
var poleMove = C[pNew]-C[pOld];
var poleHigh = H[pNew];
var poleLow = L[pNew];
int k;
for(k=pNew;k<=pOld;k++)
{
if(H[k] > poleHigh) poleHigh = H[k];
if(L[k] < poleLow) poleLow = L[k];
}
var poleHeight = poleHigh-poleLow;
if(poleHeight <= 0) return;
var flagHigh = H[1];
var flagLow = L[1];
for(k=1;k<=fB;k++)
{
if(H[k] > flagHigh) flagHigh = H[k];
if(L[k] < flagLow) flagLow = L[k];
}
if((flagHigh-flagLow) > M12_FlagMaxATR*atr) return;
var flagMid = (flagHigh+flagLow)/2.0;
var poleScore = 50.0 + 10.0*poleMove/atr;
var breakScore = 50.0 + 20.0*(C[0]-flagMid)/atr;
poleScore = clampv(poleScore,1.,99.);
breakScore = clampv(breakScore,1.,99.);
PoleS[0] = poleScore;
BreakS[0] = breakScore;
int POk = 0;
int BOk = 0;
var pF = ARIMAForecastMeta("AP12_ShapePath","pole",PoleS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&POk);
var bF = ARIMAForecastMeta("AP12_ShapePath","break",BreakS,ARIMA_N,0.01,ARIMA_MinTrendDelta,&BOk);
int buy = 0;
int sell = 0;
if(POk && BOk)
{
if(pF > 55. and bF > 55.
and ARIMAForecastUp(bF,breakScore,ARIMA_MinTrendDelta))
buy = 1;
if(pF < 45. and bF < 45.
and ARIMAForecastDown(bF,breakScore,ARIMA_MinTrendDelta))
sell = 1;
}
if(M12_UseTrendFilter)
{
var ma = smaAt(C,0,M12_MA_Period);
if(C[0] <= ma) buy = 0;
if(C[0] >= ma) sell = 0;
}
var af = adaptFactor(H,L,C);
var slDist = poleHeight*M12_SL_PoleMult*af;
var tpDist = poleHeight*M12_TP_PoleMult*af;
if(buy) openTradeDir(1,"AP12_ShapePath",slDist,tpDist,M12_TrailMult,M12_TrailStart,M12_BE_Mult,C);
if(sell) openTradeDir(-1,"AP12_ShapePath",slDist,tpDist,M12_TrailMult,M12_TrailStart,M12_BE_Mult,C);
}
// -----------------------------------------------------------------------------
// End-of-test CSV style log
// -----------------------------------------------------------------------------
void logClosedTrades()
{
if(!is(EXITRUN)) return;
file_delete("Log\\MultiStrategy_Trades_Zorro.csv");
file_append("Log\\MultiStrategy_Trades_Zorro.csv",
"asset,algo,profit\n",0);
for(closed_trades)
{
file_append("Log\\MultiStrategy_Trades_Zorro.csv",
strf("%s,%s,%.2f\n",Asset,Algo,(var)TradeProfit),0);
}
}
// -----------------------------------------------------------------------------
// Main strategy
// -----------------------------------------------------------------------------
function run()
{
set(PARAMETERS|OFF);
BarPeriod = 30;
LookBack = 2000;
Capital = FixedRiskBalance;
Hedge = 2; // allow independent long/short components in backtest
Fill = 3; // more realistic order filling; adjust to your broker/data
Slippage = 0;
Spread = Spread; // keep asset-list spread
if(is(INITRUN))
{
printf("\nArimaIndicatorMatrix v03 feedback started.");
printf("\nIndicator forecasts use feedback-adaptive AutoAri parameters from prior prediction success.");
ResetMetaState();
if(UseARIMAMetaLog)
{
file_delete("Log\\ArimaIndicatorMeta.csv");
file_append("Log\\ArimaIndicatorMeta.csv",
"asset,bar,module,field,value,forecast,delta,rate20,meta_rel,raw_ok,meta_ok,use_n,use_p,use_q,delta_mult,err_norm,param_quality\n",0);
}
}
int i;
for(i=0;i<NUM_SYMBOLS;i++)
{
if(!SymbolEnabled(i))
continue;
if(!asset(SymbolName(i)))
continue;
// Run all converted modules. ModuleRuns() applies the v8.11 instrument gating.
Module1_BB_Stoch();
Module2_BB_RSI();
Module3_Keltner_Stoch();
Module4_Ichimoku_Stoch();
Module5_Supertrend_RSI();
Module6_EMA_ADX();
Module7_Donchian();
Module8_MACD_EMA();
Module9_RSI_MR();
Module10_BB_Squeeze();
Module11_Grey();
Module12_Flag();
TimeFrame = 1;
}
if(is(EXITRUN))
FreeARIMA();
logClosedTrades();
}