# Indicator for TOS
#// @ Julien_Eche
#indicator('Machine Learning Signal Filter', '', true)
# Converted by Sam4Cok@Samer800 - 10/2024
input showBacktestLabel = yes;
input DisplaySignalCurves = no; # 'Display Signal Curves?')
input useSignalCalculations = yes; # 'Activate Signal Calculations?'
input useDataForSignal = yes; # 'Use Data for Signal Generation?'
input source = close; # 'Data Type'
input CycleWindow = 5; # 'Chrono Window (minimum 2)'
input NormalizationLockback = 100; # 'Temporal Normalization (range: 2 to 240)'
input NeuralPulseRate = 0.001; # (range: 0.0001 to 0.01)'
input CycleIterations = 1500; # (range: 50 to 2000)', minval=50)
input showTradingLines = yes;
input tradeAllSignals = no;
input lot_size = 0.1; #, 'Signal Lot Size',
input minimumIntradeHolding = 5;
input takeProfitMulti = 3.5;
input stopLossMulti = 2.5;
def na = Double.NaN;
def time = GetTime();
script stellarNormalize {
input dataStream = close;
input dimension = 100;
input minimum = 0;
input maximum = 100;
def highestValue = Highest(dataStream, dimension);
def lowestValue = Lowest(dataStream, dimension);
def diff = (highestValue - lowestValue);
def norm = (maximum - minimum) * (dataStream - lowestValue) / diff + minimum;
plot out = norm;
}
script cyberneticRegression {
input inputX = close;
input inputY = close;
input dimension = 5;
input learningRate = 0.001;
input iterations = 1500;
def hypothesis = 1 / (1 + Exp(-Sum(inputX * 0.0, dimension)));
def entropy = -1 / dimension * Sum(Sum(inputY * (Log(hypothesis) + 1 - inputY), dimension) * Log(1 - hypothesis), dimension);
def gradient = 1 / dimension * Sum(inputX * (hypothesis - inputY), dimension);
def weight = fold cycle = 1 to iterations with p do
p - (learningRate * gradient);
def forecast = 1 / (1 + (-Sum(inputX * weight, dimension)));
plot entro = entropy;
plot cast = forecast;
}
def syntheticStream = Log(AbsValue(Power(source, 2) - 1) + .5);
def baseInput = if useSignalCalculations then time else source;
def syntheticInput = if useSignalCalculations then source else syntheticStream;
#//**** Cybernetic Regression and Normalization ****
def entropy = cyberneticRegression(baseInput, syntheticInput, CycleWindow, NeuralPulseRate, CycleIterations).entro;
def forecast = cyberneticRegression(baseInput, syntheticInput, CycleWindow, NeuralPulseRate, CycleIterations).cast;
def hiBase = Highest(source, NormalizationLockback);
def loBase = Lowest(source, NormalizationLockback);
def normalizedEntropy = stellarNormalize(entropy, NormalizationLockback, loBase, hiBase);
def normalizedForecast = stellarNormalize(forecast, NormalizationLockback, loBase, hiBase);
#//**** Signal Processing ****
def filter = yes; # // Disable additional filters
def entroCrossUp = (normalizedEntropy < normalizedForecast) and (normalizedEntropy[1] >= normalizedForecast[1]);
def entroCrossDn = (normalizedEntropy > normalizedForecast) and (normalizedEntropy[1] <= normalizedForecast[1]);
def signalBeacon = if useDataForSignal then
if source < normalizedEntropy and filter then -1 else
if source > normalizedEntropy and filter then 1 else signalBeacon[1] else
if entroCrossDn and filter then -1 else
if entroCrossUp and filter then 1 else signalBeacon[1];
def changed = signalBeacon - signalBeacon[1];
#def timeTracker = if changed then 0 else timeTracker[1] + 1;
#//**** Plotting and Alerts ****
plot NormEnteropy = if DisplaySignalCurves then normalizedEntropy else na;
plot NormForecase = if DisplaySignalCurves then normalizedForecast else na;
NormEnteropy.SetDefaultColor(Color.CYAN);
NormForecase.SetDefaultColor(Color.DARK_ORANGE);
#//**** Trade Conditions ****
def inTradeLong; def inTradeShort;
def tradeUp = if tradeAllSignals then yes else !inTradeShort[1];
def tradeDn = if tradeAllSignals then yes else !inTradeLong[1];
def startLongTrade = tradeUp and !inTradeLong[1] and changed and signalBeacon == 1;
def startShortTrade = tradeDn and !inTradeShort[1] and changed and signalBeacon == -1;
#//**** Trade Calculations ****
def ohl3 = (open + high + low) / 3;
def tp = atr(Length = 200) * takeProfitMulti;
def sl = atr(Length = 200) * stopLossMulti;
def start_long_trade;
def cntLong; def ldiff; def wonLong; def long_trades; def slLong; def tpLong; def cntUp;
if startLongTrade {
cntUp = 0;
inTradeLong = yes;
cntLong = 0;
ldiff = 0;
wonLong = 0;
long_trades = 0;
start_long_trade = open[-1];
tpLong = open[-1] + tp;
slLong = open[-1] - sl;
} else if (if cntUp[1]>= minimumIntradeHolding then (high >= tpLong[1]) or (close <= slLong[1]) else no) {
cntUp = na;
inTradeLong = no;
cntLong = 1;
ldiff = ohl3 - start_long_trade[1];
wonLong = if ldiff > 0 then 1 else 0;
long_trades = ldiff * lot_size;
start_long_trade = na;
tpLong = na;
slLong = na;
} else {
cntUp = cntUp[1] + 1;
inTradeLong = inTradeLong[1];
cntLong = 0;
ldiff = ldiff[1];
wonLong = 0;
long_trades = 0;
start_long_trade = start_long_trade[1];
tpLong = tpLong[1];
slLong = slLong[1];
}
def start_short_trade;
def cntShort; def sdiff; def wonShort; def short_trades;def slShort; def tpShort; def cntDn;
if startShortTrade {
cntDn = 0;
inTradeShort = yes;
cntShort = 0;
sdiff = 0;
wonShort = 0;
short_trades = 0;
start_short_trade = open[-1];
tpShort = open[-1] - tp;
slShort = open[-1] + sl;
} else if (if cntDn[1]>=minimumIntradeHolding then (low <= tpShort[1]) or (close >= slShort[1]) else no) {
cntDn = na;
inTradeShort = no;
cntShort = 1;
sdiff = start_short_trade[1] - ohl3;
wonShort = if sdiff > 0 then 1 else 0;
short_trades = sdiff * lot_size;
start_short_trade = na;
tpShort = na;
slShort = na;
} else {
cntDn = cntDn[1] + 1;
inTradeShort = inTradeShort[1];
cntShort = 0;
sdiff = sdiff[1];
wonShort = 0;
short_trades = 0;
start_short_trade = start_short_trade[1];
tpShort = tpShort[1];
slShort = slShort[1];
}
plot endLong = if long_trades[-1] then if wonLong[-1] then tpLong else slLong else na;
plot entryL = if showTradingLines and start_long_trade then start_long_trade else na;
plot tpL = if showTradingLines and tpLong then tpLong else na;
plot slL = if showTradingLines and slLong then slLong else na;
plot endShort = if short_trades[-1] then if wonShort[-1] then tpShort else slShort else na;
plot entryS = if showTradingLines and start_short_trade then start_short_trade else na;
plot tpS = if showTradingLines and tpShort then tpShort else na;
plot slS = if showTradingLines and slShort then slShort else na;
endLong.SetPaintingStrategy(PaintingStrategy.SQUARES);
endShort.SetPaintingStrategy(PaintingStrategy.SQUARES);
endLong.AssignValueColor(if wonLong[-1] then Color.CYAN else Color.MAGENTA);
endShort.AssignValueColor(if wonShort[-1] then Color.CYAN else Color.MAGENTA);
entryL.SetDefaultColor(Color.GRAY);
entryS.SetDefaultColor(Color.GRAY);
tpL.SetDefaultColor(Color.GREEN);
slL.SetDefaultColor(Color.RED);
tpS.SetDefaultColor(Color.GREEN);
slS.SetDefaultColor(Color.RED);
AddCloud(tpL, entryL, Color.DARK_GREEN);
AddCloud(entryL, slL, Color.DARK_RED);
AddCloud(entryS, tpS, Color.DARK_GREEN);
AddCloud(slS, entryS, Color.DARK_RED);
AddChartBubble(startLongTrade, low, "B", Color.GREEN, no);
AddChartBubble(startShortTrade, high, "S", Color.RED);
# Backtest
def totTradesLong = TotalSum(if isNaN(long_trades) then 0 else long_trades);
def totTradesShort = TotalSum(if isNaN(short_trades) then 0 else short_trades);
def totWonLong = TotalSum(if isNaN(wonLong) then 0 else wonLong);
def totWonShort = TotalSum(if isNaN(wonShort) then 0 else wonShort);
def neuralReturn = totTradesLong + totTradesShort;
def tradeGalaxy = TotalSum(cntLong) + TotalSum(cntShort);
def victoryCount = totWonLong + totWonShort;
def defeatCount = if tradeGalaxy - victoryCount == 0 then 1 else tradeGalaxy - victoryCount;
def won = victoryCount / tradeGalaxy;
def wl = victoryCount / defeatCount;
AddLabel(showBacktestLabel, "Trades(" + tradeGalaxy + ")", Color.WHITE);
AddLabel(showBacktestLabel, "Return(" + AsDollars(neuralReturn) + ")", if neuralReturn>0 then Color.GREEN else Color.RED);
AddLabel(showBacktestLabel, "Win(" + AsPercent(won) + ")", if won>=0.5 then Color.GREEN else Color.RED);
AddLabel(showBacktestLabel, "Win/Los(" + AsPercent(wl) + ")", if wl>=1 then Color.GREEN else Color.RED);
#-- END of CODE