Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hbs 0 stimofeev runner optimization stand #458

Open
wants to merge 25 commits into
base: nyc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a5149d5
HBS-0: input pine optimization to nyc copy
stimofeev-tv Feb 8, 2024
cfd9592
HBS-0: test optimize perf pine funcs
stimofeev-tv Feb 16, 2024
ed86e4f
HBS-0: test optimize perf pine funcs 2
stimofeev-tv Feb 16, 2024
fb7ce09
HBS-0: test optimize bond close pine
stimofeev-tv Feb 16, 2024
4783f6b
HBS-0: test optimize fastSearch pine
stimofeev-tv Feb 16, 2024
515dc95
HBS-0: test optimize fastSearch pine 2
stimofeev-tv Feb 16, 2024
d125771
HBS-0: revert 2 last commits (optimize fastSearch pine)
stimofeev-tv Feb 16, 2024
2f44a7c
HBS-0: optimize crypto perf pine (inlines)
stimofeev-tv Feb 16, 2024
3ef7b53
HBS-0: optimize custom highest and lowest pine
stimofeev-tv Feb 16, 2024
9b17ef3
HBS-0: optimize custom highest and lowest pine 2
stimofeev-tv Feb 16, 2024
86d77d9
HBS-0: revert optimize custom highest and lowest pine
stimofeev-tv Feb 16, 2024
e2db62f
HBS-0: upd pince scripts from nyc
stimofeev-tv Feb 16, 2024
b06ffea
HBS-0: upd perf market cap pine
stimofeev-tv Feb 19, 2024
bd4132e
HBS-0: optimize high and low func (attempt 3)
stimofeev-tv Feb 20, 2024
7fe63a4
HBS-0: change mbb to magic
stimofeev-tv Feb 21, 2024
639ff9f
Revert "HBS-0: change mbb to magic"
stimofeev-tv Feb 21, 2024
e6020a3
HBS-0: change mbb to magic for 24h volume pine
stimofeev-tv Feb 21, 2024
9002a5e
Revert "HBS-0: change mbb to magic for 24h volume pine"
stimofeev-tv Feb 21, 2024
df248d6
HBS-0: test fix custom high n low funcs
stimofeev-tv Feb 27, 2024
9d21676
improve rVolCalcSumVol
Feb 28, 2024
809c62c
HBS-0: revert improve rVolCalcSumBol
stimofeev-tv Mar 5, 2024
da9cfac
HBS-4111: test upd 24h vol pine
stimofeev-tv Mar 5, 2024
f336b2e
HBS-4111: fix new 24h vol pine
stimofeev-tv Mar 5, 2024
3fc4081
NOVA-0: upd pine
stimofeev-tv Mar 7, 2024
4c6a16f
NOVA-0: test add bond presets
stimofeev-tv May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions BEST_PRACTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Рекомендации по написанию эффективного кода на пайне

