Pinescript - "Compare" Indicator with Percentage Change Function takes only last bar data - compare

need help pls.
In Tradingview I use "Compare" to see the BTCUSDT vs. ETHUSDT on Binance and it's basically OK. But lines on the chart are too "up & down" and I want to see the SMA or EMA for those tickers.
I'm trying to do it step by step but I can't pass through the issue that my code takes only last calculated value in consideration and "percentage change line" starts from 0 with each new data. So it makes no sence. Meaning, my last data doesn't add upon prior value, but always starts from zero.
So, data (value) that comes out is good (same as when I put same tickers on Tradingview "Compare") but Tradingview "Compare" calculates / adds data on historical data, while my code starts from 0.
Here is the Pine script code:
//#version=4
study(title="Compare", shorttitle="Compare", overlay=false, max_bars_back=0)
perc_change = (((close[0] - open[0]) / open [0]) * 100)
sym1 = "BINANCE:BTCUSDT", res1 = "30", source1 = perc_change
plot(security(sym1, res1, source1), color=color.orange, linewidth=2)
sym2 = "BINANCE:ETHUSDT", res2 = "30", source2 = perc_change
plot(security(sym2, res2, source2), color=color.blue, linewidth=2)

Sounds like the delta between the two ROCs is what you are looking for. With this you can show only the 2 ROCs, but also columns representing the delta between the two. you can also change the ROC's period:
//#version=4
study(title="Compare", shorttitle="Compare")
rocPeriod = input(1, minval = 1)
showLines = input(true)
showDelta = input(true)
perc_change = roc(close, rocPeriod)
sym1 = "BINANCE:BTCUSDT"
sym2 = "BINANCE:ETHUSDT"
res = "30"
s1 = security(sym1, res, perc_change)
s2 = security(sym2, res, perc_change)
delta = s1 - s2
plot(showLines ? s1 : na, "s1", color.orange)
plot(showLines ? s2 : na, "s2", color.blue)
hline(0)
plot(showDelta ? delta : na, "delta", delta > 0 ? color.lime : color.red, 1, plot.style_columns)

Related

Updating the values of variables in DAX

I need to change the value of variables in a switch in dax:
switch( true(),
condition1,
var test1 = 2
var test2 = 3
,condition 2,
var test1 = 4
var test2 = 5
,
var test1 = 7
var test2 = 6
)
I need to do this because I have to change massive number of variables depending on the condition, and I don't want to have a switch for every single variable.
I already tried this approach with switch and it works without variables.
It's like dax does not allow you to change the value of a variable after the first time it was assigned.
edit
hello, here is the example of what I want to achieve:
Value Daily Form =
SWITCH( true(),
// if both are selected
(ISFILTERED(tblAAA[AAA_name]) && ISFILTERED(tblBBB[BBB_name])),
var Target = sum(F_Daily_AAA_BBB[target])
var TotalPayments = sum(F_Daily_AAA_BBB[vlr_total_payment])
// if AAA is selected
, (ISFILTERED(tblAAA[AAA_name]) && not(ISFILTERED(tblBBB[BBB_name]))),
var Target = sum(F_Daily_AAA[target])
var TotalPayments = sum(F_Daily_AAA[vlr_total_payment])
// if BBB is selected
, (not(ISFILTERED(tblAAA[AAA_name])) && ISFILTERED(tblBBB[BBB_name])),
var Target = sum(F_Daily_BBB[target])
var TotalPayments = sum(F_Daily_BBB[vlr_total_payment])
// none is selected
,
var Target = sum(F_Daily_OR[target])
var TotalPayments = sum(F_Daily_OR[vlr_total_payment])
)
var result =
SWITCH(FIRSTNONBLANK(tblKPIs[Group_Name], tblKPIs[Group_Name]),
"Target (€)", IF(Target > 0, FORMAT(Target, "€ #,##"), if(SELECTEDVALUE('Calendar'[isWorkingDay]) = 1, "€ 0", BLANK())),
"Total Payments (€)", IF(TotalPayments > 0, FORMAT(TotalPayments, "€ #,##"), IF(SELECTEDVALUE('Calendar'[isWorkingDay]) = 1, "€ 0", BLANK())),
)
return result
in the beginning the code that I have to modify is:
Value Daily Form =
var Target = sum(F_Daily_OR[target])
var TotalPayments = sum(F_Daily_OR[vlr_total_payment])
var result =
SWITCH(FIRSTNONBLANK(tblKPIs[Group_Name], tblKPIs[Group_Name]),
"Target (€)", IF(Target > 0, FORMAT(Target, "€ #,##"), if(SELECTEDVALUE('Calendar'[isWorkingDay]) = 1, "€ 0", BLANK())),
"Total Payments (€)", IF(TotalPayments > 0, FORMAT(TotalPayments, "€ #,##"), IF(SELECTEDVALUE('Calendar'[isWorkingDay]) = 1, "€ 0", BLANK())),
)
return result
The only difference is the instead of 2 variables there are like 75,
and I don't want to make a switch for each of them because this will spaghettify the code.
Also I have to modify like 50 of this Metrics full of variables, so I need a quick copy paste solution like that switch, which worked in other cases in which the code didn't have variables.
Thank you for taking the time to help me.
It is indeed, because variables in DAX are actually constants. Variables are immutable. You can store the value in variable but you cannot change it later.
Here is a definition of the DAX variable from the documentation:
Stores the result of an expression as a named variable, which can then be passed as an argument to other measure expressions. Once resultant values have been calculated for a variable expression, those values do not change, even if the variable is referenced in another expression.
Find more in the documentation.
What exactly do you want to achieve by this?
Creating separate measure for each condition and then another measure with switch condition won't work for you?

