Strategy ATR TP/SL target doesn't stay 'locked' to my entry readings - pine-script-v5

I want a strategy to Take Profit/Stop Loss to be based on the ATR (plus multiplier). However, I want it to be whatever the readings were at the point of entry, not simply the last candle (which is what it seems to be doing). Weird thing is that I have other strategies that use this approach, and they seem fine, so I'm really stumped by what I'm doing wrong.
Any help would be much appreciated!
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dave-browning
//#version=5
strategy("Dead-Cat Bounce", overlay = true, initial_capital = 1000, default_qty_value = 100, default_qty_type = strategy.percent_of_equity, currency = currency.GBP, commission_value = 0.05, use_bar_magnifier = true)
trendEMAlength = input.int(130, "Trend EMA Length")
fastSMALength = input.int(14, "Fast SMA Length")
tpATRmultiplyer = input.float(6.2, "Short TP ATR Multiplier")
slATRmultiplier = input.float(4, "Short SL ATR Multiplier")
//Trade Conditions
shortCondition = close > ta.sma(close, fastSMALength) and close < ta.ema(close, length=trendEMAlength)
notInTrade = strategy.position_size <= 0
atr = ta.atr(14)
ema=ta.ema(close, trendEMAlength)
plot(ta.sma(close,length=fastSMALength), color=color.blue, linewidth = 2)
plot(ta.ema(close, length=trendEMAlength), color=color.yellow, linewidth = 4)
plot(low - (atr * tpATRmultiplyer), color=color.green)
plot(high + (atr * slATRmultiplier), color=color.red)
if shortCondition and notInTrade
stopLoss = (high + (atr * slATRmultiplier))
takeProfit = (low - (atr * tpATRmultiplyer))
strategy.entry("Short", strategy.short)
strategy.exit("Short Exit", "Short", limit=takeProfit, stop=stopLoss)

Related

Compare bool and float to determine plot (pine script v5)

