Multiple long orders with separate take profit and stop loss - position

A bit new with coding. Hope to find some help.
I am trying to get each long position to have its own take profit and stop loss.
What ends up happening is, whenever the next long position is triggered, the previous TP and SL get recalculated and I end up with all positions having only one TP and SL levels.
Thanks
Played around with exit code and lastEntryPriceLong but not a big coder, soo... any help would be appreciated.
//////// Long Position 0 (1) ////////
if longCondition and longConditionATR and longConditionEMA and barRangeCondition and strategy.opentrades == 0
strategy.entry('Long', strategy.long)
lastEntryPriceLong = strategy.opentrades.entry_price(0)
var float LongTP = na
var float LongSL = na
if (strategy.position_size[1] != strategy.position_size)
LongTP := lastEntryPriceLong*2 - low[1]
LongSL := lastEntryPriceLong - (lastEntryPriceLong - low[1] + atr*2)
inTradeLong = strategy.position_size > 0
plot(inTradeLong ? LongTP : na, color=color.green, style=plot.style_circles)
plot(inTradeLong ? LongSL : na, color=color.red, style=plot.style_circles)
strategy.exit('Close Long', 'Long', stop=LongSL, limit=LongTP)
//////// Long Position 1 (2) ////////
if longCondition and longConditionATR and longConditionEMA and barRangeCondition and strategy.opentrades == 1
strategy.entry('Long1', strategy.long)
lastEntryPriceLong1 = strategy.opentrades.entry_price(1)
var float LongTP1 = na
var float LongSL1 = na
if (strategy.position_size[1] != strategy.position_size)
LongTP1 := lastEntryPriceLong1*2 - low[1]
LongSL1 := lastEntryPriceLong1 - (lastEntryPriceLong1 - low[1] + atr*2)
inTradeLong1 = strategy.position_size > 0
plot(inTradeLong1 ? LongTP1 : na, color=color.green, style=plot.style_circles)
plot(inTradeLong1 ? LongSL1 : na, color=color.red, style=plot.style_circles)
strategy.exit('Close Long1', 'Long1', stop=LongSL1, limit=LongTP1)
You can see Example here
Thanks
.

strategy.exit is in the root scope. So, it gets executed on each bar overwriting earlier entry.
You need to do few things here:
Move strategy.exit and the related calculations inside if condition where you have strategy.entry. This way, exit and entry are set together.
Use an auto incrementing Id instead of same id for all. You can do it using
var id= 1
if(longCondition)
entryId = Long+str.tostring(id)
exitId = ExitLong+str.tostring(id)
id+=1
strategy.entry(entryId, strategy.long, ...)
strategy.exit(exitId, entryId, ...)
In strategy definition, set close_entry_rule to ANY. This will let each trade track it's own exit based on id instead of closing order based on FIFO or FILO.
https://www.tradingview.com/pine-script-reference/v5/#fun_strategy

Related

Draw line below/above line.new