How to set proper back test range

I do not know how to code and I am trying to learn Pinescript but it really makes no sense to me so i googled how to set a backtest range and used some code someone else wrote but it doesn't seem to be actually testing the area i would like, it tests the entirety of the chart. I'd like to test from 1/1/2018 to present. I'm trying to do this for multiple strategies so I can better tailor them to the current market. here is wat I have for one of them and if you are willing to help with the others I would very much appreciate it!!! feel free to DM me.
//#version=5
strategy("Bollinger Bands BACKTEST", overlay=true)
source = close
length = input.int(20, minval=1)
mult = input.float(2.0, minval=0.001, maxval=50)
basis = ta.sma(source, length)
dev = mult * ta.stdev(source, length)
upper = basis + dev
lower = basis - dev
buyEntry = ta.crossover(source, lower)
sellEntry = ta.crossunder(source, upper)
if (ta.crossover(source, lower))
strategy.entry("BBandLE", strategy.long, stop=lower, oca_name="BollingerBands", oca_type=strategy.oca.cancel, comment="BBandLE")
else
strategy.cancel(id="BBandLE")
if (ta.crossunder(source, upper))
strategy.entry("BBandSE", strategy.short, stop=upper, oca_name="BollingerBands", oca_type=strategy.oca.cancel, comment="BBandSE")
else
strategy.cancel(id="BBandSE")
//plot(strategy.equity, title="equity", color=color.red, linewidth=2, style=plot.style_areabr)
// === INPUT BACKTEST RANGE ===
fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromDay = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromYear = input.int(defval = 2018, title = "From Year", minval = 1970)

Pinescript. Plotting conditional statement

