Storing Pivots as a variables? Pine Script - variables

Is there any way to store let's say 5 latest pivots as variables?
There is a simple built-in indicator call Pivot H/L which finds pivots and places plot shapes near them. Is there a way to store them instead of plotting the plot shapes?

yes, you can. It's ugly code, but you can. Here, I show you as an example to do it for the current and last 2 pivot highs. You can extend as much as you want creating more variables in analogy to what is here.
If you're interested in the pivot lows, also just replicate everything to the low pivots.
The way it is shown here, you'll find:
ph0: the last found high pivot
ph1: the penultimate last found high pivot
ph2: the last found high pivot before ph1
This way, we keep (about) the same way we reference past elements of Series variables in Pine-script. Here the code:
//#version=4
study("Trend", overlay=false)
//INPUT VARIABLES
leftBars = input(3)
rightBars = input(3)
//INIT VARIABLES
var float ph_valid = 0
var float ph0 = 0
var float ph1 = 0
var float ph2 = 0
ph = pivothigh(high, leftBars, rightBars)
ph_non_na = nz(ph,0) // stores 0's instead of na's for non-pivot-pointed bars
// Assigns non-na values to pre-instantiated variables
if ph_non_na != 0
ph2 := ph1
ph1 := ph0
ph0 := ph_non_na
else
ph2 := ph2
ph1 := ph1
ph0 := ph0
plot(ph0)
plot(ph1)
plot(ph2)

Related

Is there any way to convert a portfolio class from portfolio analytics into a data frame

I'm trying to find the optimal weights for an especific target return using Portfolio Analytics library and ROI optimization; However, even that I know that that target return should be feasable and should be part of the efficient frontier, the ROI optimization does not find any solution.
The code that I'm using is the following:
for(i in 0:n){
target=minret+(i)*Del
p <- portfolio.spec(assets = colnames(t_EROAS)) #Specification of asset classes
p <- add.constraint(p, type = "full_investment") #An investment that has to sum 1
p <- add.constraint(portfolio=p, type="box", min=0, max=1) #No short position long-only
p <- add.constraint(p,
type="group",
groups=group_list,
group_min=VCONSMIN[,1],
group_max=VCONSMAX[,1])
p <- add.constraint(p, type = "return", name = "mean", return_target = target)
p <- add.objective(p, type="risk", name="var")
eff.opt <- optimize.portfolio(t_EROAS, p, optimize_method = "ROI",trace=TRUE)}
n=30 but is just finding 27 portfolios and the efficient frontier that I'm creating is looking empty from portfolio 27 to portfolio 30, the 28 and 29 seems to not have a solution but I'm not sure that this is correct.
What I want to have is an efficient frontier on a data frame format with a fixed number of portfolios, and it seems that the only way to achive this is by this method. Any help or any ideas that could help?

Pinescript index range

Is there a way to code an index range in pinescript? For example, If I want to include all close values between 10 bars and 5 bars ago. Everything between close[10] and close[5].
In python this would be close[5:10] but I cannot find any literature discussing a range of indexes.
thanks!
You could code a function to do that, but to be clear [] has a specific meaning in Pinescript as a history-referencing operator. I think what you are asking for is a way to construct an array of values from a series based on indicies.
This would work if you're use float values like OHLC
//#version=4
study("My Script")
range(_src, _a, _b) =>
_arr = array.new_float(0)
for i = _a to _b - 1
array.push(_arr, _src[i])
_arr
someCloses = range(close, 5, 10)
plot(array.size(someCloses))
But with this you are converting your data to a different type. So make sure to look at the available array functions.

How to get the lowest low of a series in PineScript

I'm trying to get the lowest low of a series of candles after a condition, but it always returns the last candle of the condition. I try with min(), lowest() and a for loop but it doesn't work. Also try using blackCandle[] and min(ThreeinARow)/lowest(ThreeinARow) and sometimes it returns the last candle and other times it gives me compilation error.
blackCandle = close < open
ThreeinARow = blackCandle[3] and blackCandle[2] and blackCandle[1]
SL = ThreeinARow ? min(low[1], low[2], low[3]) : na
//#version=4
study("Help (low after 3DownBar)", overlay=true, max_bars_back=100)
blackCandle = close < open
ThreeinARow = blackCandle[3] and blackCandle[2] and blackCandle[1]
bar_ind = barssince(ThreeinARow)
//SL = lowest(max(1, nz(bar_ind))) // the lowest low of a series of candles after the condition
SL = lowest(max(1, nz(bar_ind)+1)) // the lowest low of a series of candles since the condition
plot(SL, style=plot.style_cross, linewidth=3)
bgcolor(ThreeinARow ? color.silver : na)
See also the second solution which is in the commented line
It seems that I was misinterpreting it. Using min() does return the minimum of a series of candles. The detail is that I must enter the specific number of candles that I will use to calculate the minimum, which, for now, does not generate any problem for me. In the end, this is how I ended up writing it:
blackCandle = close < open
ThreeinARow = blackCandle[3] and blackCandle[2] and blackCandle[1]
Lowest_Low = if ThreeinARow
min(low[1], low[2], low[3])
plot(Lowest_Low, color=color.red)