Here is a script i'm using for detecting pivot point.
I'd like to draw a line at the close of the new detected pivot point, each time new pivot point are detected (and deleting other lines)
i try to change the line.new value to get the "close" but it didn't work
See the picture below, the blue lines i draw is what i'm searching to do :D
enter image description here
indicator("Pivot Points", overlay=true)
// Get user input
var devTooltip = "Deviation is a multiplier that affects how much the price should deviate from the previous pivot in order for the bar to become a new pivot."
var depthTooltip = "The minimum number of bars that will be taken into account when analyzing pivots."
threshold_multiplier = input.float(title="Deviation", defval=2.5, minval=0, tooltip=devTooltip)
depth = input.int(title="Depth", defval=10, minval=1, tooltip=depthTooltip)
deleteLastLine = input.bool(title="Delete Last Line", defval=false)
bgcolorChange = input.bool(title="Change BgColor", defval=false)
// Calculate deviation threshold for identifying major swings
dev_threshold = ta.atr(10) / close * 100 * threshold_multiplier
// Prepare pivot variables
var line lineLast = na
var int iLast = 0 // Index last
var int iPrev = 0 // Index previous
var float pLast = 0 // Price last
var isHighLast = false // If false then the last pivot was a pivot low
// Custom function for detecting pivot points (and returning price + bar index)
pivots(src, length, isHigh) =>
l2 = length * 2
c = nz(src[length])
ok = true
for i = 0 to l2
if isHigh and src[i] > c // If isHigh, validate pivot high
ok := false
if not isHigh and src[i] < c // If not isHigh, validate pivot low
ok := false
if ok // If pivot is valid, return bar index + high price value
[bar_index[length], c]
else // If pivot is invalid, return na
[int(na), float(na)]
// Get bar index & price high/low for current pivots
[iH, pH] = pivots(high, depth / 2, true)
[iL, pL] = pivots(low, depth / 2, false)
// Custom function for calculating price deviation for validating large moves
calc_dev(base_price, price) => 100 * (price - base_price) / price
// Custom function for detecting pivots that meet our deviation criteria
pivotFound(dev, isHigh, index, price) =>
if isHighLast == isHigh and not na(lineLast) // Check bull/bear direction of new pivot
// New pivot in same direction as last (a pivot high), so update line upwards (ie. trend-continuation)
if isHighLast ? price > pLast : price < pLast // If new pivot is above last pivot, update line
line.set_xy2(lineLast, index, price)
[lineLast, isHighLast]
else
[line(na), bool(na)] // New pivot is not above last pivot, so don't update the line
else // Reverse the trend/pivot direction (or create the very first line if lineLast is na)
if math.abs(dev) > dev_threshold
// Price move is significant - create a new line between the pivot points
id = line.new(iLast, pLast, index, price, color=color.gray, width=1, style=line.style_dashed)
[id, isHigh]
else
[line(na), bool(na)]
// If bar index for current pivot high is not NA (ie. we have a new pivot):
if not na(iH)
dev = calc_dev(pLast, pH) // Calculate the deviation from last pivot
[id, isHigh] = pivotFound(dev, true, iH, pH) // Pass the current pivot high into pivotFound() for validation & line update
if not na(id) // If the line has been updated, update price & index values and delete previous line
if id != lineLast and deleteLastLine
line.delete(lineLast)
lineLast := id
isHighLast := isHigh
iPrev := iLast
iLast := iH
pLast := pH
else
if not na(iL) // If bar index for current pivot low is not NA (ie. we have a new pivot):
dev = calc_dev(pLast, pL) // Calculate the deviation from last pivot
[id, isHigh] = pivotFound(dev, false, iL, pL) // Pass the current pivot low into pivotFound() for validation & line update
if not na(id) // If the line has been updated, update price values and delete previous line
if id != lineLast and deleteLastLine
line.delete(lineLast)
lineLast := id
isHighLast := isHigh
iPrev := iLast
iLast := iL
pLast := pL
**// Get starting and ending high/low price of the current pivot line
startIndex = line.get_x1(lineLast)
startPrice = line.get_y1(lineLast)
endIndex = line.get_x2(lineLast)
endPrice = line.get_y2(lineLast)
// Draw top & bottom of impulsive move
topLine = line.new(startIndex, startPrice, endIndex, startPrice, extend=extend.right, color=color.red)
bottomline = line.new(startIndex, endPrice, endIndex, endPrice, extend=extend.right, color=color.green)
line.delete(topLine[1])
line.delete(bottomline[1])**
//plot(startPrice, color=color.green)
//plot(endPrice, color=color.red)
// Do what you like with these pivot values :)
// Keep in mind there will be an X bar delay between pivot price values updating based on Depth setting
dist = math.abs(startPrice - endPrice)
plot(dist, color=color.new(color.purple,100))
bullish = endPrice > startPrice
offsetBG = -(depth / 2)
bgcolor(bgcolorChange ? bullish ? color.new(color.green,90) : color.new(color.red,90) : na, offset=offsetBG)
Thank you
Changing the code
**// Get starting and ending high/low price of the current pivot line
startIndex = line.get_x1(lineLast)
startPrice = line.get_y1(lineLast)
endIndex = line.get_x2(lineLast)
endPrice = line.get_y2(lineLast)
// Draw top & bottom of impulsive move
topLine = line.new(startIndex, startPrice, endIndex, startPrice, extend=extend.right, color=color.red)
bottomline = line.new(startIndex, endPrice, endIndex, endPrice, extend=extend.right, color=color.green)
line.delete(topLine[1])
line.delete(bottomline[1])**

Why doesn't my if-statements return the right numbers?

First of all, this is my first week trying out C# or any other programming language for that matter, also my first post here on Stackoverflow!
Been working on this change calculator for a while now, trying to get it to round the result to either 0 if its <.25, 0.50 if it's between .25 and .75 and 1 if it's >.75. Seems like it's ignoring my if-statements, And on top of that the result I get isn't correct either. Some calculations ends up being negative, which I can't figure out why :/
double summa0 = vara - kontant; //item - change
var extrakt = (int)summa0; //removes decimals out of summa0 = 107
var avrundsSumma = summa0 - extrakt; //<--- extracts the decimals out of summa0
if (avrundsSumma < 0.25f)
{
avrundsSumma = Math.Floor(avrundsSumma);
}
else if (avrundsSumma > 0.75f) //Runs the decimals through if-statements
{
avrundsSumma = Math.Ceiling(avrundsSumma);
}
else
{
avrundsSumma = 0.5;
} // = in this case the result should be 1
double summa = extrakt + avrundsSumma; // 107 + 1 = 108
double attBetala = kontant - summa; // 500 - 108 = 392
Since I'm very new to this it's hard to know exactly which part of the code is causing the issue. When I run the code in CMD I get a negative result from "double summa = extrakt + avrundsSumma; // 107 + 1 = 108"
So instead of 108 I get -108.
Not sure what you mean by "Hard code the values" either :o

