Conditional color of Table cell in pinescript v5 - pine-script-v5

I am looking to have a reference table of sorts for my tradingview set up. My aim is to compare 5 stock tickers, namely apple(AAPL), microsoft(MSFT), Amazon(AMZN), Google(GOOGL) and Tesla(TSLA). The data is current price, price change(from yesterday's) and percentage change.
Here is the screengrab of the table
https://prnt.sc/XzaN3fJjwuZz
What I am doing to do next is to color the cells based on the positive or negative changes. So if a change has been positive, the cell background becomes green, if negative, then red.
I tried using conditional logic but I am getting error: An argument of 'series color' type was used but a 'series int' is expected
I searched and could find only two questions in stackoverflow on this topic:
pine script error- An argument of 'series string' type was used but a 'const string' is expected
Converting series integer to integer in pinescript
However, I was not able to understand as to how to relate their answers to my case.
Here is the code snippet I am using to calculate the values:
pr_x2 = request.security(x1,"D", close[1])
pr_x1 = request.security(x1,"", close)
pr_diff = (pr_x1 - pr_x2)
pr_pct = truncate(((pr_diff1/pr_x2)*100),2)
where
pr_x2 -> previous day close
pr-x1 -> current value
I'm trying to use this condition for background in the cell:
table.cell(panel, 0, 1, str.tostring(pr_diff) + "\nChg: " + str.tostring(pr_pct1) + " %", bgcolor = (pr_diff>0)?color.green:color.red, text_color=color.white)
but then I get the error I have mentioned above.
I read in the discussions forum that converting series integer to integer in pinescript cannot be done. Is there a workaround for my case?
To admin: My apologies if it is similar to a previous thread, but I was not able to find it. It would be very kind of you to point me in the right direction.

You are trying on the cell, try applying on the array.
var = array.get(id) conditions ? Color.green :
array.get(id) conditions? Color.red

Related

How to run a pivot operation on a table selection within a ticker function in KDB+/Q

I am trying to run a pivot operation on a selection made within a ticker function as follows:
// Trades table
trades:(
[]time:`timespan$();
sym:`symbol$();
exch:`symbol$();
side:`symbol$();
price:`float$();
size:`float$());
// Generic pivot function
piv:{[t;k;p;v]f:{[v;P]`${raze "_" sv x} each string raze P,'/:v};v:(),v; k:(),k; p:(),p;G:group flip k!(t:.Q.v t)k;F:group flip p!t p;key[G]!flip(C:f[v]P:flip value flip key F)!raze{[i;j;k;x;y]a:count[x]#x 0N;a[y]:x y;b:count[x]#0b;b[y]:1b;c:a i;c[k]:first'[a[j]#'where'[b j]];c}[I[;0];I J;J:where 1<>count'[I:value G]]/:\:[t v;value F]};
// Ticker function that "ticks" every 5 seconds
if[not system"t";system"t 5000";
.z.ts:{
// Selection is made from the trades table with the index reset
trds:0!select first_price:first price, last_price:last price, mean_size:avg size, volume:sum size, min_price:min price, max_price:max price by time:1 xbar time.second, exch, sym from trades;
// Check if selection returns at least one row and run pivot
if[(count trds)>0; (
ptrds:piv[`trds;`time;`exch`sym;`first_price`last_price`mean_size`min_price`max_price`volume];
show ptrds;
)];
}];
However this does not function as the trds reference made in the pivot function is not picked up, presumably because the trds selection is not global, however whilst using trds (without) as a parameter the piv function somehow is not applied and returns the result as if no operation had been performed. In addition, having to create an additional variable with ptrds seems inneficcient and also throws a reference error. Could someone please advise me how I can go about implementing this logic in a canonical manner that is efficient. Thanks
I think the source of your error here is the () brackets in your final if statement. The problem is that, when multiple arguments are enclosed within brackets, the object becomes a list. In kdb, elements of a list are evaluated from right to left, e.g.
q)(a:10;a+15)
'a
[0] (a:10;a+15)
^
q)(a+15;a:10)
25 10
To solve your problem, simply remove the brackets such that it reads
if[(count trades)>0;ptrds:piv[...];show ptrds;]

SSRS Expression works as cell value expression, but not as background color value expression

I have an SSRS report with a matrix in it, where I needed to display the Growth Percentage in a column group compared to the previous column value. I managed this by using custom code...
DIM PreviousColValue AS Decimal
Dim RowName AS String = ""
Public Function GetPreviousColValue(byval Val as Decimal, byval rwName as string) as Decimal
DIM Local_PreviousColValue AS Decimal
IF RowName <> rwName THEN
RowName = rwName
PreviousColValue = val
Local_PreviousColValue = 0
ELSE
Local_PreviousColValue = (Val - PreviousColValue)/PreviousColValue
PreviousColValue = val
END IF
Return Local_PreviousColValue
End Function
..and then using this as the value expression in the cell..
=Round(Code.GetPreviousColValue(ReportItems!Textbox8.Value,Fields!BusinessUnit.Value)*100,0,system.MidpointRounding.AwayFromZero)
So far so good, this produces the expected value. Now I need to use this expression in a background color expression to get a red/yellow/green but in that capacity it fails.
The background color expression looks like this: =IIF(ROUND(Code.GetPreviousColValue(ReportItems!Textbox9.Value,Fields!Salesperson.Value)*100,0,System.MidpointRounding.AwayFromZero)<=-5,"Red"
,IIF(ROUND(Code.GetPreviousColValue(ReportItems!Textbox9.Value,Fields!Salesperson.Value)*100,0,System.MidpointRounding.AwayFromZero) >=5,"Green"
,"Yellow"))
When I run the report the background color expression only ever returns yellow. As a test I pasted the background color expression in as the cell value and ran it again. Results in the image below
I get no build or run time errors so I'm not sure why this does not work.
After some more searching I found a better Custom Code solution than what I was using to get the Growth Percentage in a column group compared to the previous column value. Besides being simpler to read this version has an added benefit: You can dynamically hide the growth percentage column for your first instance of the column group (because it will always be zero or null) and still get the right values in the 2nd/3rd/4th instance of the column group.
Public Function GetDeltaPercentage(ByVal PreviousValue, ByVal CurrentValue) As Object
If IsNothing(PreviousValue) OR IsNothing(CurrentValue) Then
Return Nothing
Else if PreviousValue = 0 OR CurrentValue = 0 Then
Return Nothing
Else
Return (CurrentValue - PreviousValue) / PreviousValue
End If
End Function
The new function is called like so
=Code.GetDeltaPercentage(Previous(Sum(<expression or dataset field>),"Group ByColumn"), Sum(<expression or dataset field>))
Re: the original question - why does my cell value expression not work when used as the background color expression - I took an easy out and just referenced the cell value.
=IIF(ROUND(Me.Value*100,0,System.MidpointRounding.AwayFromZero)<=-5,"Red"
,IIF(ROUND(Me.Value*100,0,System.MidpointRounding.AwayFromZero) >=5,"Green"
,"Yellow"))

Summing Only Visible Rows in SSRS

I'm trying to sum only the visible rows for a report and I know the format is:
=Sum( iif( <use the condition of the Visibility.Hidden expression>, 0, Fields!A.Value))
In my report, I've set row visbility to:
=IIF(CInt(Fields!EM_ET.Value)=1 Or CInt(Fields!EM_ET.Value)= 2,True,False)
Not exactly sure what I'm missing, but when I use this as an expression:
=Sum(IIF(CInt(Fields!EM_ET.Value)=1 Or CInt(Fields!EM_ET.Value)= 2,True,False),0,Fields!EM_ET.Value)
I get this following error: Value expression for textrun'FTD1.Paragraph[0].TextRuns[0]' has a scope argument that is not valid for aggregate function.
You are giving the True/False as output to the SUM() from your expression.You need to change your expression as,
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value)= 2,0,Fields!EM_ET.Value))
Thanks coder of code.
I am getting some error message if i am using '0', so i replaced with nothing it's working. I thought it would be helpful.
=SUM(IIF(ISNOTHING(Fields!value1.Value) OR ISNOTHING(Fields!value2.Value),NOTHING,Fields!value1.Value))
I was having similar issues. I know this question has a marked answer, however it isn't entirely correct.
The following contains the code from the "marked correct" answer:
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value) = 2,0,Fields!EM_ET.Value))
The following snipit of code contains the code from above, with a slight tweak:
=Sum(IIF(CInt(Fields!EM_ET.Value) = 1 Or CInt(Fields!EM_ET.Value) = 2,NOTHING,Fields!EM_ET.Value))
By changing the "0" to "NOTHING" this will resolve any lingering issues with your formula. The formula I was having issues with was returning "#Error" in the cell that was supposed to return the sum of the visible cells in the column within the row group.
My formula originally looked like this:
=IIF(Sum(Fields!VCBitType.Value) <> 0 OR (Parameters!Details.Value = "Detail"), Sum(IIF((Fields!VCBitType.Value = 0) and (Parameters!Details.Value = "Dangerous"),0,Fields!VC.Value)), "")
I altered my formula after seeing Hari's comment above:
=IIF(SUM(Fields!VCBitType.Value) <> 0 OR (Parameters!Details.Value = "Detail"), SUM(IIF((Fields!VCBitType.Value = 0) and (Parameters!Details.Value = "Dangerous"),NOTHING, Fields!VC.Value)), "")
I wanted to set the cells value to "" (empty) rather than hide the cell entirely or set that cell's value to "0" in my report (due to the fact that not displaying the cell entirely made the report look really funky). Because I did this, using a "0" in my formula conflicted with the value of the cell which was "" (empty), causing the formula to break. The only change I made was to alter "0" to "Nothing", this resolved the issue I was having with the cell's formula.

Why won't my factor column value change to a date value?

I know this is elementary but I can't seem to figure it out, even after reading other posts.
In a dataset, I want to convert an entire column into a date. The current class is factor.
The value in the field looks like this 12/25/2012
This is what I've tried.
C$DateofDeath=as.Date(C$DateofDeath,'%m/%d/%Y')
Error in as.Date.default(C$DateofDeath, "%m/%d/%Y") :
do not know how to convert 'C$DateofDeath' to class “Date”
C$DateofDeath=as.Date(C$DateofDeath,"%m/%d/%Y")
Error in as.Date.default(C$DateofDeath, "%m/%d/%Y") :
do not know how to convert 'C$DateofDeath' to class “Date”
Claims$DateofDeath=strptime(as.character(Claims$DateofDeath),format= '%m/%d/%Y')
Error in `$<-.data.frame`(`*tmp*`, "DateofDeath", value = list(sec = numeric(0), :
replacement has 0 rows, data has 71616
Claims$DateofDeath=strptime(as.character(Claims$DateofDeath),format= "%m/%d/%Y")
Error in `$<-.data.frame`(`*tmp*`, "DateofDeath", value = list(sec = numeric(0), :
replacement has 0 rows, data has 71616
Use as.POSIXct
C$DateOfDeath<-as.POSIXct(as.character(C$DateOfDeath), format = "%d/%m/%Y")
There are lots of R experts here but you have to specify R as one of your tags to get them to notice your question.
Looks like you have tried a bunch of combinations but not the right one.
> C <- data.frame(DateofDeath="12/25/2012",other=TRUE)
> as.Date(as.character(C$DateofDeath),format="%m/%d/%Y")
[1] "2012-12-25"
Notice that as.Date() takes a character input, not a factor. So you need to convert to character, then to Date.
Your strptime() versions seem fine to me except that you call are referring to the dataframe Claims instead of C. Actually strptime() should convert the factor to character for you, so you don't need the as.character() part with those.

Function equivalent to SUM() for multiplication in SQL Reporting

I'm looking for a function or solution to the following:
For the chart in SQL Reporting i need to multiply values from a Column A. For summation i would use =SUM(COLUMN_A) for the chart. But what can i use for multiplication - i was not able to find a solution so far?
Currently i am calculating the value of the stacked column as following:
=ROUND(SUM(Fields!Value_Is.Value)/SUM(Fields!StartValue.Value),3)
Instead of SUM i need something to multiply the values.
Something like that:
=ROUND(MULTIPLY(Fields!Value_Is.Value)/MULTIPLY(Fields!StartValue.Value),3)
EDIT #1
Okay tried to get this thing running.
The expression for the chart looks like this:
=Exp(Sum(Log(IIf(Fields!Menge_Ist.Value = 0, 10^-306, Fields!Menge_Ist.Value)))) / Exp(Sum(Log(IIf(Fields!Startmenge.Value = 0, 10^-306, Fields!Startmenge.Value))))
If i calculate my 'needs' manually i have to get the following result:
In my SQL Report i get the following result:
To make it easier, these are the raw values:
and you have the possibility to group the chart by CW, CQ or CY
(The values from the first pictures are aggregated Sum values from the raw values by FertStufe)
EDIT #2
Tried your expression, which results in this:
Just to make it clear:
The values in the column
=Value_IS / Start_Value
in the first picture are multiplied against each other
0,9947 x 1,0000 x 0,59401 = 0,58573
Diffusion Calenderweek 44 Sums
Startvalue: 1900,00 Value Is: 1890,00 == yield:0,99474
Waffer unbestrahlt Calenderweek 44 Sums
Startvalue: 620,00 Value Is: 620,00 == yield 1,0000
Pellet Calenderweek 44 Sums
Startvalue: 271,00 Value Is: 160,00 == yield 0,59041
yield Diffusion x yield Wafer x yield Pellet = needed Value in chart = 0,58730
EDIT #3
The raw values look like this:
The chart ist grouped - like in the image - on these fields
CY (Calendar year), CM (Calendar month), CW (Calendar week)
You can download the data as xls here:
https://www.dropbox.com/s/g0yrzo3330adgem/2013-01-17_data.xls
The expression i use (copy / past from the edit window)
=Exp(Sum(Log(Fields!Menge_Ist.Value / Fields!Startmenge.Value)))
I've exported the whole report result to excel, you can get it here:
https://www.dropbox.com/s/uogdh9ac2onuqh6/2013-01-17_report.xls
it's actually a workaround. But I am pretty sure is the only solution for this infamous problem :D
This is how I did:
Exp(∑(Log(X))), so what you should do is:
Exp(Sum(Log(Fields!YourField.Value)))
Who said math was worth nothing? =D
EDIT:
Corrected the formula.
By the way, it's tested.
Addressing Ian's concern:
Exp(Sum(Log(IIf(Fields!YourField.Value = 0, 10^-306, Fields!YourField.Value))))
The idea is change 0 with a very small number. Just an idea.
EDIT:
Based on your updated question this is what you should do:
Exp(Sum(Log(Fields!Value_IS.Value / Fields!Start_Value.Value)))
I just tested the above code and got the result you hoped for.