Я пытался воспроизвести довольно простой алгоритм для TradingView Pine Script. Я хочу построить график текущей максимальной просадки на основе количества периодов функции (например, 252 для годовой максимальной просадки). Функция должна вернуться через окно и найти самую высокую цену, затем cal c наименьшее изменение от планки. Это очень простой al go, но меня удивили странные результаты от TradingView. Я думаю, это потому, что l oop работает последовательно и, возможно, переключается на каждом проходе. В недоумении.
//@version=4
study(title="Rolling Max Drawdown", shorttitle="Rolling Max Drawdown", precision=6)
periods = input(title="periods", type=input.integer, defval=252)
// This "brute force" function produces a correct answer which we can use as a debugging baseline, but obviously we'd want a user-defined set of periods, e.g., 252 for annual rolling dropdown, which would be very brute force.
max_drawdown1() =>
dd0 = ((close[0] / highest(close[0], 5)) - 1)
dd1 = ((close[1] / highest(close[1], 4)) - 1)
dd2 = ((close[2] / highest(close[2], 3)) - 1)
dd3 = ((close[3] / highest(close[3], 2)) - 1)
dd4 = ((close[4] / highest(close[4], 1)) - 1)
max_dd = min(dd0, dd1, dd2, dd3, dd4)
[max_dd, dd0, dd1, dd2, dd3, dd4] //dd's returned for debugging purposes
max_drawdown2(bars) =>
// I thought it would be simple to convert above to a simple loop and then get the min value of the result, but a simple for i= loop didn't give me expected result
// Pine Script does not support arrays or lists, which would allow me to append each period's result and find the min() at the end.
var dd = 0.0
var max_dd = 999999.99
var dd0 = 0.0 // for debug
var dd1 = 0.0 // for debug
var dd2 = 0.0 // for debug
var dd3 = 0.0 // for debug
var dd4 = 0.0 // for debug
for i = 0 to (bars-1)
dd := ((close[i] / highest(close[i], bars-i )) - 1)
max_dd := min(max_dd, dd)
// For debugging, save values to display
dd0 := iff(i==0, dd, dd0)
dd1 := iff(i==1, dd, dd1)
dd2 := iff(i==2, dd, dd2)
dd3 := iff(i==3, dd, dd3)
dd4 := iff(i==4, dd, dd4)
[max_dd, dd0, dd1, dd2, dd3, dd4]
// Plot the correct result brute force version
[max1_dd, dd1_0, dd1_1, dd1_2, dd1_3, dd1_4] = max_drawdown1()
plot(max1_dd, color = color.blue, style = plot.style_line, linewidth = 1)
plotchar(max1_dd, 'max1_dd', '', location=location.top)
plotchar(dd1_0, 'dd1_0', '', location=location.top)
plotchar(dd1_1, 'dd1_1', '', location=location.top)
plotchar(dd1_2, 'dd1_2', '', location=location.top)
plotchar(dd1_3, 'dd1_3', '', location=location.top)
plotchar(dd1_4, 'dd1_4', '', location=location.top)
// Plot the erroneous loop version
[max2_dd, dd2_0, dd2_1, dd2_2, dd2_3, dd2_4] = max_drawdown2(5)
plot(max2_dd, color = color.green, style = plot.style_line, linewidth = 1)
plotchar(max2_dd, 'max2_dd', '', location=location.top)
plotchar(dd2_0, 'dd2_0', '', location=location.top)
plotchar(dd2_1, 'dd2_1', '', location=location.top)
plotchar(dd2_2, 'dd2_2', '', location=location.top)
plotchar(dd2_3, 'dd2_3', '', location=location.top)
plotchar(dd2_4, 'dd2_4', '', location=location.top)