3

I am trying to rewrite this code to Python:

src = input.source(close, "Source")
volStop(src) =>
    var max     = src
    var min     = src
    max         := math.max(max, src)
    min         := math.min(min, src)
    [max, min]

[max, min] = volStop(src)
plot(max, "Max", style=plot.style_cross)

Precisely I have a problem with these lines:

    max         := math.max(max, src)
    min         := math.min(min, src)

In Python I have a function, leta call it func1, and I want to get the same result the Pinescript is returning.

I have only tried for loop since from what I understand calling a function in Pinescript works kind of like for loop. And I tried to replicate the calculation but I couldn't achieve the expected results.

This is the line that is being plotted on Tradingview:

enter image description here

And this is the line that is being plotted in Python: the area that is framed with red square is the approximate area that is visible on Tradingview screenshot.

enter image description here

My current code:

maxmin = pd.DataFrame()
maxmin["max"] = price_df[f"{name_var}"]
maxmin["min"] = price_df[f"{name_var}"]
for i in range(price_df.shape[0]):
    maxmin["max"].iloc[i] = max(maxmin["max"].shift(1).fillna(0).iloc[i], price_df[f"{name_var}"].iloc[i])
    maxmin["min"].iloc[i] = min(maxmin["min"].shift(1).fillna(0).iloc[i], price_df[f"{name_var}"].iloc[i])

The name_var variable is set to 'Close' column.

How can I rewrite the Pinescript code to Python to get the same results?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    You can get the maximum value of a column in a single line: `price_df[name_var].max()`. Note that `f"{name_var}"` is just a silly way to write `name_var`. – Tim Roberts Jan 17 '23 at 19:01
  • But I do not want a single value from the whole column. The trick is I think that I do not fully understand how pinescript is being handled. The problem is that `price_df[name_var].max()` is going to give me a single value, that is not going to give the same values as pinescript. same with vectorized operation like this: `maxmin = max(maxmin.shift(1), source)` - note that this is pseudocode. As I said I think the problem is with how pinescript is being handling such code and I do not now how to interpret it correctly. – Jakub Szurlej Jan 17 '23 at 19:30
  • Can you provide sample data for src, and the pinescript output for ```max := math.max(max, src)``` and ```min := math.min(min, src)``` using the sample data? – itprorh66 Jan 17 '23 at 19:55
  • Is that pinescript code giving you the "max so far"? – Tim Roberts Jan 17 '23 at 22:05
  • @itprorh66 Sure! https://www.transfernow.net/dl/202301180nyA2Mib This is the link to csv file with data from tradingview which I use during development. But I can't provide you whole column of target value from pinescript since I don't have a premium subscribtion on tradingview anymore and I can't download the data. The only thing I can think of I could give you a couple of target values directly i.e. for a couple dates, or you would have to look at tradingview directly. – Jakub Szurlej Jan 18 '23 at 07:33
  • @itprorh66 Oh and do not compare target value for the last row for the data in csv fil this is 06/jan/2023 - 10:50:00 since the data from this time period is not closed i.e. when I downloaded the data the 5 minute period was still running, so data is not complete and it might give wrong output comparing to tradingview. – Jakub Szurlej Jan 18 '23 at 07:53

1 Answers1

3

Pine Script basically runs your code on every bar and store variables into a history (series). This is why you can access old data.

I think the problem here is you should give the same input data to get the same output. The calculation starts from the 1st available bar, where bar_index is 0. You can scroll to the left to see at which time the 1st bar is. Then your input data in python should be the same. Or you can restrict your Pine Script to start calculation like this:

start_time = input.time(timestamp("1 Jan 2023 00:00 +0000"), "Date")

// ...

volStop(src) =>
    var max = src
    var min = src
    if time >= start_time
        max := math.max(max, src)
        min := math.min(min, src)
        [max, min]
    else
        [na, na]

// ...
   

The python code doesn't need the shift and fillna. The input data should not have na at all, because you need the same data as on TradingView, which has no na. So the for cycle and the builtin max/min do the job:

for i in range(price_df.shape[0]):
    maxmin["max"].iloc[i] = max(maxmin["max"].iloc[i], price_df[f"{name_var}"].iloc[i])
    maxmin["min"].iloc[i] = min(maxmin["min"].iloc[i], price_df[f"{name_var}"].iloc[i])

But it is slow because of the iteration and value access one by one. You can use pandas methods here:

maxmin['max'] = price_df[name_var].cummax()
maxmin['min'] = price_df[name_var].cummin()
Adam Wallner
  • 2,292
  • 23
  • 20
  • Droping the data in python that is (now) invisible for me on tradingview worked- but it does not solve the problem completly. So basically to get the exact value that is on tradingview I would have to drop data in python when calculating? So summarizing is rewriting this line code to python and replicating the output in python is generally unachiavable? – Jakub Szurlej Jan 18 '23 at 08:30
  • @JakubSzurlej Edited my answer to include python code too. – Adam Wallner Jan 18 '23 at 09:25