You folks helped me with another part of this script and I'm making good progress. However, I'm stuck again.
I added a code to produce a dynamic overbought/oversold line on the indicator. That part works great. Now, I'm wanting to add a plotshape when conditions are met to signal long or short. Unfortunately, I can't figure out how to compare a bool variable and a float variable. The dynamic OB/OS lines are floats. The crossover lines are bool.
What I want is for the (green/long) shape to plot when a crossover happens below the dynamic oversold line and the (red/short) shape to plot when the crossunder happens above the dynamic overbought line.
I've tried all kinds of things (var, loop with "while" using sb value as a trigger). I either break the code or I get every crossover plotted. Here is what I have that is stable. I took all my junk that didn't work out:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HammerGeek
//#version=5
indicator('Impulse MACD [HammerGeek - LazyBear]', shorttitle='IMACD_HG_LB', overlay=false)
lengthMA = input(34)
lengthSignal = input(9)
//OverBought = input.float(0.1)
//OverSold = input.float(-0.1)
calc_smma(src, len) =>
smma = 0.0
sma_1 = ta.sma(src, len)
smma := na(smma[1]) ? sma_1 : (smma[1] * (len - 1) + src) / len
smma
calc_zlema(src, length) =>
ema1 = ta.ema(src, length)
ema2 = ta.ema(ema1, length)
d = ema1 - ema2
ema1 + d
src = hlc3
hi = calc_smma(high, lengthMA)
lo = calc_smma(low, lengthMA)
mi = calc_zlema(src, lengthMA)
md = mi > hi ? mi - hi : mi < lo ? mi - lo : 0
sb = ta.sma(md, lengthSignal)
sh = md - sb
mda = ta.sma(md, lengthSignal)
OverBoughtLine = ta.highest(sb * 0.5, lengthMA*100)
OverSoldLine = ta.lowest(sb * 0.5, lengthSignal*100)
shsbCrossOver = ta.crossover(md, sb)
shsbCrossUnder = ta.crossunder(md, sb)
//mdc = src > mi ? src > hi ? color.lime : color.green : src < lo ? color.red : color.orange
mdc = color.green
plot(0, color=color.new(color.gray, 0), linewidth=1, title='MidLine')
plot(md, color=mdc, linewidth=2, title='ImpulseMACD', style=plot.style_line)
plot(sh, color=color.rgb(122, 5, 168, 40), linewidth=2, title='ImpulseHisto', style=plot.style_area)
plot(sb, color=color.rgb(255, 255, 255, transp = 40), linewidth=2, title='ImpulseMACDCDSignal')
plot(OverBoughtLine, color=color.new(#f3e032, 0), linewidth=1, title = 'Overbought Line')
plot(OverSoldLine, color=color.new(color.yellow, 0), linewidth=1, title = 'Oversold Line')
plotshape(shsbCrossOver, "LONG", shape.triangleup, location.bottom, color.new(color.green, 0))
plotshape(shsbCrossUnder, "SHORT", shape.triangledown, location.top, color.new(#cd0808, 0))
//ebc = input(false, title='Enable bar colors')
//barcolor(ebc ? mdc : na)
You cannot compare a bool with a float. It doesn't make any sense and it is not legal in pinescript.
What I want is for the (green/long) shape to plot when a crossover
happens below the dynamic oversold line and the (red/short) shape to
plot when the crossunder happens above the dynamic overbought line.
You want to check if the values you use in that crossover is under your dynamic oversold line at the time of crossover.
OverSoldLine = ta.lowest(sb * 0.5, lengthSignal*100)
shsbCrossOver = ta.crossover(md, sb)
is_good = shsbCrossOver and (md < OverSoldLine) and (sb < OverSoldLine)

increasing the displayed indicator value by a percentage

i'm trying to find a way to make a indicator like rsi or stochastic but be able to adjust the output by a percentage. For example RSI signal that is increased by a percentage of what i would output by default. So it normally show 70 but is increased to 80 e.g.
Is there a way to do this? I've been scrolling through the manual for hours but couldnt find it.
Any help is appreciated
//#version=4
study(title="RSI", shorttitle="RSI", format=format.price, precision=2, resolution="")
len = input(14, minval=1, title="Length")
src = input(close, "Source", type = input.source)
rsiValue = rsi(src, len)
i_perc = input(10, title = "Percentage", type = input.float) * 0.01
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsi_increase_conditon = rsiValue >= rsiValue[1] * (1 + i_perc)
rsi_decrease_conditon = rsiValue <= rsiValue[1] * (1 - i_perc)
plot(rsi, "RSI", color=color.white)
hline(70, "OBBand", color=color.red, linestyle=hline.style_solid)
hline(20, "XOSBand", color=color.blue, linestyle=hline.style_solid)
hline(50, "Mid", color=color.gray, linestyle=hline.style_solid)
hline(80, "XOBBand", color=color.blue, linestyle=hline.style_solid)
hline(30, "OSBand", color=color.red, linestyle=hline.style_solid)
i_perc = input(10, title = "Percentage", type = input.float) * 0.01
...
rsi_increase_conditon = rsiValue >= rsiValue[1] * (1 + i_perc)
rsi_decrease_conditon = rsiValue <= rsiValue[1] * (1 - i_perc)
plotshape(rsi_increase_conditon and not rsi_increase_conditon[1], title = "RSI Increase %", style = shape.triangleup, location = location.belowbar, size = size.normal)
plotshape(rsi_decrease_conditon and not rsi_decrease_conditon[1], title = "RSI Decrease %", style = shape.triangledown, location = location.abovebar, size = size.normal)

TRADE open and close in the same time

in the following strategy all time (trades) open and close in the same time, so I pay only fees.
I have written to tradingview assistance, they have said me (and send) to put OPEN LONG and CLOSE LONG (the first 2 lines in strategy).
But I still have the same problem, I don't know why.
All test are ok, I think that problem is with TRAIDINGVIEW HUB, but I am not scure.
Thanks for your attention and time
strategy V5
Open Long:
{"pair":"BTCUSDT","unitsPercent":"50","unitsType":"percentWallet","exchange":"Bybit","apiKey":"TradingView BYBIT ACC AFF","token":"7dfa66d6-5b94-4047-a11c-e8bdd0f1c0f4","isBuy":true,"isMarket":false,"leverage":"5","marginType":"ISOLATED","closeCurrentPosition":true,"delay":"10"}
Close Long:
{"pair":"BTCUSDT","unitsPercent":"50","exchange":"Bybit","apiKey":"TradingView BYBIT ACC AFF","token":"7dfa66d6-5b94-4047-a11c-e8bdd0f1c0f4","isClose":true,"delay":"10"}
strategy(title='Take profit (% of instrument price)', overlay=true, pyramiding=1)
// STEP 1:
// Make inputs that set the take profit % (optional)
FastPeriod = input.int(title='Fast MA Period', defval=18, minval=1, group='Moving Average')
SlowPeriod = input.int(title='Slow MA Period', defval=20, minval=1, group='Moving Average')
TPPerc = input.float(title='Long Take Profit (%)', minval=0.0, step=0.5, defval=0.9, group='TP & SL')
SLPerc = input.float(title='Long Stop Loss (%)', minval=0.0, step=0.1, defval=4, group='TP & SL')
TP_Ratio = input.float(title='Sell Postion Size % # TP', defval=100, step=1, group='TP & SL', tooltip='Example: 100 closing 100% of the position once TP is reached') / 100
// Calculate moving averages
fastSMA = ta.sma(close, FastPeriod)
slowSMA = ta.sma(close, SlowPeriod)
// Calculate trading conditions
enterLong = ta.crossover(fastSMA, slowSMA)
// Plot moving averages
plot(series=fastSMA, color=color.new(color.green, 0), title='Fase MA')
plot(series=slowSMA, color=color.new(color.red, 0), title='Slow MA')
// STEP 2:
// Figure out take profit price
percentAsPoints(pcnt) =>
strategy.position_size != 0 ? math.round(pcnt / 100.0 * strategy.position_avg_price / syminfo.mintick) : float(na)
percentAsPrice(pcnt) =>
strategy.position_size != 0 ? (pcnt / 100.0 + 2.0) * strategy.position_avg_price : float(na)
current_position_size = math.abs(strategy.position_size)
initial_position_size = math.abs(ta.valuewhen(strategy.position_size[1] == 0.0, strategy.position_size, 0))
TP = strategy.position_avg_price + percentAsPoints(TPPerc) * syminfo.mintick * strategy.position_size / math.abs(strategy.position_size)
SL = strategy.position_avg_price - percentAsPoints(SLPerc) * syminfo.mintick * strategy.position_size / math.abs(strategy.position_size)
// Submit entry orders
if enterLong
strategy.entry(id='Long', direction=strategy.long)
// STEP 3:
// Submit exit orders based on take profit price
if strategy.position_size > 0
strategy.exit('TP', from_entry='Long', qty=initial_position_size * TP_Ratio, limit=TP, stop=SL)
// Plot take profit values for confirmation
plot(series=strategy.position_size > 0 ? TP : na, color=color.new(color.green, 0), style=plot.style_circles, linewidth=1, title='Take Profit 1')
plot(series=strategy.position_size > 0 ? SL : na, color=color.new(color.red, 0), style=plot.style_circles, linewidth=1, title='Stop Loss')

How to find data of wma at the open position?

I have this plot:
WMA_point = wma(close, 9)
plot(WMA_point, title='WMA', color=#000000)
It makes a line on the chart. When the price goes up, the line moves up, and vice versa, when the price goes down, it moves down.
I know that it depends on the "close" data.
I would like to find the price data of this wma when (close == open)
EDIT:
I mean: I want to get the first data of the close line wma(close, 9), when the new candle appears, when the (close == open) . I dont need the data of the open line wma(open, 9)
You can either use WMA_point[1], which is generally where the price value of the current bar will open at. If you want to take into consideration gapping, you'll need to calculate the wma using n-1 historical close values and with the nth value the current bar's open.
//#version=5
indicator("wma open", overlay = true)
len = input.int(10)
float wtd_close_sum = 0.0
int denom = 0
for i = 1 to len - 1
wt = len - i
wtd_close_sum += close[i] * wt
denom += wt
wtd_close_sum += open * len
denom += len
wma_open = wtd_close_sum / denom
plot(wma_open)
as a function :
f_wma_open(_open, _close, _len) =>
float _wtd_close_sum = 0.0
int _denom = 0
for i = 1 to _len - 1
_wt = _len - i
_wtd_close_sum += _close[i] * _wt
_denom += _wt
_wtd_close_sum += _open * _len
_denom += _len
_wma_open = _wtd_close_sum / _denom
_wma_open
Try using open as your source:
WMA_point = wma(open, 9)
plot(WMA_point, title='WMA', color=#000000)
Cheers, and best of luck with your trading and coding
So, you need to store the price in a var when your condition is true.
var float p = na
WMA_point = wma(close, 9)
if (open == close)
p := WMA_point // This will have the wma value of the last time open == close
plot(WMA_point, title='WMA', color=#000000)

Buy and sell-markers on lower time frames when longer time frame shows uptrend

So, I'm trying to run a trading bot on medium timeframes (1h - 4h) using the KDJ-indicator. I know it's not the most responsive indicator but it is very reliable, at least on higher time frames (8h - 1D).
What I would like to be able to do is use the following script to send BUY/SELL-signals to my bot, BUT ONLY when the asset is not trending down on the 1D-chart. In other words, I would like to run this script:
//#version=4
study(title="KDJ IndicatorTV", shorttitle="KDJ_TV", format=format.price, precision=2, resolution="", overlay=true)
periodK = input(9, title="K", minval=1)
periodD = input(5, title="D", minval=1)
smoothK = input(3, title="Smooth", minval=1)
multiplierJ = input(3.5, title="Jx", minval=0.1)
k = ema(stoch(hlc3, high, low, periodK), smoothK)
d = ema(k, periodD)
j = multiplierJ * k-2 * d
makeShape1 = if (crossover(j,d) or crossover(j,99))
true
else
false
plotshape(series=makeShape1, style=shape.cross, color=#0094FF, transp=10, text="buy", title='buy')
makeShape2 = if (crossunder(j,d) or crossunder(j,99))
true
else
false
plotshape(series=makeShape2, style=shape.cross, color=#FF6A00, transp=10, text="sell", title='sell')
//end
And I would like to add a condition to makeShape1, something like "AND If j>d on 1D-chart", to ensure that buys are only generated while J is larger than D on the 1D-chart of that asset (ie: when the market for that asset is in an uptrend).
Any ideas on if/how I can achieve that?
Thanks!
-Daniel
You can access higher TFs with security() function
//#version=4
study(title="KDJ IndicatorTV", shorttitle="KDJ_TV", format=format.price, precision=2, resolution="", overlay=true)
periodK = input(9, title="K", minval=1)
periodD = input(5, title="D", minval=1)
smoothK = input(3, title="Smooth", minval=1)
multiplierJ = input(3.5, title="Jx", minval=0.1)
k = ema(stoch(hlc3, high, low, periodK), smoothK)
d = ema(k, periodD)
j = multiplierJ * k-2 * d
j_sec = security(syminfo.tickerid, "D", j) // 1 day time frame for j
d_sec = security(syminfo.tickerid, "D", d) // 1 day time frame for d
makeShape1 = if (crossover(j,d) or crossover(j,99)) and j_sec > d_sec
true
else
false
plotshape(series=makeShape1, style=shape.cross, color=#0094FF, transp=10, text="buy", title='buy')
makeShape2 = if (crossunder(j,d) or crossunder(j,99))
true
else
false
plotshape(series=makeShape2, style=shape.cross, color=#FF6A00, transp=10, text="sell", title='sell')
//end