### По-возможности обращаться непосредственно к истории серий (`time`/`open`/`high`/`close`) вместо обращения к истории переменных или аргументов, в противном случае на каждый вызов функции будет выделен буфер в размере глубины обращения. В частности, если функция всегда вызывается с некоторыми одинаковыми параметрами, их следует инлайнить
```
fastSearchN(_xs, x, maxbarsback) => // xs - sorted, ascending
xs = _xs
if bar_index == 0
xs += xs[maxbarsback] * 0 // max_bars_back
left = 0
right = math.min(bar_index, maxbarsback)
mid = 0
if xs < x
0
else
for i = 0 to 9 by 1
mid := math.ceil((left + right) / 2)
if left == right
break
else if xs[mid] < x
right := mid
continue
else if xs[mid] > x
left := mid
continue
else
break
mid

countOfBars1DayAgoBond = fastSearchTimeIndex(dayAgoYield, dayYield)
countOfBars1MonthAgoBond = fastSearchTimeIndex(monthAgoYield, monthYield)
countOfBars1YearAgoBond = fastSearchTimeIndex(yearAgoYield, yearYield)
```
можно улучшить так
```
fastSearchTimeIndex(x, maxbarsback) =>
max_bars_back(time, maxbarsback)
left = 0
right = math.min(bar_index, maxbarsback)
mid = 0
if time < x
0
else
for i = 0 to 9 by 1
mid := math.ceil((left + right) / 2)
if left == right
break
else if time[mid] < x
right := mid
continue
else if time[mid] > x
left := mid
continue
else
break
mid

countOfBars1DayAgoBond = fastSearchTimeIndex(dayAgoYield, dayYield)
countOfBars1MonthAgoBond = fastSearchTimeIndex(monthAgoYield, monthYield)
countOfBars1YearAgoBond = fastSearchTimeIndex(yearAgoYield, yearYield)
```
### Рекомендуется схлопывать одинаковые секюрити в одну при помощи тюплов
```
fund_flows1M = request.security(makeFundFlowsTicker(), getFundTF(), sum(oneMonth), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
fund_flows3M = request.security(makeFundFlowsTicker(), getFundTF(), sum(threeMonths), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
fund_flows1Y = request.security(makeFundFlowsTicker(), getFundTF(), sum(oneYear), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
fund_flows3Y = request.security(makeFundFlowsTicker(), getFundTF(), sum(threeYears), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
fund_flows5Y = request.security(makeFundFlowsTicker(), getFundTF(), sum(fiveYears), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
fund_flowsYTD = request.security(makeFundFlowsTicker(), getFundTF(), sumYTD(), ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
```
стоит зарефакторить так
```
[fund_flows1M, fund_flows3M, fund_flows1Y, fund_flows3Y, fund_flows5Y, fund_flowsYTD] = request.security(fundFlowsTicker, fundTF, [sum(oneMonth), sum(threeMonths), sum(oneYear), sum(threeYears), sum(fiveYears), sumYTD()], ignore_invalid_symbol=true, gaps=barmerge.gaps_off)
```
### Следует переиспользовать вычиcления
```
plot(ta.rsi(close, 2), title='RSI2')
plot(ta.rsi(close, 2)[1], title='RSI2[1]')
```
нужно переписать так
```
RSI2 = ta.rsi(close, 2)
plot(RSI2, title='RSI2')
plot(RSI2[1], title='RSI2[1]')
```
### Стоит использовать `var` по назначению
```
pivotX_open = float(na)
pivotX_open := nz(pivotX_open[1], open)
```
можно упростить
```
var pivotX_open = open
```
### Если что-то можно посчитать 1 раз, то стоит это сделать и записать результат в var переменную. NB: если инициализируемое значение константа, то var не нужен
```
getFundTF() => timeframe.isintraday ? "1D" : timeframe.period
```
превратить в
```
var fundTF = timeframe.isintraday ? "D" : timeframe.period
```
### Эффективнее применять подход "вычислений по скользящему окну" вместо постоянного обхода в цикле
```
sumYTD()=>
max_bars_back(time, 2*oneYear)
max_bars_back(close, 2*oneYear)
var firstBar = time

if year(timenow, syminfo.timezone) == year(firstBar, syminfo.timezone)
na
else
sum = 0.
for i = 0 to bar_index
if year(time[i], syminfo.timezone) < year
break
sum += close[i]
sum
```
можно соптимизировать
```
sumYTD()=>
var startYear = year(time, syminfo.timezone)

if year(timenow, syminfo.timezone) == startYear
na
else
var sum = 0.
if year(time[1], syminfo.timezone) < year(time, syminfo.timezone)
sum := 0
sum += close
sum
```
### Инпуты в сканерных скриптах не нужны
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@


## Как обновлять код индикаторов
Для обновления скрипта индикатора, отредактируйте соответствующий .pine файл
Для добавления скрипта индикатора, добавьте соответствующий .pine файл
Для начала прочитать [рекомендации](BEST_PRACTICES.md)
Для обновления скрипта индикатора, отредактируйте соответствующий .pine файл
Для добавления скрипта индикатора, добавьте соответствующий .pine файл