How to force a waiting time of a few seconds between execution of commands in Pine? Need cooldown between close and open possition

A simple strategy script sends alerts to open and exit trades, that need to switch between long and short when conditions are met.
Problem: Two alerts (e.g. exit short / enter long) are generated one after the other. Enter long fails, as the previous short deal didn't have time to close.
Question: How can I delay script execution by 5-10 seconds?
Have tried Utilities.sleep(10000), but it does not compile.
*I am a complete beginner, and looking for a simple answer. Hope there is one :]
Here the code:
'''
strategy("My Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=15)
////////////
// Inputs //
length = input(100)
mult = input(2.0)
message_long_entry = input("long entry message")
message_long_exit = input("long exit message")
message_short_entry = input("short entry message")
message_short_exit = input("short exit message")
atrPeriod = input(10, "ATR Length")
factor = input.float(3.0, "Factor", step = 0.01)
[_, direction] = ta.supertrend(factor, atrPeriod)
if ta.change(direction) < 0
strategy.entry("My Long Entry Id", strategy.long, when = barstate.isconfirmed)
alert(message_short_exit)
/// Utilities.sleep(10000) <--- Delay needed here
alert(message_long_entry)
if ta.change(direction) > 0
strategy.entry("My Short Entry Id", strategy.short, when = barstate.isconfirmed)
alert(message_long_exit)
/// Utilities.sleep(10000) <--- Delay needed here
alert(message_short_entry)
'''
You can use this example from Pinecoders FAQ
//#version=5
strategy('Strat with time delay', overlay=true)
i_qtyTimeUnits = -input.int(20, 'Quantity', inline='Delay', minval=0, tooltip='Use 0 for no delay')
i_timeUnits = input.string('minutes', '', inline='Delay', options=['seconds', 'minutes', 'hours', 'days', 'months', 'years'])
// ————— Converts current chart timeframe into a float minutes value.
f_tfInMinutes() =>
_tfInMinutes = timeframe.multiplier * (timeframe.isseconds ? 1. / 60 : timeframe.isminutes ? 1. : timeframe.isdaily ? 60. * 24 : timeframe.isweekly ? 60. * 24 * 7 : timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
_tfInMinutes
// ————— Calculates a +/- time offset in variable units from the current bar's time or from the current time.
// WARNING:
// This functions does not solve the challenge of taking into account irregular gaps between bars when calculating time offsets.
// Optimal behavior occurs when there are no missing bars at the chart resolution between the current bar and the calculated time for the offset.
// Holidays, no-trade periods or other irregularities causing missing bars will produce unpredictable results.
f_timeFrom(_from, _qty, _units) =>
// _from : starting time from where the offset is calculated: "bar" to start from the bar's starting time, "close" to start from the bar's closing time, "now" to start from the current time.
// _qty : the +/- qty of _units of offset required. A "series float" can be used but it will be cast to a "series int".
// _units : string containing one of the seven allowed time units: "chart" (chart's resolution), "seconds", "minutes", "hours", "days", "months", "years".
// Dependency: f_resInMinutes().
int _timeFrom = na
// Remove any "s" letter in the _units argument, so we don't need to compare singular and plural unit names.
_unit = str.replace_all(_units, 's', '')
// Determine if we will calculate offset from the bar's time or from current time.
_t = _from == 'bar' ? time : _from == 'close' ? time_close : timenow
// Calculate time at offset.
if _units == 'chart'
// Offset in chart res multiples.
_timeFrom := int(_t + f_tfInMinutes() * 60 * 1000 * _qty)
_timeFrom
else
// Add the required _qty of time _units to the _from starting time.
_year = year(_t) + (_unit == 'year' ? int(_qty) : 0)
_month = month(_t) + (_unit == 'month' ? int(_qty) : 0)
_day = dayofmonth(_t) + (_unit == 'day' ? int(_qty) : 0)
_hour = hour(_t) + (_unit == 'hour' ? int(_qty) : 0)
_minute = minute(_t) + (_unit == 'minute' ? int(_qty) : 0)
_second = second(_t) + (_unit == 'econd' ? int(_qty) : 0)
// Return the resulting time in ms Unix time format.
_timeFrom := timestamp(_year, _month, _day, _hour, _minute, _second)
_timeFrom
// Entry conditions.
ma = ta.sma(close, 100)
goLong = close > ma
goShort = close < ma
// Time delay filter
var float lastTradeTime = na
if nz(ta.change(strategy.position_size), time) != 0
// An order has been executed; save the bar's time.
lastTradeTime := time
lastTradeTime
// If user has chosen to do so, wait `i_qtyTimeUnits` `i_timeUnits` between orders
delayElapsed = f_timeFrom('bar', i_qtyTimeUnits, i_timeUnits) >= lastTradeTime
if goLong and delayElapsed
strategy.entry('Long', strategy.long, comment='Long')
if goShort and delayElapsed
strategy.entry('Short', strategy.short, comment='Short')
plot(ma, 'MA', goLong ? color.lime : color.red)
plotchar(delayElapsed, 'delayElapsed', '•', location.top, size=size.tiny)
What worked for me was just adding a while loop in my webhook side code checking if there is in realtime an active trade. Im using binance so through postman i accessed to GET /fapi/v2/positionRisk which shows you your current positions information which shows like this:
[
{
"symbol": "BTCUSDT",
"positionAmt": "0.000",
"entryPrice": "0.0",
"markPrice": "22615.15917559",
"unRealizedProfit": "0.00000000",
"liquidationPrice": "0",
"leverage": "10",
"maxNotionalValue": "20000000",
"marginType": "isolated",
"isolatedMargin": "0.00000000",
"isAutoAddMargin": "false",
"positionSide": "BOTH",
"notional": "0",
"isolatedWallet": "0",
"updateTime": 165963
} ]
so accessing your current positions amount:
check = float(client.futures_position_information(symbol="BTCUSDT")[0]["positionAmt"])
note if you have hedge mode activated you would have to check from both your long or short side positions changing through [0] or [1] depending on which side you need.
now you can just add the loop before any of your entries:
while check != 0:
check = float(client.futures_position_information(symbol="BTCUSDT")[0]["positionAmt"])
order = client.futures_create_order(symbol=symbol, side=side, type=order_type, quantity=quantity) //this is your entry after loop breaks
this will delay any of your entries with the loop always updating and checking your current position amount until all of your positions are closed which will make it 0, breaking, and then allowing the code to keep going and start a new position in this case

How to access the last indicator values

I've got an indicator which shows pivot points:
//#version=4
study("Trend", overlay=false)
leftBars = input(3)
rightBars = input(3)
ph = pivothigh(high, leftBars, rightBars)
pl = pivotlow(low, leftBars, rightBars)
How can I check if the last ph was higher than the ph before? (I'd like to check for an uptrend or downtrend)
You can try the following code (including your original, as you see):
//#version=4
study("Trend", overlay=false)
leftBars = input(3)
rightBars = input(3)
ph = pivothigh(high, leftBars, rightBars)
pl = pivotlow(low, leftBars, rightBars)
//INIT VARIABLES
var int ph_uptrend_flag = 0
var float ph_valid = 0
var float ph_valid_old = 1e99 // use any very high non meaningful number here for initialization only
ph_non_na = nz(ph,0) // stores 0's instead of na's for non-pivot-pointed bars
// re-calculate uptrend flag every time a new pivot comes in, otherwise keep last known value for uptrend flag
if ph_non_na != 0
ph_valid := ph_non_na
ph_uptrend_flag := ph_valid > ph_valid_old ? 1 : 0
ph_valid_old := ph_valid
else
ph_valid := ph_valid
ph_valid_old := ph_valid_old
//plot uptrend flag and mark background accordingly
plot(ph_uptrend_flag,title="ph uptrend indication",linewidth=4,color=color.white)
//plot(ph,title="ph value",color=color.lime,style=8) //plot ph values (better used with overlay=true)

Mean of one variable when another variable equals 1 in matlab

I would like to get the mean of my reaction time column when my stimnum column is equal to 1
I am not sure if i can do this with one simple line of code or if i need to do a for loop.
stimnum = randi([1 3], [1 100]);
y = 1 + 1.*randn(1, 100);
rt = (y.^2) +.01;
A = rand(1,100);
correct = A>=0.2;
Data= [stimnum; rt; correct ]';
Data = dataset({ Data, 'Stimnum', 'RT', 'Correct'});
rtmean = mean (Data.RT{Data.Stimnum == 1});

Resources