Swing Trading Safely with Super Trend Signal v1
stableDescription
Hey!
Pleasure to present to you the first version of my palindromic script I called: Swing Trading Safely with Super Trend Signal (STSwSTS)
This script is a simple improvement of the MassEve script by our King pshai and is quite relevant in this bull market.
Thanks mate, you're the best :)
It uses the required command:
CC_SuperTrendExt
The script uses two supertrends, one closer to the price (the TP ST) and one further (the main ST).
The script enters a long if both ST are below the price and when the price dips a bit on LTF.
Then it takes a safety TP once the price pumped a bit.
The long is kept until the TP ST flips, at which point the script takes some profit.
When the main ST flips bearish it exits the long.
A SL is included when a candle closes below some price defined relatve to the entry though it may not be useful on HTF because of the ST flip safety.
This script is mainly designed for HTF, though it may work on LTF for some pairs.
Many parameters to adjust to your needs!
You may experience some issues in Equity mode. The maximum nb of contracts which can be longed is not accurate in HBS, you may divide your equities by 4 in order to make it work fine.
Let me know if you run into some issues!
v2, v3 and v4 are planned and I may publish them in due time.
Short version for bear market is straightforward, spot version also, I may publish them later.
Safe trading!
~deemzie
HaasScript
-- Swing Trading Safely with Super Trend Signal (STSwSTS)
-- Author: deemzie
-- Thanks to pshai for the MassEve script which inspired the present and for the SuperTrend command
-- Consider donating to support our work!
-- deemzie: ETH/BSC: 0xFcFD51f3eD7BCcb3652631E7118C2c5913A3aa14
-- phsai BTC: 3FRx1EkG4T4izrkaS34xeZHJFK4kQefHKf
HideTradeAmountSettings()
local src_types = {
'Close',
'Open',
'HL',
'HLC',
'OHLC'
}
InputGroupHeader('Timeframe Settings')
local tf_update = InputInterval('1. Update Timeframe', 60, 'Update timeframe, how frequently does the bot logic update.')
local tf_price = InputInterval('2. Prices Timeframe', 240, 'Prices timeframe to use.')
InputGroupHeader('Position Settings')
local type = InputOptions('1. Position order type', 'Amount', {'Amount', 'Equity'}, 'Initial position defined either by the number of contract or a percentage of the wallet balance.')
local amount = Input('2. Position amount', 100, 'Trade amount to use')
local prop = Input('3. Equity', 20, 'Equity of the available wallet balance to use')
InputGroupHeader('Entry and Exit Settings')
local ent_trlg = Input('1. Entry Trailing %', 1, 'Price move down before going Long after the SuperTrend Buy signal')
local sec_tp = Input('2. Safety TP price %', 5, 'Price move up after going Long to secure profit')
local sec_tp_prct = Input('3. Safety TP amount %', 50, 'Portion of the Long to close when the Safety TP is reached')
local tp_prct = Input('4. Partial TP amount %', 15, 'Portion of the Long to close after the SuperTrend TP Sell signal')
local sl = Input('5. Stop Loss %', 20, 'Maximum price movement from entry before triggering the Stop Loss')
local sl_lim = Input('6. Stop Loss limit %', 0.2, 'Limit order below the trigger for the Stop Loss')
local sl_type = InputOptions('7. Stop Loss type', 'Fixed Market', {'Fixed Market', 'Fixed Limit', 'Close'}, 'Fixed: SL triggered if the price drops below trigger, Close: if the candle closes below')
InputGroupHeader('SuperTrend Settings')
local st_atr_len = Input('1. ATR Length Open', 10, 'SuperTrend ATR period lenth.')
local st_atr_mul = Input('2. ATR Mult Open', 3, 'SuperTrend ATR multiplier.')
local st_atr_len_tp = Input('1. ATR Length TP', 10, 'SuperTrend ATR period lenth.')
local st_atr_mul_tp = Input('2. ATR Mult TP', 2, 'SuperTrend ATR multiplier.')
local st_src_type = InputOptions('3. Price Source Type', src_types[4], src_types, 'Price source used for SuperTrend.')
local st_use_smooth = Input('4. Use Smoothing', false, 'Whether or not use MA smoothing on SuperTrend price source.')
local st_smooth_type = InputMaTypes('5. Smooth Type', SmaType, 'MA type for smoothing, if enabled.')
local st_smooth_len = Input('6. Smooth Length', 10, 'MA length for smoothing, if enabled.')
if type == 'Equity' then
amount = MaxLongAmount(AccountGuid()) * prop / 100
end
function init_id (name)
local id = Load(name)
if id == nil then
id = NewGuid()
end
return id
end
-- all trading logic etc happens inside this command's callback.
OptimizedForInterval(
tf_update, -- update interval
-- the callback function
function()
-- get candle prices
local o = OpenPrices(tf_price)
local h = HighPrices(tf_price)
local l = LowPrices(tf_price)
local c = ClosePrices(tf_price)
local op = OpenPrices(tf_update)
local hp = HighPrices(tf_update)
local lp = LowPrices(tf_update)
local cp = ClosePrices(tf_update)
-- get source prices
local st_src
local src
if st_src_type == src_types[1] then
st_src = c
src = cp
elseif st_src_type == src_types[2] then
st_src = o
src = op
elseif st_src_type == src_types[3] then
st_src = (h+l)/2
src = (hp+lp)/2
elseif st_src_type == src_types[4] then
st_src = (h+l+c)/3
src = (hp+lp+cp)/3
elseif st_src_type == src_types[5] then
st_src = (o+h+l+c)/4
src = (op+hp+lp+cp)/4
end
-- apply smoothing if used
if st_use_smooth then
st_src = MA(st_src, st_smooth_len, st_smooth_type)
end
-- super trend
local st = CC_SuperTrendExt(h, l, st_src, st_atr_len, st_atr_mul)
local st_tp = CC_SuperTrendExt(h, l, st_src, st_atr_len_tp, st_atr_mul_tp)
Plot(0, 'st', st)
Plot(0, 'st tp', st_tp)
-- go long orders
local enter_id = init_id('enter_id')
local enter = OrderContainer(enter_id)
-- exit long orders
local sec_id = init_id('sec_id')
local sec = OrderContainer(sec_id)
local tp_id = init_id('tp_id')
local tp = OrderContainer(tp_id)
local stop_id = init_id('stop_id')
local stop = OrderContainer(stop_id)
-- position
local long_id = init_id('long_id')
local long = PositionContainer(long_id)
local entry = GetPositionEnterPrice(long_id)
local pos_amount = GetPositionAmount(long_id)
-- entry logic
if st_src > st_tp and st_src > st and not long.isLong and not stop.isFilled then
if (enter.isOpen and enter.price < lp * (1 - ent_trlg / 100)) or not enter.isOpen then
CancelAllOrders(long_id)
long_id = NewGuid()
enter_id = PlaceGoLongOrder(lp * (1 - ent_trlg / 100), amount, {timeout = 999999, positionId = long_id})
sec_id = NewGuid()
tp_id = NewGuid()
stop_id = NewGuid()
end
end
-- SL logic
if sl_type == 'Fixed Market' then
if long.isLong and not stop.isOpen and not stop.isFilled then
stop_id = PlaceExitLongOrder(entry * (1 - sl / 100), pos_amount, {triggerPrice = entry * (1 - sl / 100), type = StopMarketOrderType, timeout = 999999, positionId = long_id})
end
if long.isLong and stop.isOpen and not stop.isFilled and stop.executedAmount != pos_amount then
CancelOrder(stop_id)
stop_id = PlaceExitLongOrder(entry * (1 - sl / 100), pos_amount, {triggerPrice = entry * (1 - sl / 100), type = StopMarketOrderType, timeout = 999999, positionId = long_id})
end
elseif sl_type == 'Fixed Limit' then
if long.isLong and not stop.isOpen and not stop.isFilled then
stop_id = PlaceExitLongOrder(entry * (1 - sl / 100) * (1 - sl_lim / 100), pos_amount, {triggerPrice = entry * (1 - sl / 100), type = StopLimitOrderType, timeout = 999999, positionId = long_id})
end
if long.isLong and stop.isOpen and not stop.isFilled and stop.executedAmount != pos_amount then
CancelOrder(stop_id)
stop_id = PlaceExitLongOrder(entry * (1 - sl / 100) * (1 - sl_lim / 100), pos_amount, {triggerPrice = entry * (1 - sl / 100), type = StopLimitOrderType, timeout = 999999, positionId = long_id})
end
else
if long.isLong and c < entry * (1 - sl / 100) then
CancelAllOrders(long_id)
stop_id = PlaceExitPositionOrder(long_id, {type = MarketOrderType, timeout = 999999})
long_id = NewGuid()
long = PositionContainer(long_id)
Log('Stop!')
end
end
-- Exit logic
if long.isLong and st_src < st then
CancelAllOrders(long_id)
PlaceExitPositionOrder(long_id, {type = MarketOrderType, timeout = 999999})
long_id = NewGuid()
long = PositionContainer(long_id)
Log('Exit!')
end
-- Secure TP logic
if long.isLong and not sec.isOpen and not sec.isFilled and not stop.isFilled then
sec_id = PlaceExitLongOrder(entry * (1 + sec_tp / 100), pos_amount * sec_tp_prct / 100, {timeout = 999999, positionId = long_id})
end
-- TP logic
if long.isLong and st_src < st_tp and not tp.isOpen and not tp.isFilled and not stop.isFilled then
tp_id = PlaceExitLongOrder(hp, pos_amount * tp_prct / 100, {timeout = 999999, positionId = long_id})
end
-- reset TP
if long.isLong and st_src > st_tp and tp.isFilled then
tp_id = NewGuid()
end
-- reset SL: if SL has been triggered, wait for ST to flip bullish again
if stop.isFilled then
CancelAllOrders(long_id)
long_id = NewGuid()
end
if st_src < st and stop.isFilled then
stop_id = NewGuid()
end
Save('long_id', long_id)
Save('enter_id', enter_id)
Save('sec_id', sec_id)
Save('tp_id', tp_id)
Save('stop_id', stop_id)
end
)
15 Comments
Sign in to leave a comment.
Hmm I am getting this warning in the log
WARNING: IsOrderFilled(): orderId can not be empty
And it looks like it cant close its position, so did I make a mistake or is there something else I missed?
I am running it in equity mode (5%), would that be the problem?
Fixed. Try the new script, it should work properly now.
thanks, nice work. Will set up tests and give feedback when I have some interesting data
I am interested in the spot version of this script. Could you possibly publish that?
Yes! The spot version is planned... I am a bit busy rn, I will publish it by this weekend
Nice script and amazing backtesting performance on the BTC / USDT pair in futures trading ... 1,123.97% ... in 4 Weeks ... !!! Will give it a try the next two weeks! Thanks for sharing!
With which settings and which pairs do you have good success with your bot?
I updated the script, there was an issue with the stop loss and the take profits. Make sure you have the new one or the bot may take a short after exiting the long...
This bots works well with essentially any pair that displays regular patterns of the type: pump -> dump -> fairly flat accumulation -> pump...
It catches the pump and exits when it starts to dump to enter again lower.
Works great on like BTC, DOT, BNB, THETA...
It may work less on like RUNE, SUSHI or SNX which have more volatile PA, thought some settings may be found to work ok.
Update 1h - Prices 4h is the most reliable setting imo. It may work with 1h prices but you may want to set the ATH Length to 3 and 4.
It depends on the pair but you may want to set an entry trailling to like 4-5% for volatile pairs, while 1% may be good for BTC or idk
For alts, a sec TP may be set to as much as 6-10% because of increased volatility, while you may want it lower for majors 4-5%
Safety TP also depends on volatility, 40-50% may be used for alts and maybe 20-30% for less volatile pairs. This needs to be adjusted depending on the nb of bots you run at the same time on your account. Idem for partial TP, 10-20% is fine in general.
Feel free to do some BT and share your results and the settings you chose. I have few time do try it myself rn as I am working on v2 and other stuff...
Script updated to allow for a Fixed Stop Loss.
Just been doing backtesting and it doesn't look like there is liquidation detection built-in? is that correct?
Hello I´m new here but the script give this error:
4. 04 Nov 2021 20:06:34 ERROR: Unknown references: CC_SuperTrendExt3. 04 Nov 2021 20:06:34 ERROR: Unknown references: CC_SuperTrendExt2. 04 Nov 2021 20:06:34 This script is compatible with margin and leverage trading.1. 04 Nov 2021 20:06:34 Doing compile test..
I found the solutions, you must create a command script for SuperTrend Extended but save as CC_SuperTrendExt otherwise the principal scrip won´t find the command
Here is my errors:/ what am i doing wrong? Any idea?
Using the updated version of script and try to save it with both "CC_SuperTrendExt" and "SuperTrendExt" names as command script
455. 19 Jul 2022 12:19:00 ERROR: OptimizedForInterval(): Execution error occurred.
454. 19 Jul 2022 12:19:00 ERROR: Index out of range exception.
453. 19 Jul 2022 12:19:00 ERROR: Plot(): Attempting to call with 'null' value for value.
452. 19 Jul 2022 12:19:00 ERROR: CC_SuperTrendExt(): Invalid input count of 5 (requires 6 inputs).
451. 19 Jul 2022 12:19:00 ERROR: CC_SuperTrendExt(): Invalid input count of 5 (requires 6 inputs)
Solved. Thank you @Tilanthi (Discord) for your guide
Depending on which version of SuperTrendExt you are using, try adding the ClosePrices() into the supertrend call in your main script as the third callable parameter, which gives you the six inputs that it is looking for - so for example
local c = ClosePrices(tf_price)
local st = CC_SuperTrendExt(h, l, c, st_src, st_atr_len, st_atr_mul)
and hopefully it should work for you - it did when I just tried it !
Great trading bot scrpt!
Hi
Share please Swing Trading Safely with Super Trend Signal v1 exmaple where I need to put it ?
Becase I have the same error
I fixed this error - ERROR: CC_SuperTrendExt(): Invalid input count of 5 (requires 6 inputs).
But now I'm experiencing another error:
ERROR: Unknown references:
ERROR: - st_tp