How to make a new variable based on 30 other variables

I have 30 variables on family history of cancer i.e. breast cancer father, breast cancer mother, breast cancer sister etc. I would like to make a new variable and give it a value of "1" if in one of my columns there is a 1.
Thus:
I have 30 variables with answers 1 to 3; 1 is yes, 2 is no and, 3 is unknown if one of the 30 variables is given a 1 I would like my new variable to take on the value 1.
Does someone know how I can do this?
You can create a list instead of separate 30 variables and then filter it out to create a new variable. This will make it more dynamic.
// This will be the cancer history for a single family
var cancerHistory = [];
// Add dummy data
cancerHistory.push('yes');
cancerHistory.push('no')
cancerHistory.push('unknown');
cancerHistory.push('no');
// Check if at least one of them is "yes"
var hasHistoryOfCancer = cancerHistory.indexOf('yes') > -1;
alert(hasHistoryOfCancer); // true
You can use a for loop. You did not mention the language so I am writing the code in Python which is easy to understand. If you want it in other language you can use the similar approach and apply it
import pandas as pd
new_var = []
df = pd.read_csv("DataFile.csv") # Convert data file to csv and put name it.
for i in range(len(df)):
x = [df['column1'][i], df['column2'][i] ...., df['column30'][i]]
if (1 in x): new_var.append(1)
else: new_var.append(0)
df['new_var'] = new_var
df.to_csv('NewDataFile.csv', sep=',', encoding='utf-8')

Conditional formatting: max value, comparing rows with specific data

I am making an exercise tracking sheet with Google Sheets, and ran into a problem. The sheet has a table for raw data such as day, exercise type chosen from a validated list, and sets, reps, weight, you name it. To find the useful information for analysis, I have set up a pivot table. I want to find the max values for each type of value per exercise.
For example, comparing all the three instances of "DL-m BB" in column D, the table should highlight the highest values between all them: H9 would be the record weight, F5 record volume and so on, and for "SQ-lb BB box" H12 would be max weight and F3 max volume. Eventually the table will have several hundred rows per year, and finding max values per exercise per attribute is going to be too much of a task, time better spent elsewhere.
The Conditional Formatting can be set as follow for the two examples you give above. A separate rule is set for each. They are set from the same cell (H1) adding an additional rule.
Apply to Range
H1:H1000
Custom Formula is
=$H1=max(filter($D:$H,$D:$D="DL-m BB"))
Add another rule
Apply to Range
H1:H1000
Custom Formula is
=$H1=max(filter($D:$H,$D:$D="SQ-lb box BB"))
Place this on your Pivot table page (Try M1 - it must be outside of the PT)
It list max correctly.
=UNIQUE(query($D2:$K,"SELECT D,Max(F),Max(G),Max(H),Max(I),Max(J), Max(K) Where D !='' Group By D Label Max(F) 'Max F', Max(G) 'Max G', Max(H) 'Max H', Max(I) 'Max I',Max(J) 'Max J',Max(K) 'Max K'"))
The below query lists the max for F
=query($D2:$F,"SELECT Max(F) Where D !='' Group By D label Max(F)''")
I have been trying this with conditional formatting and it almost works. Maybe you will see something I don't. Still trying.
This works.
function onOpen(){
keepUnique()
}
function keepUnique(){ //create array og unique non black values to find max for
var col = 4 ; // choose the column you want to use as data source (0 indexed, it works at array level)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheets()[1];
var data = sh.getRange(2, col, sh.getLastRow()-2).getValues();
var newdata = new Array();
for(nn in data){
var duplicate = false;
for(j in newdata){
if(data[nn][0] == newdata[j][0] || data[nn][0]==""){
duplicate = true;
}
}
if(!duplicate){
newdata.push([data[nn][0]]);
}}
colorMax(newdata)
}
function colorMax(newdata){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheets()[1];
lc=sh.getLastColumn()
var data = sh.getRange(2, 4, sh.getLastRow()-2,lc).getValues(); //get col 4 to last col
for(k=2;k<lc;k++){
for(i=0;i<newdata.length;i++){
var maxVal=0
for(j=0;j<data.length;j++){
if(data[j][0]==newdata[i][0]){
if(data[j][k]>maxVal){maxVal=data[j][k];var row=j+2} //find max value and max value row number
}}
var c =sh.getRange(row,k+4,1,1)//get cell to format
var cv=c.getValue()
c.setFontColor("red") //set font red
}}
}