If the variable barup is true, I want it to plot one series; if the variable bardown is true, I want it to plot another series value.
My current code yields the error: Cannot use "plot in local scope".
How do I change the following code to make the indicator show the number of days the lows have been above the 30 ema or below the 30 day ema based on the high or low of the current day.
Here is the code I have now:
indicator("LandryLight")
bardown = high < ta.ema(close,30)
barup = low > ta.ema(close,30)
if barup
plot(series=ta.barssince(barup)*-1, title="Consecutive Bars Down", color=color.red, style=plot.style_histogram, linewidth=2)
if bardown
plot(series=ta.barssince(bardown), title="Consecutive Bars Up", color=color.green, style=plot.style_histogram, linewidth=2)
hline(10,title="Threshold", color=color.white, linestyle=hline.style_dashed, linewidth=1)
First Use tag [pine-script]
Try going step by step, and then the plot
I would do it like this:
//#version=5
indicator("LandryLight")
bardown = high < ta.ema(close,30)
barup = low > ta.ema(close,30)
barupCont = ta.barssince(barup)*-1
bardownCont = ta.barssince(bardown)
barupOK = barup ? barupCont : na
bardownOK = bardown ? bardownCont : na
plot(series= barupOK, title="Consecutive Bars Down", color=color.red, style=plot.style_histogram, linewidth=2)
plot(series= bardownOK, title="Consecutive Bars Up", color=color.green, style=plot.style_histogram, linewidth=2)
hline(10,title="Threshold", color=color.white, linestyle=hline.style_dashed, linewidth=1)

Calculating results pro rata over several months with PowerQuery

