0% found this document useful (0 votes)
43 views12 pages

@version : Strategy

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views12 pages

@version : Strategy

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 12

// This work is licensed under a Attribution-NonCommercial-

ShareAlike 4.0 International (CC BY-NC-SA 4.0)


https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo

//@version=5
//indicator("Pegasus", "Pegasus",overlay = false, max_labels_count
= 500)
strategy("PEGASUS-STRATEGY", overlay = false,
process_orders_on_close = true)
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
length = input(10, 'ATR Length')

minMult = input.int(1, 'Factor Range', minval = 0, inline = 'factor')


maxMult = input.int(5, '', minval = 0, inline = 'factor')
step = input.float(.5, 'Step', minval = 0, step = 0.1)
//Trigger error
if minMult > maxMult
runtime.error('Minimum factor is greater than maximum factor
in the range')
perfAlpha = input.float(10, 'Performance Memory', minval = 2)
fromCluster = input.string('Best', 'From Cluster', options = ['Best',
'Average', 'Worst'])
//Optimization
maxIter = input.int(1000, 'Maximum Iteration Steps', minval = 0,
group = 'Optimization')
maxData = input.int(10000, 'Historical Bars Calculation', minval = 0,
group = 'Optimization')
//Style
bearCss = input(color.red, 'Trailing Stop', inline = 'ts', group =
'Style')
bullCss = input(color.teal, '', inline = 'ts', group = 'Style')
amaBearCss = input(color.new(color.red, 50), 'AMA', inline = 'ama',
group = 'Style')
amaBullCss = input(color.new(color.teal, 50), '', inline = 'ama',
group = 'Style')
showGradient = input(true, 'Candle Coloring', group = 'Style')
showSignals = input(true, 'Show Signals', group = 'Style')
//Dashboard
showDash = input(true, 'Show Dashboard', group = 'Dashboard')
dashLoc = input.string('Top Right', 'Location', options = ['Top
Right', 'Bottom Right', 'Bottom Left'], group = 'Dashboard')
textSize = input.string('Small', 'Size' , options = ['Tiny',
'Small', 'Normal'], group = 'Dashboard')
//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type supertrend
float upper = hl2
float lower = hl2
float output
float perf = 0
float factor
int trend = 0

type vector
array<float> out

//-----------------------------------------------------------------------------}
//Supertrend
//-----------------------------------------------------------------------------{
var holder = array.new<supertrend>(0)
var factors = array.new<float>(0)

//Populate supertrend type array


if barstate.isfirst
for i = 0 to int((maxMult - minMult) / step)
factors.push(minMult + i * step)
holder.push(supertrend.new())

atr = ta.atr(length)
//Compute Supertrend for multiple factors
k=0
for factor in factors
get_spt = holder.get(k)

up = hl2 + atr * factor


dn = hl2 - atr * factor

get_spt.trend := close > get_spt.upper ? 1 : close <


get_spt.lower ? 0 : get_spt.trend
get_spt.upper := close[1] < get_spt.upper ? math.min(up,
get_spt.upper) : up
get_spt.lower := close[1] > get_spt.lower ? math.max(dn,
get_spt.lower) : dn

diff = nz(math.sign(close[1] - get_spt.output))


get_spt.perf += 2/(perfAlpha+1) * (nz(close - close[1]) * diff -
get_spt.perf)
get_spt.output := get_spt.trend == 1 ? get_spt.lower :
get_spt.upper
get_spt.factor := factor
k += 1

//-----------------------------------------------------------------------------}
//K-means clustering
//-----------------------------------------------------------------------------{
factor_array = array.new<float>(0)
data = array.new<float>(0)

//Populate data arrays


if last_bar_index - bar_index <= maxData
for element in holder
data.push(element.perf)
factor_array.push(element.factor)

//Intitalize centroids using quartiles


centroids = array.new<float>(0)
centroids.push(data.percentile_linear_interpolation(25))
centroids.push(data.percentile_linear_interpolation(50))
centroids.push(data.percentile_linear_interpolation(75))

//Intialize clusters
var array<vector> factors_clusters = na
var array<vector> perfclusters = na

if last_bar_index - bar_index <= maxData


for _ = 0 to maxIter
factors_clusters :=
array.from(vector.new(array.new<float>(0)),
vector.new(array.new<float>(0)),
vector.new(array.new<float>(0)))
perfclusters := array.from(vector.new(array.new<float>(0)),
vector.new(array.new<float>(0)),
vector.new(array.new<float>(0)))

//Assign value to cluster


i=0
for value in data
dist = array.new<float>(0)
for centroid in centroids
dist.push(math.abs(value - centroid))

idx = dist.indexof(dist.min())
perfclusters.get(idx).out.push(value)
factors_clusters.get(idx).out.push(factor_array.get(i))
i += 1

//Update centroids
new_centroids = array.new<float>(0)
for cluster_ in perfclusters
new_centroids.push(cluster_.out.avg())

//Test if centroid changed


if new_centroids.get(0) == centroids.get(0) and
new_centroids.get(1) == centroids.get(1) and new_centroids.get(2)
== centroids.get(2)
break

centroids := new_centroids

//-----------------------------------------------------------------------------}
//Signals and trailing stop
//-----------------------------------------------------------------------------{
//Get associated supertrend
var float target_factor = na
var float perf_idx = na
var float perf_ama = na

var from = switch fromCluster


'Best' => 2
'Average' => 1
'Worst' => 0

//Performance index denominator


den = ta.ema(math.abs(close - close[1]), int(perfAlpha))

if not na(perfclusters)
//Get average factors within target cluster
target_factor := nz(factors_clusters.get(from).out.avg(),
target_factor)

//Get performance index of target cluster


perf_idx := math.max(nz(perfclusters.get(from).out.avg()), 0) /
den

//Get new supertrend


var upper = hl2
var lower = hl2
var os = 0
up = hl2 + atr * target_factor
dn = hl2 - atr * target_factor
upper := close[1] < upper ? math.min(up, upper) : up
lower := close[1] > lower ? math.max(dn, lower) : dn
os := close > upper ? 1 : close < lower ? 0 : os
ts = os ? lower : upper

//Get trailing stop adaptive MA


if na(ts[1]) and not na(ts)
perf_ama := ts
else
perf_ama += perf_idx * (ts - perf_ama)

//-----------------------------------------------------------------------------}
//Dashboard
//-----------------------------------------------------------------------------{
var table_position = dashLoc == 'Bottom Left' ? position.bottom_left
: dashLoc == 'Top Right' ? position.top_right : position.bottom_right
var table_size = textSize == 'Tiny' ? size.tiny : textSize == 'Small' ?
size.small : size.normal
var tb = table.new(table_position, 4, 4, bgcolor = #1e222d,
border_color = #373a46, border_width = 1, frame_color = #373a46,
frame_width = 1)

if showDash
if barstate.isfirst
tb.cell(0, 0, 'Cluster', text_color = color.white, text_size =
table_size)
tb.cell(0, 1, 'Best', text_color = color.white, text_size =
table_size)
tb.cell(0, 2, 'Average', text_color = color.white, text_size =
table_size)
tb.cell(0, 3, 'Worst', text_color = color.white, text_size =
table_size)

tb.cell(1, 0, 'Size', text_color = color.white, text_size =


table_size)
tb.cell(2, 0, 'Centroid Dispersion', text_color = color.white,
text_size = table_size)
tb.cell(3, 0, 'Factors', text_color = color.white, text_size =
table_size)

if barstate.islast
topN = perfclusters.get(2).out.size()
midN = perfclusters.get(1).out.size()
btmN = perfclusters.get(0).out.size()
//Size
tb.cell(1, 1, str.tostring(topN), text_color = color.white,
text_size = table_size)
tb.cell(1, 2, str.tostring(midN), text_color = color.white,
text_size = table_size)
tb.cell(1, 3, str.tostring(btmN), text_color = color.white,
text_size = table_size)

//Content
tb.cell(3, 1, str.tostring(factors_clusters.get(2).out),
text_color = color.white, text_size = table_size, text_halign =
text.align_left)
tb.cell(3, 2, str.tostring(factors_clusters.get(1).out),
text_color = color.white, text_size = table_size, text_halign =
text.align_left)
tb.cell(3, 3, str.tostring(factors_clusters.get(0).out),
text_color = color.white, text_size = table_size, text_halign =
text.align_left)

//Calculate dispersion around centroid


i=0
for cluster_ in perfclusters
disp = 0.
if cluster_.out.size() > 1
for value in cluster_.out
disp += math.abs(value - centroids.get(i))

disp /= switch i
0 => btmN
1 => midN
2 => topN

i += 1
tb.cell(2, 4 - i, str.tostring(disp, '#.####'), text_color =
color.white, text_size = table_size)

//-----------------------------------------------------------------------------}
//Plots
//-----------------------------------------------------------------------------{
css = os ? bullCss : bearCss
plot(ts, 'Trailing Stop', os != os[1] ? na : css, force_overlay = true)
plot(perf_ama, 'Trailing Stop AMA',ta.cross(close, perf_ama) ? na:
close > perf_ama ? amaBullCss : amaBearCss, force_overlay = true)
//Candle coloring
barcolor(showGradient ? color.from_gradient(perf_idx, 0, 1,
color.new(css, 80), css) : na)
//Signals
n = bar_index
if showSignals
if os > os[1]
label.new(n, ts, str.tostring(int(perf_idx * 10)), color =
bullCss, style = label.style_label_up, textcolor = color.white, size =
size.tiny, force_overlay = true)
if os < os[1]
label.new(n, ts, str.tostring(int(perf_idx * 10)), color =
bearCss, style = label.style_label_down, textcolor = color.white, size
= size.tiny,force_overlay = true)

////indicator
//indicator("AI supertrend_osc Clustering Oscillator [LuxAlgo]",
"LuxAlgo - AI supertrend_osc Clustering Oscillator")
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
length_osc = input(10, 'atr_osc length_osc')
minMult_osc = input.int(1, 'Factor Range Oscillator', minval = 0,
inline = 'factor osc')
maxMult_osc = input.int(5, '', minval = 0, inline = 'factor osc')
step_osc = input.float(.5, 'step_osc', minval = 0, step = 0.1)
smooth = input.float(1, minval = 1)
//Trigger error
if minMult_osc > maxMult_osc
runtime.error('Minimum factor is greater than maximum factor
in the range')
//Optimization
maxIter_osc = input.int(1000, 'Maximum Iteration step_oscs', minval
= 0, group = 'Optimization')
maxdata_osc_osc = input.int(10000, 'Historical Bars Calculation',
minval = 0, group = 'Optimization')
//Style
bullCss_osc = input(color.new(#5b9cf6, 50), 'Bullish', inline = 'bull',
group = 'Style')
strongbullCss_osc = input(color.new(#5b9cf6, 28), 'Strong', inline =
'bull', group = 'Style')
neutCss = input(#9598a1, 'Neutral', inline = 'neut', group = 'Style')
bearCss_osc = input(color.new(#f77c80, 50), 'Bearish', inline =
'bear', group = 'Style')
strongbearCss_osc = input(color.new(#f77c80, 28), 'Strong', inline =
'bear', group = 'Style')
//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type supertrend_osc
float upper = hl2
float lower = hl2
float output
int trend

type vector_osc
array<float> out

//-----------------------------------------------------------------------------}
//supertrend_osc
//-----------------------------------------------------------------------------{
var holder_osc = array.new<supertrend_osc>(0)
var factors_osc = array.new<float>(0)

//Populate supertrend_osc type array


if barstate.isfirst
for i = 0 to int((maxMult_osc - minMult_osc) / step_osc)
factors_osc.push(minMult_osc + i * step_osc)
holder_osc.push(supertrend_osc.new())

atr_osc = ta.atr(length_osc)

//Compute supertrend_osc for multiple factors_osc


k_osc = 0
for factor in factors_osc
get_spt = holder_osc.get(k_osc)

up = hl2 + atr_osc * factor


dn = hl2 - atr_osc * factor

get_spt.upper := close[1] < get_spt.upper ? math.min(up,


get_spt.upper) : up
get_spt.lower := close[1] > get_spt.lower ? math.max(dn,
get_spt.lower) : dn
get_spt.trend := close > get_spt.upper ? 1 : close <
get_spt.lower ? 0 : get_spt.trend
get_spt.output := get_spt.trend == 1 ? get_spt.lower :
get_spt.upper
k_osc += 1

//-----------------------------------------------------------------------------}
//k_osc-means clustering
//-----------------------------------------------------------------------------{
data_osc = array.new<float>(0)

//Populate data_osc arrays


if last_bar_index - bar_index <= maxdata_osc_osc
for element in holder_osc
data_osc.push(close - element.output)

//Intitalize centroids_osc using quartiles


centroids_osc = array.new<float>(0)
centroids_osc.push(data_osc.percentile_linear_interpolation(25))
centroids_osc.push(data_osc.percentile_linear_interpolation(50))
centroids_osc.push(data_osc.percentile_linear_interpolation(75))

//Intialize clusters
var array<vector_osc> clusters = na

if last_bar_index - bar_index <= maxdata_osc_osc


for _ = 0 to maxIter_osc
clusters :=
array.from(vector_osc.new(array.new<float>(0)),
vector_osc.new(array.new<float>(0)),
vector_osc.new(array.new<float>(0)))

//Assign value to cluster


for value in data_osc
dist = array.new<float>(0)
for centroid in centroids_osc
dist.push(math.abs(value - centroid))

idx = dist.indexof(dist.min())
if idx != -1
clusters.get(idx).out.push(value)

//Update centroids_osc
new_centroids_osc = array.new<float>(0)
for cluster_ in clusters
new_centroids_osc.push(cluster_.out.avg())

//Test if centroid changed


if new_centroids_osc.get(0) == centroids_osc.get(0) and
new_centroids_osc.get(1) == centroids_osc.get(1) and
new_centroids_osc.get(2) == centroids_osc.get(2)
break

centroids_osc := new_centroids_osc
//-----------------------------------------------------------------------------}
//Get centroids_osc
//-----------------------------------------------------------------------------{
//Get associated supertrend_osc
var float bull = 0
var float neut = 0
var float bear = 0
var den_osc = 0

if not na(clusters)
bull += 2/(smooth+1) * nz(centroids_osc.get(2) - bull)
neut += 2/(smooth+1) * nz(centroids_osc.get(1) - neut)
bear += 2/(smooth+1) * nz(centroids_osc.get(0) - bear)
den_osc += 1

//-----------------------------------------------------------------------------}
//Plots
//-----------------------------------------------------------------------------{
plot_bull = plot(math.max(bull, 0), color = na, editable = false)
plot_bull_ext = plot(math.max(bear, 0), 'Strong Bullish Oscillator',
bear > 0 ? strongbullCss_osc : na, style = plot.style_circles)

plot_bear = plot(math.min(bear, 0), color = na, editable = false)


plot_bear_ext = plot(math.min(bull, 0), 'Strong Bearish Oscillator',
bull < 0 ? strongbearCss_osc : na, style = plot.style_circles)

plot(neut, 'Consensus', neutCss)

fill(plot_bull, plot_bull_ext, bull, math.max(bear, 0), bullCss_osc,


color.new(chart.bg_color, 100))
fill(plot_bear_ext, plot_bear, math.min(bull, 0), bear,
color.new(chart.bg_color, 100), bearCss_osc)

hline(0, linestyle = hline.style_solid)

//
=========================================
============================

// if showSignals
// if os > os[1]
// label.new(n, ts, str.tostring(int(perf_idx * 10))
// , color = bullCss
// , style = label.style_label_up
// , textcolor = color.white
// , size = size.tiny)

// if os < os[1]
// label.new(n, ts, str.tostring(int(perf_idx * 10))
// , color = bearCss
// , style = label.style_label_down
// , textcolor = color.white
// , size = size.tiny)

plot_bearish_series = math.min(bear, 0)
plot_bullish_series = math.max(bull, 0)
ids = int(perf_idx * 10)

buy_signal = os > os[1] and ids >= 3 and plot_bullish_series != 0


and plot_bearish_series == 0
sell_signal = os < os[1] and ids >= 3 and plot_bearish_series != 0
and plot_bullish_series == 0

// Calculate SL and TP
buy_sl = low - (low * 0.01) // SL for buy is the low of the candle
minus 1% buffer
buy_tp = buy_sl + 5 * (high - buy_sl) // 1:5 Risk Reward

sell_sl = high + (high * 0.01) // SL for sell is the high of the candle
plus 1% buffer
sell_tp = sell_sl - 5 * (sell_sl - low) // 1:5 Risk Reward

// Alert JSON Messages for Telegram


//buy_message = '{"chat_id": "-4289184834", "text": "*🚨 BUY
SIGNAL ALERT 🚨*\n\n*Asset:* ' + syminfo.tickerid + '\n*Entry Price:*
`' + str.tostring(close, "#.####") + '`\n*Stop Loss:* `' +
str.tostring(buy_sl, "#.####") + '`\n*Take Profit:* `' +
str.tostring(buy_tp, "#.####") + '`\n*Condition:* Strong Buy",
"parse_mode": "MarkdownV2"}'
//sell_message = '{"chat_id": "-4289184834", "text": "*🚨 SELL
SIGNAL ALERT 🚨*\n\n*Asset:* ' + syminfo.tickerid + '\n*Entry Price:*
`' + str.tostring(close, "#.####") + '`\n*Stop Loss:* `' +
str.tostring(sell_sl, "#.####") + '`\n*Take Profit:* `' +
str.tostring(sell_tp, "#.####") + '`\n*Condition:* Strong Sell",
"parse_mode": "MarkdownV2"}'

// Plot Buy Label below the low of the candle


if buy_signal
label.new( x=n, y=ts, text="BUY",
style=label.style_label_down, color=color.green,
textcolor=color.white, force_overlay = true, size=size.small )
// Plot Sell Label above the high of the candle
if sell_signal
label.new( x=n, y=ts, text="SELL",
style=label.style_label_up, color=color.red,
textcolor=color.white,force_overlay = true, size=size.small )

if sell_signal
strategy.entry("SHORT", strategy.short)
if buy_signal
strategy.entry("LONG", strategy.long)

if strategy.position_size>0
strategy.exit("EXIT_LONG","LONG",stop= low, limit = high )
if strategy.position_size<0
strategy.exit("EXIT_SHORT","SHORT",stop= high, limit = low )

// Alert Conditions
alertcondition(buy_signal, title="BUY SIGNAL")
alertcondition(sell_signal, title="SELL SIGNAL")

You might also like