После внесенных изменений, запустите утилиту pine_compiler (https://git.xtools.tv/tv/scanner/tree/master/pine_compiler):
```shell
Expand Down
55 changes: 25 additions & 30 deletions links/24h_volume.pine.link
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
// 24h volume
price = close
currency = "USD"
msIn24h = 24*60*60*1000
countOfFiveMinsInDay = 24*60/5
maxBufferSize = 2*countOfFiveMinsInDay
cumVolTF = "5"
cum24hVol(s) =>
src = s
if bar_index==0
src := src[maxBufferSize] * time[maxBufferSize] * 0
var cumSum = 0.
var int firstBarTimeIndex = na
if na(firstBarTimeIndex) // 24 H have not elapsed yet
sum = 0.
for i = 0 to countOfFiveMinsInDay
if (time - time[i]) >= msIn24h
firstBarTimeIndex := bar_index - i + 1
break
sum += src[i]
cumSum := sum
else
cumSum += nz(src)
for i = firstBarTimeIndex to bar_index
if (time - time[bar_index - i]) < msIn24h
firstBarTimeIndex := i
break
cumSum -= nz(src[bar_index - i])
if cumSum <= 0
cumSum := 0
cumSum
expr = syminfo.volumetype == "quote" ? volume : ( syminfo.volumetype == "base" ? price*volume : na )
vol24h = request.security(syminfo.tickerid, cumVolTF, cum24hVol(expr), lookahead = barmerge.lookahead_off, currency = currency, ignore_invalid_symbol=true)
sumVolTF = "5"
// rollOnTimeWhen is internal function from PineCoders/getSeries/1 library
rollOnTimeWhen(series float src, simple int timeWindow, series bool cond = true, simple int minBars = 1) =>
var float[] sources = array.new_float(0)
var int[] times = array.new_int(0)
if cond
array.push(sources, src)
array.push(times, time)
if array.size(sources) > 0
while time - array.get(times, 0) >= timeWindow and array.size(sources) > minBars
array.shift(sources)
array.shift(times)
float[] result = sources
sum24hVol(src) =>
sourceValues = rollOnTimeWhen(src, msIn24h)
sourceValues.sum()
var cumVol = 0.
cumVol += nz(volume)
expr = syminfo.volumetype == "quote" ? volume : close * volume
vol24h = request.security(syminfo.tickerid, sumVolTF, sum24hVol(expr * request.currency_rate(syminfo.currency, currency, ignore_invalid_currency = true)), ignore_invalid_symbol = true)
if barstate.islast
if syminfo.volumetype == "tick" and syminfo.type == "crypto" or cumVol == 0
vol24h := na
plot(vol24h, title = "24h_vol", style = plot.style_columns)

// volume in base and quote currencies
Expand All @@ -42,8 +37,8 @@ plot(volQuote, title = "volume_quote", style = plot.style_columns)
// 24h prev value (generic)
prev24hVal(source) =>
src = source
if bar_index == 0
src := src[maxBufferSize] * time[maxBufferSize] * 0
max_bars_back(src, maxBufferSize)
max_bars_back(time, maxBufferSize)
int BB24h = na
for i = 0 to countOfFiveMinsInDay
if (time - time[i]) >= msIn24h
Expand Down
17 changes: 7 additions & 10 deletions links/bond_close_days_back.pine.link
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ yearYield = 365
dayAgoYield = timenow - 1000 * 60 * 60 * 24 * dayYield
monthAgoYield = timenow - 1000 * 60 * 60 * 24 * monthYield
yearAgoYield = timenow - 1000 * 60 * 60 * 24 * yearYield
countOfBars1DayAgoBond = fastSearchN(time, dayAgoYield, dayYield)
countOfBars1MonthAgoBond = fastSearchN(time, monthAgoYield, monthYield)
countOfBars1YearAgoBond = fastSearchN(time, yearAgoYield, yearYield)
countOfBars1DayAgoBond = fastSearchTimeIndex(dayAgoYield, dayYield)
countOfBars1MonthAgoBond = fastSearchTimeIndex(monthAgoYield, monthYield)
countOfBars1YearAgoBond = fastSearchTimeIndex(yearAgoYield, yearYield)

series = close
if bar_index == 0
series += series[yearYield] * 0 // max_bars_back

plot(series[countOfBars1DayAgoBond], title="close_1_days_back")
plot(series[countOfBars1MonthAgoBond], title="close_30_days_back")
plot(series[countOfBars1YearAgoBond], title="close_365_days_back")
max_bars_back(close, yearYield)
plot(close[countOfBars1DayAgoBond], title="close_1_days_back")
plot(close[countOfBars1MonthAgoBond], title="close_30_days_back")
plot(close[countOfBars1YearAgoBond], title="close_365_days_back")
Loading
Loading