I am currently stuck on below issue:
I have two tables that I have to work with, one contains financial information for vessels and the other contains arrival and departure time for vessels. I get my data combining multiple excel sheets from different folders:
financialTable
voyageTimeTable
I have to calculate the result for above voyage, and apportion the result over June, July and August for both estimated and updated.
Time in June : 4 hours (20/06/2020 20:00 - 23:59) + 10 days (21/06/2020 00:00 - 30/06/2020 23:59) = 10.1666
Time in July : 31 full days
Time in August: 1 day + 14 hours (02/08/2020 00:00 - 14:00) = 1.5833
Total voyage duration = 10.1666 + 31 + 1.5833 = 42.7499
The result for the "updated" financialItem would be the following:
Result June : 100*(10.1666/42.7499) = 23.7816
Result July : 100*(31/42.7499) = 72.5148
Result August : 100*(1.5833/42.7499) = 3.7036
sum = 100
and then for "estimated" it would be twice of everything above.
This is the format I ideally would like to get:
prorataResultTable
I have to do this for multiple vessels, with multiple timespans and several voyage numbers.
Eagerly awaiting responses, if any. Many thanks in advance.
Brds,
Not sure if you're still looking for an answer, but code below gives me your expected output:
let
financialTable = Table.FromRows({{"A", 1, "profit/loss", 200, 100}}, type table [vesselName = text, vesselNumber = Int64.Type, financialItem = text, estimated = number, updated = number]),
voyageTimeTable = Table.FromRows({{"A", 1, #datetime(2020, 6, 20, 20, 0, 0), #datetime(2020, 8, 2, 14, 0, 0)}}, type table [vesselName = text, vesselNumber = Int64.Type, voyageStartDatetime = datetime, voyageEndDatetime = datetime]),
joined =
let
joined = Table.NestedJoin(financialTable, {"vesselName", "vesselNumber"}, voyageTimeTable, {"vesselName", "vesselNumber"}, "$toExpand", JoinKind.LeftOuter),
expanded = Table.ExpandTableColumn(joined, "$toExpand", {"voyageStartDatetime", "voyageEndDatetime"})
in expanded,
toExpand = Table.AddColumn(joined, "$toExpand", (currentRow as record) =>
let
voyageInclusiveStart = DateTime.From(currentRow[voyageStartDatetime]),
voyageExclusiveEnd = DateTime.From(currentRow[voyageEndDatetime]),
voyageDurationInDays = Duration.TotalDays(voyageExclusiveEnd - voyageInclusiveStart),
createRecordForPeriod = (someInclusiveStart as datetime) => [
inclusiveStart = someInclusiveStart,
exclusiveEnd = List.Min({
DateTime.From(Date.EndOfMonth(DateTime.Date(someInclusiveStart)) + #duration(1, 0, 0, 0)),
voyageExclusiveEnd
}),
durationInDays = Duration.TotalDays(exclusiveEnd - inclusiveStart),
prorataDuration = durationInDays / voyageDurationInDays,
estimated = prorataDuration * currentRow[estimated],
updated = prorataDuration * currentRow[updated],
month = Date.MonthName(DateTime.Date(inclusiveStart)),
year = Date.Year(inclusiveStart)
],
monthlyRecords = List.Generate(
() => createRecordForPeriod(voyageInclusiveStart),
each [inclusiveStart] < voyageExclusiveEnd,
each createRecordForPeriod([exclusiveEnd])
),
toTable = Table.FromRecords(monthlyRecords)
in toTable
),
expanded =
let
dropped = Table.RemoveColumns(toExpand, {"estimated", "updated", "voyageStartDatetime", "voyageEndDatetime"}),
expanded = Table.ExpandTableColumn(dropped, "$toExpand", {"month", "year", "estimated", "updated"})
in expanded
in
expanded
The code tries to:
join financialTable and voyageTimeTable, so that for each vesselName and vesselNumber combination, we know: estimated, updated, voyageStartDatetime and voyageEndDatetime.
generate a list of months for the period between voyageStartDatetime and voyageEndDatetime (which get expanded into new table rows)
for each month (in the list), do all the arithmetic you mention in your question
get rid of some columns (like the old estimated and updated columns)
I recommend testing it with different vesselNames and vesselNumbers from your dataset, just to see if the output is always correct (I think it should be).
You should be able to manually inspect the cells in the $toExpand column (of the toExpand step/expression) to see the nested rows before they get expanded.

PowerBi subtracting two cells in different rows with condition

I am wondering if something that i would like to achieve is possible, please look at the picture and read description below:
I would like to add a column to the right, where if a cell table[ActionType] = "TERMINATING", it calculates a difference between timestamps (timestamp for TERMINATING - timestamp for STARTING in below row). If the result is positive (>0) then store it in a column in a corresponding row (eg next to timestapm for terminating), if result is negative don't store it. And all of that applied to whole table.
I tried conditional column and i guess it cannot be done with this or at least I couldn't make it.
Will be very thankful for responses and tips!
Pre-requisite :- Add an Index Column using the query editor. Make sure they are in the next row to each other.
It is advisable to keep TimeStamp column as a DateTime Column itself.
So, if you can change your TimeStamp column to a DateTime column then try this :-
Difference =
Var Get_Action_Type = Table1[ActionType]
Var required_Index_1 = Table1[Index] + 1
Var required_Index = IF(required_Index_1 > MAX(Table1[Index]),required_Index_1-1, required_Index_1)
Var Current_Action_TimeStamp = Table1[TimeStamp]
Var next_Action_TimeStamp = CALCULATE(MAX(Table1[TimeStamp]),FILTER(Table1, Table1[Index] = required_Index))
Var pre_result = IF(Get_Action_Type = "TERMINATING", DATEDIFF(Current_Action_TimeStamp, next_Action_TimeStamp,SECOND), BLANK())
Var result = IF(pre_result > 0, pre_result, BLANK())
return result
And if you cannot change it to a Date Time, then try this calculated column,
Difference_2 =
Var Get_Action_Type = Table1[ActionType]
Var required_Index_1 = Table1[Index] + 1
Var required_Index = IF(required_Index_1 > MAX(Table1[Index]),required_Index_1-1, required_Index_1)
Var Current_Action_TimeStamp = Table1[Time_Stamp_Number]
Var next_Action_TimeStamp = CALCULATE(MAX(Table1[Time_Stamp_Number]),FILTER(Table1, Table1[Index] = required_Index))
Var pre_result = IF(Get_Action_Type = "TERMINATING", next_Action_TimeStamp - Current_Action_TimeStamp, BLANK())
Var result = IF(pre_result > 0, pre_result, BLANK())
return result
The Output looks as below :-
Kindly accept the answer if it helps and do let me know, how it works for you.