Lorentzian Classification Strategy by StrategiesForEveryone Modded
Lorentzian Classification Strategy by StrategiesForEveryone Modded
0 at
https://mozilla.org/MPL/2.0/
//
// Please, visit the main script that strategy is based in :) Machine Learning:
Lorentzian Classification/<<<< ==============================================
// Indicator developed by ©jdehorty
// Strategy devoleped by ©StrategiesForEVeryone
// @version=5
strategy('Lorentzian Classification Strategy by StrategiesForEveryone modded by
LUPEN', precision=2, initial_capital = 100000, process_orders_on_close = true,
calc_on_every_tick = true, commission_value = 0.03)
import jdehorty/MLExtensions/2 as ml
import jdehorty/KernelFunctions/2 as kernels
// ======================
// ==== Custom Types ====
// ======================
// This section uses PineScript's new Type syntax to define important data
structures
// used throughout the script.
type Settings
float source
int neighborsCount
int maxBarsBack
int featureCount
int colorCompression
bool showExits
bool useDynamicExits
type Label
int long
int short
int neutral
type FeatureArrays
array<float> f1
array<float> f2
array<float> f3
array<float> f4
array<float> f5
type FeatureSeries
float f1
float f2
float f3
float f4
float f5
type MLModel
int firstBarIndex
array<int> trainingLabels
int loopSize
float lastDistance
array<float> distancesArray
array<int> predictionsArray
int prediction
type FilterSettings
bool useVolatilityFilter
bool useRegimeFilter
bool useAdxFilter
float regimeThreshold
int adxThreshold
type Filter
bool volatility
bool regime
bool adx
// ==========================
// ==== Helper Functions ====
// ==========================
// ================
// ==== Inputs ====
// ================
// Label Object: Used for classifying historical data as training data for the ML
Model
Label direction_s =
Label.new(
long=1,
short=-1,
neutral=0
)
// EMA Settings
useEmaFilter = input.bool(title="Use EMA Filter", defval=false, group="Filters",
inline="ema")
emaPeriod = input.int(title="Period", defval=200, minval=1, step=1,
group="Filters", inline="ema", tooltip="The period of the EMA used for the EMA
Filter.")
isEmaUptrend = useEmaFilter ? close > ta.ema(close, emaPeriod) : true
isEmaDowntrend = useEmaFilter ? close < ta.ema(close, emaPeriod) : true
useSmaFilter = input.bool(title="Use SMA Filter", defval=false, group="Filters",
inline="sma")
smaPeriod = input.int(title="Period", defval=200, minval=1, step=1,
group="Filters", inline="sma", tooltip="The period of the SMA used for the SMA
Filter.")
isSmaUptrend = useSmaFilter ? close > ta.sma(close, smaPeriod) : true
isSmaDowntrend = useSmaFilter ? close < ta.sma(close, smaPeriod) : true
// Display Settings
showBarColors = input.bool(false, "Show Bar Colors", tooltip="Whether to show the
bar colors.", group="Display Settings")
showBarPredictions = input.bool(defval = false, title = "Show Bar Prediction
Values", tooltip = "Will show the ML model's evaluation of each bar as an
integer.", group="Display Settings")
useAtrOffset = input.bool(defval = false, title = "Use ATR Offset", tooltip = "Will
use the ATR offset instead of the bar prediction offset.", group="Display
Settings")
barPredictionsOffset = input.float(0, "Bar Prediction Offset", minval=0,
tooltip="The offset of the bar predictions as a percentage from the bar high or
close.", group="Display Settings")
// =================================
// ==== Next Bar Classification ====
// =================================
array.push(y_train_array, y_train_series)
// =========================
// ==== Core ML Logic ====
// =========================
lastDistance = -1.0
size = math.min(settings.maxBarsBack-1, array.size(y_train_array)-1)
sizeLoop = math.min(settings.maxBarsBack-1, size)
// ============================
// ==== Prediction Filters ====
// ============================
// User Defined Filters: Used for adjusting the frequency of the ML Model's
predictions
filter_all = filter.volatility and filter.regime and filter.adx
// ===========================
// ==== Entries and Exits ====
// ===========================
//
emaf = 0.0
emas = 0.0
val = 0.0
nval = 0.0
sig = 0.0
//
// Dynamic Exit Conditions: Booleans for ML Model Position Exits based on Fractal
Filters and Kernel Regression Filters
lastSignalWasBullish = ta.barssince(startLongTrade) < ta.barssince(startShortTrade)
lastSignalWasBearish = ta.barssince(startShortTrade) < ta.barssince(startLongTrade)
barsSinceRedEntry = ta.barssince(startShortTrade)
barsSinceRedExit = ta.barssince(alertBullish)
barsSinceGreenEntry = ta.barssince(startLongTrade)
barsSinceGreenExit = ta.barssince(alertBearish)
isValidShortExit = barsSinceRedExit > barsSinceRedEntry
isValidLongExit = barsSinceGreenExit > barsSinceGreenEntry
endLongTradeDynamic = (isBearishChange and isValidLongExit[1])
endShortTradeDynamic = (isBullishChange and isValidShortExit[1])
// Fixed Exit Conditions: Booleans for ML Model Position Exits based on a Bar-Count
Filters
endLongTradeStrict = ((isHeldFourBars and isLastSignalBuy) or
(isHeldLessThanFourBars and isNewSellSignal and isLastSignalBuy)) and
startLongTrade[4]
endShortTradeStrict = ((isHeldFourBars and isLastSignalSell) or
(isHeldLessThanFourBars and isNewBuySignal and isLastSignalSell)) and
startShortTrade[4]
isDynamicExitValid = not useEmaFilter and not useSmaFilter and not
useKernelSmoothing
endLongTrade = settings.useDynamicExits and isDynamicExitValid ?
endLongTradeDynamic : endLongTradeStrict
endShortTrade = settings.useDynamicExits and isDynamicExitValid ?
endShortTradeDynamic : endShortTradeStrict
// =========================
// ==== Plotting Labels ====
// =========================
// Note: These will not repaint once the most recent bar has fully closed. By
default, signals appear over the last closed bar; to override this behavior set
offset=0.
//plotshape(startLongTrade ? low : na, 'Buy', shape.labelup, location.belowbar,
color=ml.color_green(prediction), size=size.small, offset=0, display = display.all
- display.price_scale - display.status_line)
//plotshape(startShortTrade ? high : na, 'Sell', shape.labeldown,
location.abovebar, ml.color_red(-prediction), size=size.small, offset=0, display =
display.all - display.price_scale - display.status_line)
//plotshape(endLongTrade and settings.showExits ? high : na, 'StopBuy',
shape.xcross, location.absolute, color=#3AFF17, size=size.tiny, offset=0, display =
display.all - display.price_scale - display.status_line)
//plotshape(endShortTrade and settings.showExits ? low : na, 'StopSell',
shape.xcross, location.absolute, color=#FD1707, size=size.tiny, offset=0, display =
display.all - display.price_scale - display.status_line)
// ================
// ==== Alerts ====
// ================
// =========================
// ==== Display Signals ====
// =========================
//
===================================================================================
============================================================
// ------------ Super Trend ----------
atrPeriod = input(9, "ATR Length SuperTrend", group = "========= Super Trend filter
==========")
factor = input.float(2.5, "Factor SuperTrend", step = 0.05, group = "=========
Super Trend filter ==========")
[supertrend, direction_supertrend] = ta.supertrend(factor, atrPeriod)
show_supertrend = input.bool(defval = false, title="Show supertrend ?", group =
"============ Appearance ============")
bodyMiddle = plot(show_supertrend ? ((open + close) / 2) : na,
display=display.none)
upTrend = plot(show_supertrend and direction_supertrend < 0 ? supertrend : na, "Up
Trend", color = color.green, style=plot.style_linebr, display = display.all -
display.status_line)
downTrend = plot(show_supertrend and direction_supertrend > 0 ? supertrend : na,
"Down Trend", color = color.red, style=plot.style_linebr, display = display.all -
display.status_line)
fill(bodyMiddle, upTrend, color.new(color.green, 95), fillgaps=false, title =
"Supertrend background")
fill(bodyMiddle, downTrend, color.new(color.red, 95), fillgaps=false, title =
"Supertrend background")
up_trend_plot = direction_supertrend < 0
down_trend_plot = direction_supertrend > 0
//
===================================================================================
============================================================
// -------------- Atr stop loss by garethyeo (modified) -----------------
if add_money_frequency == "Monthly"
add_frequency := month
if add_money_frequency == "Weekly"
add_frequency := weekofyear
if add_money_frequency == "Daily"
add_frequency := dayofweek
if add_money_frequency == "Yearly"
add_frequency := year
add_money = input.string("No", title = "Add money from time to time ?", options =
["Yes","No"] , group = "=============== Adding money frequently ===============")
// We use this for being able to choose the frequency of withdrawing money:
if withdraw_money_frequency == "Monthly"
withdraw_frequency := month
if withdraw_money_frequency == "Weekly"
withdraw_frequency := weekofyear
if withdraw_money_frequency == "Daily"
withdraw_frequency := dayofweek
if withdraw_money_frequency == "Yearly"
withdraw_frequency := year
// Percentage of earnings:
if withdraw_frequency != withdraw_frequency[1] and withdraw_money == "Yes" and
amount_to_withdraw == "%" and date and strategy.netprofit>0
initial_capital_w -= strategy.netprofit * (percentage_of_earnings / 100)
initial_capital -= strategy.netprofit * (percentage_of_earnings / 100)
balance := strategy.netprofit + initial_capital
// Fixed amount:
if withdraw_frequency != withdraw_frequency[1] and withdraw_money == "Yes" and
amount_to_withdraw == "Fixed" and date and strategy.netprofit>0
initial_capital_w -= amount_for_withdraw
initial_capital -= amount_for_withdraw
balance := strategy.netprofit + initial_capital
// Logic
//
===================================================================================
============================================================
// ------------- Money management --------------
//
===================================================================================
============================================================
// ------------ Trade conditions ---------------
// Entry Conditions: Booleans for ML Model Position Entries
//startLongTrade = isNewBuySignal and isBullish and isEmaUptrend and isSmaUptrend
//startShortTrade = isNewSellSignal and isBearish and isEmaDowntrend and
isSmaDowntrend
//endLongTrade = settings.useDynamicExits and isDynamicExitValid ?
endLongTradeDynamic : endLongTradeStrict
//endShortTrade = settings.useDynamicExits and isDynamicExitValid ?
endShortTradeDynamic : endShortTradeStrict
//bullish := close > ema200
//bearish := close < ema200
bought = strategy.position_size > 0
sold = strategy.position_size < 0
buy = startLongTrade
sell = startShortTrade
var float total_commissions_value = 0
var float commission_value_l = 0
var float commission_value_s = 0
var float sl_long = na
var float sl_short = na
var float be_long = na
var float be_short = na
var float tp_long = na
var float tp_short = na
var int totaltrades = 0
if not bought
be_long:=na
sl_long:=na
tp_long:=na
if not sold
be_short:=na
sl_short:=na
tp_short:=na
long_positions = input.bool(defval = true, title = "Long positions ?", group =
"============ Positions management ============")
short_positions = input.bool(defval = true, title = "Short positions ?", group =
"============ Positions management ============")
use_takeprofit = input.bool(defval = true, title = "Use take profit ?", group =
"============ Risk management for trades ============")
use_breakeven = input.bool(defval = true, title = "Use break even ?", group =
"============ Risk management for trades ============")
close_only_tp = input.bool(defval = false, title = "Close just with take profit ?",
group = "============ Risk management for trades ============", tooltip = "Activate
if you just want to exit from a position until reaching take profit or stop loss.
If it´s activated, change % of closing by tp to 100%")
ema_filter_long = input.bool(defval = true, title = "Ema filter for long
positions ?", group = "============ Positions management ============", tooltip =
"Activate if you just want to long above 200 ema")
ema_filter_short = input.bool(defval = true, title = "Ema filter for short
positions ?", group = "============ Positions management ============", tooltip =
"Activate if you just want to short under 200 ema")
commission_percent = input.float(0.03, title = "Commission value in %", group =
"============ Positions management ============", tooltip = "Set the % of
commission. For example, when you enter into a position, you have a commission of
0.04% per entry and 0.04% per exit. You have also to change this value in
properties for getting a real return in backtest. (in this case, 0.04%)")
if fixed_amounts
commission_value_l := (close * (long_amount) * (commission_percent/100))
commission_value_s := (close * (short_amount) * (commission_percent/100))
if not fixed_amounts
commission_value_l := (close * ((strategy_contracts * (risk / 100)) /
distance_sl_long) * (commission_percent/100))
commission_value_s := (close * ((strategy_contracts * (risk / 100)) /
distance_sl_short) * (commission_percent/100))
// ======================= Strategy
===================================================================================
================================
if not bought and buy and date and long_positions and inSession(timeSession) and
use_takeprofit and not ema_filter_long
sl_long:=longStopLoss
long_stoploss_distance = close - longStopLoss
be_long := close + long_stoploss_distance * risk_reward_breakeven_long
tp_long:=close+(long_stoploss_distance*risk_reward_take_profit_long)
total_commissions_value += commission_value_l
strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
strategy.exit('Exit', 'L', stop=sl_long)
if bought and high > be_long and use_breakeven
sl_long := strategy.position_avg_price
strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
strategy.exit('Exit', 'L', stop=sl_long)
if bought and sell and strategy.openprofit>0 and not close_only_tp or bought and
closelong_supertrend and close_withsupertrend and strategy.openprofit>0 and not
close_only_tp
strategy.close("L", comment="CL")
balance := balance + strategy.openprofit
if not bought and buy and date and long_positions and inSession(timeSession) and
not ema_filter_long
sl_long:=longStopLoss
long_stoploss_distance = close - longStopLoss
be_long := close + long_stoploss_distance * risk_reward_breakeven_long
total_commissions_value += commission_value_l
strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
strategy.exit('Exit', 'L', stop=sl_long)
if bought and high > be_long and use_breakeven
sl_long := strategy.position_avg_price
strategy.exit('Exit', 'L', stop=sl_long)
if bought and sell and strategy.openprofit>0
strategy.close("L", comment="CL")
balance := balance + strategy.openprofit
if not sold and sell and date and short_positions and inSession(timeSession) and
use_takeprofit and not ema_filter_short
sl_short:=shortStopLoss
short_stoploss_distance=shortStopLoss - close
be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
tp_short:=((short_stoploss_distance*risk_reward_take_profit_short)-close)*-1
total_commissions_value += commission_value_s
strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
strategy.exit("Exit", "S", stop=sl_short)
if sold and low < be_short and use_breakeven
sl_short:=strategy.position_avg_price
strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
strategy.exit("Exit", "S", stop=sl_short)
if sold and buy and strategy.openprofit>0 and not close_only_tp or sold and
closeshort_supertrend and close_withsupertrend and strategy.openprofit>0 and not
close_only_tp
strategy.close("S", comment="CS")
balance := balance + strategy.openprofit
if not sold and sell and date and short_positions and inSession(timeSession) and
not ema_filter_short
sl_short:=shortStopLoss
short_stoploss_distance=shortStopLoss - close
be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
total_commissions_value += commission_value_s
strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
strategy.exit("Exit", "S", stop=sl_short)
if sold and low < be_short and use_breakeven
sl_short:=strategy.position_avg_price
strategy.exit("Exit", "S", stop=sl_short)
if sold and buy and strategy.openprofit>0
strategy.close("S", comment="CS")
balance := balance + strategy.openprofit
//
===================================================================================
============================================================
if not bought and buy and date and long_positions and inSession(timeSession) and
use_takeprofit and bullish and ema_filter_long
sl_long:=longStopLoss
long_stoploss_distance = close - longStopLoss
be_long := close + long_stoploss_distance * risk_reward_breakeven_long
tp_long:=close+(long_stoploss_distance*risk_reward_take_profit_long)
total_commissions_value += commission_value_l
strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
strategy.exit('Exit', 'L', stop=sl_long)
if bought and high > be_long and use_breakeven
sl_long := strategy.position_avg_price
strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
strategy.exit('Exit', 'L', stop=sl_long)
if bought and sell and strategy.openprofit>0 and not close_only_tp or bought and
closelong_supertrend and close_withsupertrend and strategy.openprofit>0 and not
close_only_tp
strategy.close("L", comment="CL")
balance := balance + strategy.openprofit
if not bought and buy and date and long_positions and inSession(timeSession) and
bullish and ema_filter_long
sl_long:=longStopLoss
long_stoploss_distance = close - longStopLoss
be_long := close + long_stoploss_distance * risk_reward_breakeven_long
total_commissions_value += commission_value_l
strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
strategy.exit('Exit', 'L', stop=sl_long)
if bought and high > be_long and use_breakeven
sl_long := strategy.position_avg_price
strategy.exit('Exit', 'L', stop=sl_long)
if bought and sell and strategy.openprofit>0
strategy.close("L", comment="CL")
balance := balance + strategy.openprofit
// Short positon with ema filter
if not sold and sell and date and short_positions and inSession(timeSession) and
bearish and ema_filter_short
sl_short:=shortStopLoss
short_stoploss_distance=shortStopLoss - close
be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
total_commissions_value += commission_value_s
strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
strategy.exit("Exit", "S", stop=sl_short)
if sold and low < be_short and use_breakeven
sl_short:=strategy.position_avg_price
strategy.exit("Exit", "S", stop=sl_short)
if sold and buy and strategy.openprofit>0
strategy.close("S", comment="CS")
balance := balance + strategy.openprofit
//
===================================================================================
============================================================
if high>tp_long
tp_long:=na
if low<tp_short
tp_short:=na
if high>be_long
be_long:=na
if low<be_short
be_short:=na
//
===================================================================================
============================================================
// --------------- Positions amount calculator -------------
//
===================================================================================
============================================================
// ===================== Drawing stats about add and withdraw money frequently and
others on chart ===================