oakscriptjs 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +31 -9
- package/dist/cjs/array/index.d.ts +701 -0
- package/dist/cjs/array/index.d.ts.map +1 -0
- package/dist/cjs/array/index.js +392 -0
- package/dist/cjs/array/index.js.map +7 -0
- package/dist/cjs/box/index.d.ts +444 -0
- package/dist/cjs/box/index.d.ts.map +1 -0
- package/dist/cjs/box/index.js +246 -0
- package/dist/cjs/box/index.js.map +7 -0
- package/dist/cjs/callsite/index.d.ts +61 -0
- package/dist/cjs/callsite/index.d.ts.map +1 -0
- package/dist/cjs/callsite/index.js +65 -0
- package/dist/cjs/callsite/index.js.map +7 -0
- package/dist/cjs/chartpoint/index.d.ts +90 -0
- package/dist/cjs/chartpoint/index.d.ts.map +1 -0
- package/dist/cjs/chartpoint/index.js +56 -0
- package/dist/cjs/chartpoint/index.js.map +7 -0
- package/dist/cjs/color/index.d.ts +285 -0
- package/dist/cjs/color/index.d.ts.map +1 -0
- package/dist/cjs/color/index.js +143 -0
- package/dist/cjs/color/index.js.map +7 -0
- package/dist/cjs/compare/index.d.ts +26 -0
- package/dist/cjs/compare/index.d.ts.map +1 -0
- package/dist/cjs/compare/index.js +50 -0
- package/dist/cjs/compare/index.js.map +7 -0
- package/dist/cjs/drawing/registry.d.ts +42 -0
- package/dist/cjs/drawing/registry.d.ts.map +1 -0
- package/dist/cjs/drawing/registry.js +87 -0
- package/dist/cjs/drawing/registry.js.map +7 -0
- package/dist/cjs/index.d.ts +85 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +184 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/indicator.d.ts +117 -0
- package/dist/cjs/indicator.d.ts.map +1 -0
- package/dist/cjs/indicator.js +74 -0
- package/dist/cjs/indicator.js.map +7 -0
- package/dist/cjs/input.d.ts +196 -0
- package/dist/cjs/input.d.ts.map +1 -0
- package/dist/cjs/input.js +197 -0
- package/dist/cjs/input.js.map +7 -0
- package/dist/cjs/label/index.d.ts +303 -0
- package/dist/cjs/label/index.d.ts.map +1 -0
- package/dist/cjs/label/index.js +190 -0
- package/dist/cjs/label/index.js.map +7 -0
- package/dist/cjs/lib/index.d.ts +8 -0
- package/dist/cjs/lib/index.d.ts.map +1 -0
- package/dist/cjs/lib/index.js +19 -0
- package/dist/cjs/lib/index.js.map +7 -0
- package/dist/{lib → cjs/lib}/zigzag/index.d.ts +4 -1
- package/dist/cjs/lib/zigzag/index.d.ts.map +1 -0
- package/dist/cjs/lib/zigzag/index.js +27 -0
- package/dist/cjs/lib/zigzag/index.js.map +7 -0
- package/dist/cjs/lib/zigzag/zigzag.d.ts +100 -0
- package/dist/cjs/lib/zigzag/zigzag.d.ts.map +1 -0
- package/dist/cjs/lib/zigzag/zigzag.js +207 -0
- package/dist/cjs/lib/zigzag/zigzag.js.map +7 -0
- package/dist/cjs/line/index.d.ts +342 -0
- package/dist/cjs/line/index.d.ts.map +1 -0
- package/dist/cjs/line/index.js +193 -0
- package/dist/cjs/line/index.js.map +7 -0
- package/dist/cjs/linefill/index.d.ts +124 -0
- package/dist/cjs/linefill/index.d.ts.map +1 -0
- package/dist/cjs/linefill/index.js +56 -0
- package/dist/cjs/linefill/index.js.map +7 -0
- package/dist/cjs/map/index.d.ts +69 -0
- package/dist/cjs/map/index.d.ts.map +1 -0
- package/dist/cjs/map/index.js +80 -0
- package/dist/cjs/map/index.js.map +7 -0
- package/dist/cjs/math/index.d.ts +560 -0
- package/dist/cjs/math/index.d.ts.map +1 -0
- package/dist/cjs/math/index.js +441 -0
- package/dist/cjs/math/index.js.map +7 -0
- package/dist/cjs/matrix/index.d.ts +1231 -0
- package/dist/cjs/matrix/index.d.ts.map +1 -0
- package/dist/cjs/matrix/index.js +1200 -0
- package/dist/cjs/matrix/index.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/plot.d.ts +76 -0
- package/dist/cjs/plot.d.ts.map +1 -0
- package/dist/cjs/plot.js +51 -0
- package/dist/cjs/plot.js.map +7 -0
- package/dist/cjs/polyline/index.d.ts +115 -0
- package/dist/cjs/polyline/index.d.ts.map +1 -0
- package/dist/cjs/polyline/index.js +76 -0
- package/dist/cjs/polyline/index.js.map +7 -0
- package/dist/cjs/runtime/adapters/LightweightChartsAdapter.d.ts +86 -0
- package/dist/cjs/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
- package/dist/cjs/runtime/adapters/LightweightChartsAdapter.js +141 -0
- package/dist/cjs/runtime/adapters/LightweightChartsAdapter.js.map +7 -0
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.d.ts +59 -0
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js +117 -0
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js.map +7 -0
- package/dist/{runtime → cjs/runtime}/index.d.ts +12 -5
- package/dist/cjs/runtime/index.d.ts.map +1 -0
- package/dist/cjs/runtime/index.js +49 -0
- package/dist/cjs/runtime/index.js.map +7 -0
- package/dist/cjs/runtime/inputs.d.ts +91 -0
- package/dist/cjs/runtime/inputs.d.ts.map +1 -0
- package/dist/cjs/runtime/inputs.js +262 -0
- package/dist/cjs/runtime/inputs.js.map +7 -0
- package/dist/cjs/runtime/runtime.d.ts +70 -0
- package/dist/cjs/runtime/runtime.d.ts.map +1 -0
- package/dist/cjs/runtime/runtime.js +148 -0
- package/dist/cjs/runtime/runtime.js.map +7 -0
- package/dist/cjs/runtime/series.d.ts +362 -0
- package/dist/cjs/runtime/series.d.ts.map +1 -0
- package/dist/cjs/runtime/series.js +560 -0
- package/dist/cjs/runtime/series.js.map +7 -0
- package/dist/cjs/runtime/types.d.ts +282 -0
- package/dist/cjs/runtime/types.d.ts.map +1 -0
- package/dist/cjs/runtime/types.js +17 -0
- package/dist/cjs/runtime/types.js.map +7 -0
- package/dist/cjs/script/index.d.ts +987 -0
- package/dist/cjs/script/index.d.ts.map +1 -0
- package/dist/cjs/script/index.js +1169 -0
- package/dist/cjs/script/index.js.map +7 -0
- package/dist/cjs/security/resample.d.ts +63 -0
- package/dist/cjs/security/resample.d.ts.map +1 -0
- package/dist/cjs/security/resample.js +84 -0
- package/dist/cjs/security/resample.js.map +7 -0
- package/dist/cjs/session/bars.d.ts +80 -0
- package/dist/cjs/session/bars.d.ts.map +1 -0
- package/dist/cjs/session/bars.js +219 -0
- package/dist/cjs/session/bars.js.map +7 -0
- package/dist/cjs/session/calendar.d.ts +70 -0
- package/dist/cjs/session/calendar.d.ts.map +1 -0
- package/dist/cjs/session/calendar.js +164 -0
- package/dist/cjs/session/calendar.js.map +7 -0
- package/dist/cjs/str/dateformat.d.ts +15 -0
- package/dist/cjs/str/dateformat.d.ts.map +1 -0
- package/dist/cjs/str/dateformat.js +149 -0
- package/dist/cjs/str/dateformat.js.map +7 -0
- package/dist/cjs/str/index.d.ts +459 -0
- package/dist/cjs/str/index.d.ts.map +1 -0
- package/dist/cjs/str/index.js +143 -0
- package/dist/cjs/str/index.js.map +7 -0
- package/dist/cjs/str/messageformat.d.ts +14 -0
- package/dist/cjs/str/messageformat.d.ts.map +1 -0
- package/dist/cjs/str/messageformat.js +114 -0
- package/dist/cjs/str/messageformat.js.map +7 -0
- package/dist/cjs/str/numberformat.d.ts +19 -0
- package/dist/cjs/str/numberformat.d.ts.map +1 -0
- package/dist/cjs/str/numberformat.js +170 -0
- package/dist/cjs/str/numberformat.js.map +7 -0
- package/dist/{strategy → cjs/strategy}/index.d.ts +50 -0
- package/dist/cjs/strategy/index.d.ts.map +1 -0
- package/dist/cjs/strategy/index.js +92 -0
- package/dist/cjs/strategy/index.js.map +7 -0
- package/dist/cjs/ta/index.d.ts +1397 -0
- package/dist/cjs/ta/index.d.ts.map +1 -0
- package/dist/cjs/ta/index.js +1715 -0
- package/dist/cjs/ta/index.js.map +7 -0
- package/dist/cjs/ta/running-sum.d.ts +30 -0
- package/dist/cjs/ta/running-sum.d.ts.map +1 -0
- package/dist/cjs/ta/running-sum.js +99 -0
- package/dist/cjs/ta/running-sum.js.map +7 -0
- package/dist/cjs/ta-series.d.ts +558 -0
- package/dist/cjs/ta-series.d.ts.map +1 -0
- package/dist/cjs/ta-series.js +606 -0
- package/dist/cjs/ta-series.js.map +7 -0
- package/dist/cjs/text/index.d.ts +14 -0
- package/dist/cjs/text/index.d.ts.map +1 -0
- package/dist/cjs/text/index.js +29 -0
- package/dist/cjs/text/index.js.map +7 -0
- package/dist/cjs/time/datestring.d.ts +23 -0
- package/dist/cjs/time/datestring.d.ts.map +1 -0
- package/dist/cjs/time/datestring.js +106 -0
- package/dist/cjs/time/datestring.js.map +7 -0
- package/dist/cjs/time/index.d.ts +89 -0
- package/dist/cjs/time/index.d.ts.map +1 -0
- package/dist/cjs/time/index.js +85 -0
- package/dist/cjs/time/index.js.map +7 -0
- package/dist/cjs/time/session.d.ts +17 -0
- package/dist/cjs/time/session.d.ts.map +1 -0
- package/dist/cjs/time/session.js +65 -0
- package/dist/cjs/time/session.js.map +7 -0
- package/dist/cjs/time/timezone.d.ts +40 -0
- package/dist/cjs/time/timezone.d.ts.map +1 -0
- package/dist/cjs/time/timezone.js +125 -0
- package/dist/cjs/time/timezone.js.map +7 -0
- package/dist/cjs/timeframe/index.d.ts +73 -0
- package/dist/cjs/timeframe/index.d.ts.map +1 -0
- package/dist/cjs/timeframe/index.js +85 -0
- package/dist/cjs/timeframe/index.js.map +7 -0
- package/dist/cjs/types/index.d.ts +343 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +32 -0
- package/dist/cjs/types/index.js.map +7 -0
- package/dist/cjs/types/metadata.d.ts +300 -0
- package/dist/cjs/types/metadata.d.ts.map +1 -0
- package/dist/cjs/types/metadata.js +17 -0
- package/dist/cjs/types/metadata.js.map +7 -0
- package/dist/cjs/utils/index.d.ts +167 -0
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/cjs/utils/index.js +209 -0
- package/dist/cjs/utils/index.js.map +7 -0
- package/dist/esm/array/index.d.ts +701 -0
- package/dist/esm/array/index.d.ts.map +1 -0
- package/dist/esm/array/index.js +983 -0
- package/dist/esm/array/index.js.map +1 -0
- package/dist/esm/box/index.d.ts +444 -0
- package/dist/esm/box/index.d.ts.map +1 -0
- package/dist/esm/box/index.js +602 -0
- package/dist/esm/box/index.js.map +1 -0
- package/dist/esm/callsite/index.d.ts +61 -0
- package/dist/esm/callsite/index.d.ts.map +1 -0
- package/dist/esm/callsite/index.js +97 -0
- package/dist/esm/callsite/index.js.map +1 -0
- package/dist/esm/chartpoint/index.d.ts +90 -0
- package/dist/esm/chartpoint/index.d.ts.map +1 -0
- package/dist/esm/chartpoint/index.js +113 -0
- package/dist/esm/chartpoint/index.js.map +1 -0
- package/dist/esm/color/index.d.ts +285 -0
- package/dist/esm/color/index.d.ts.map +1 -0
- package/dist/esm/color/index.js +373 -0
- package/dist/esm/color/index.js.map +1 -0
- package/dist/esm/compare/index.d.ts +26 -0
- package/dist/esm/compare/index.d.ts.map +1 -0
- package/dist/esm/compare/index.js +39 -0
- package/dist/esm/compare/index.js.map +1 -0
- package/dist/esm/drawing/registry.d.ts +42 -0
- package/dist/esm/drawing/registry.d.ts.map +1 -0
- package/dist/esm/drawing/registry.js +89 -0
- package/dist/esm/drawing/registry.js.map +1 -0
- package/dist/esm/index.d.ts +85 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +96 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/indicator.d.ts +117 -0
- package/dist/esm/indicator.d.ts.map +1 -0
- package/dist/esm/indicator.js +84 -0
- package/dist/esm/indicator.js.map +1 -0
- package/dist/esm/input.d.ts +196 -0
- package/dist/esm/input.d.ts.map +1 -0
- package/dist/esm/input.js +183 -0
- package/dist/esm/input.js.map +1 -0
- package/dist/esm/label/index.d.ts +303 -0
- package/dist/esm/label/index.d.ts.map +1 -0
- package/dist/esm/label/index.js +417 -0
- package/dist/esm/label/index.js.map +1 -0
- package/dist/esm/lib/index.d.ts +8 -0
- package/dist/esm/lib/index.d.ts.map +1 -0
- package/dist/esm/lib/index.js +8 -0
- package/dist/esm/lib/index.js.map +1 -0
- package/dist/esm/lib/zigzag/index.d.ts +5 -0
- package/dist/esm/lib/zigzag/index.d.ts.map +1 -0
- package/dist/esm/lib/zigzag/index.js +5 -0
- package/dist/esm/lib/zigzag/index.js.map +1 -0
- package/dist/esm/lib/zigzag/zigzag.d.ts +100 -0
- package/dist/esm/lib/zigzag/zigzag.d.ts.map +1 -0
- package/dist/esm/lib/zigzag/zigzag.js +229 -0
- package/dist/esm/lib/zigzag/zigzag.js.map +1 -0
- package/dist/esm/line/index.d.ts +342 -0
- package/dist/esm/line/index.d.ts.map +1 -0
- package/dist/esm/line/index.js +470 -0
- package/dist/esm/line/index.js.map +1 -0
- package/dist/esm/linefill/index.d.ts +124 -0
- package/dist/esm/linefill/index.d.ts.map +1 -0
- package/dist/esm/linefill/index.js +144 -0
- package/dist/esm/linefill/index.js.map +1 -0
- package/dist/esm/map/index.d.ts +69 -0
- package/dist/esm/map/index.d.ts.map +1 -0
- package/dist/esm/map/index.js +106 -0
- package/dist/esm/map/index.js.map +1 -0
- package/dist/esm/math/index.d.ts +560 -0
- package/dist/esm/math/index.d.ts.map +1 -0
- package/dist/esm/math/index.js +495 -0
- package/dist/esm/math/index.js.map +1 -0
- package/dist/esm/matrix/index.d.ts +1231 -0
- package/dist/esm/matrix/index.d.ts.map +1 -0
- package/dist/esm/matrix/index.js +2450 -0
- package/dist/esm/matrix/index.js.map +1 -0
- package/dist/esm/plot.d.ts +76 -0
- package/dist/esm/plot.d.ts.map +1 -0
- package/dist/esm/plot.js +63 -0
- package/dist/esm/plot.js.map +1 -0
- package/dist/esm/polyline/index.d.ts +115 -0
- package/dist/esm/polyline/index.d.ts.map +1 -0
- package/dist/esm/polyline/index.js +157 -0
- package/dist/esm/polyline/index.js.map +1 -0
- package/dist/esm/runtime/adapters/LightweightChartsAdapter.d.ts +86 -0
- package/dist/esm/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
- package/dist/esm/runtime/adapters/LightweightChartsAdapter.js +140 -0
- package/dist/esm/runtime/adapters/LightweightChartsAdapter.js.map +1 -0
- package/dist/esm/runtime/adapters/SimpleInputAdapter.d.ts +59 -0
- package/dist/esm/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js +115 -0
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js.map +1 -0
- package/dist/esm/runtime/index.d.ts +13 -0
- package/dist/esm/runtime/index.d.ts.map +1 -0
- package/dist/esm/runtime/index.js +14 -0
- package/dist/esm/runtime/index.js.map +1 -0
- package/dist/esm/runtime/inputs.d.ts +91 -0
- package/dist/esm/runtime/inputs.d.ts.map +1 -0
- package/dist/esm/runtime/inputs.js +334 -0
- package/dist/esm/runtime/inputs.js.map +1 -0
- package/dist/esm/runtime/runtime.d.ts +70 -0
- package/dist/esm/runtime/runtime.d.ts.map +1 -0
- package/dist/esm/runtime/runtime.js +193 -0
- package/dist/esm/runtime/runtime.js.map +1 -0
- package/dist/esm/runtime/series.d.ts +362 -0
- package/dist/esm/runtime/series.d.ts.map +1 -0
- package/dist/esm/runtime/series.js +583 -0
- package/dist/esm/runtime/series.js.map +1 -0
- package/dist/esm/runtime/types.d.ts +282 -0
- package/dist/esm/runtime/types.d.ts.map +1 -0
- package/dist/esm/runtime/types.js +7 -0
- package/dist/esm/runtime/types.js.map +1 -0
- package/dist/esm/script/index.d.ts +987 -0
- package/dist/esm/script/index.d.ts.map +1 -0
- package/dist/esm/script/index.js +1289 -0
- package/dist/esm/script/index.js.map +1 -0
- package/dist/esm/security/resample.d.ts +63 -0
- package/dist/esm/security/resample.d.ts.map +1 -0
- package/dist/esm/security/resample.js +110 -0
- package/dist/esm/security/resample.js.map +1 -0
- package/dist/esm/session/bars.d.ts +80 -0
- package/dist/esm/session/bars.d.ts.map +1 -0
- package/dist/esm/session/bars.js +232 -0
- package/dist/esm/session/bars.js.map +1 -0
- package/dist/esm/session/calendar.d.ts +70 -0
- package/dist/esm/session/calendar.d.ts.map +1 -0
- package/dist/esm/session/calendar.js +172 -0
- package/dist/esm/session/calendar.js.map +1 -0
- package/dist/esm/str/dateformat.d.ts +15 -0
- package/dist/esm/str/dateformat.d.ts.map +1 -0
- package/dist/esm/str/dateformat.js +136 -0
- package/dist/esm/str/dateformat.js.map +1 -0
- package/dist/esm/str/index.d.ts +459 -0
- package/dist/esm/str/index.d.ts.map +1 -0
- package/dist/esm/str/index.js +540 -0
- package/dist/esm/str/index.js.map +1 -0
- package/dist/esm/str/messageformat.d.ts +14 -0
- package/dist/esm/str/messageformat.d.ts.map +1 -0
- package/dist/esm/str/messageformat.js +111 -0
- package/dist/esm/str/messageformat.js.map +1 -0
- package/dist/esm/str/numberformat.d.ts +19 -0
- package/dist/esm/str/numberformat.d.ts.map +1 -0
- package/dist/esm/str/numberformat.js +189 -0
- package/dist/esm/str/numberformat.js.map +1 -0
- package/dist/esm/strategy/index.d.ts +245 -0
- package/dist/esm/strategy/index.d.ts.map +1 -0
- package/dist/esm/strategy/index.js +84 -0
- package/dist/esm/strategy/index.js.map +1 -0
- package/dist/esm/ta/index.d.ts +1397 -0
- package/dist/esm/ta/index.d.ts.map +1 -0
- package/dist/esm/ta/index.js +3227 -0
- package/dist/esm/ta/index.js.map +1 -0
- package/dist/esm/ta/running-sum.d.ts +30 -0
- package/dist/esm/ta/running-sum.d.ts.map +1 -0
- package/dist/esm/ta/running-sum.js +113 -0
- package/dist/esm/ta/running-sum.js.map +1 -0
- package/dist/esm/ta-series.d.ts +558 -0
- package/dist/esm/ta-series.d.ts.map +1 -0
- package/dist/esm/ta-series.js +910 -0
- package/dist/esm/ta-series.js.map +1 -0
- package/dist/esm/text/index.d.ts +14 -0
- package/dist/esm/text/index.d.ts.map +1 -0
- package/dist/esm/text/index.js +14 -0
- package/dist/esm/text/index.js.map +1 -0
- package/dist/esm/time/datestring.d.ts +23 -0
- package/dist/esm/time/datestring.d.ts.map +1 -0
- package/dist/esm/time/datestring.js +94 -0
- package/dist/esm/time/datestring.js.map +1 -0
- package/dist/esm/time/index.d.ts +89 -0
- package/dist/esm/time/index.d.ts.map +1 -0
- package/dist/esm/time/index.js +108 -0
- package/dist/esm/time/index.js.map +1 -0
- package/dist/esm/time/session.d.ts +17 -0
- package/dist/esm/time/session.d.ts.map +1 -0
- package/dist/esm/time/session.js +69 -0
- package/dist/esm/time/session.js.map +1 -0
- package/dist/esm/time/timezone.d.ts +40 -0
- package/dist/esm/time/timezone.d.ts.map +1 -0
- package/dist/esm/time/timezone.js +144 -0
- package/dist/esm/time/timezone.js.map +1 -0
- package/dist/esm/timeframe/index.d.ts +73 -0
- package/dist/esm/timeframe/index.d.ts.map +1 -0
- package/dist/esm/timeframe/index.js +131 -0
- package/dist/esm/timeframe/index.js.map +1 -0
- package/dist/esm/types/index.d.ts +343 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +17 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/metadata.d.ts +300 -0
- package/dist/esm/types/metadata.d.ts.map +1 -0
- package/dist/esm/types/metadata.js +7 -0
- package/dist/esm/types/metadata.js.map +1 -0
- package/dist/esm/utils/index.d.ts +167 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +295 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/package.json +53 -23
- package/src/array/index.ts +1056 -0
- package/src/box/index.ts +680 -0
- package/src/callsite/index.ts +104 -0
- package/src/chartpoint/index.ts +126 -0
- package/src/color/index.ts +411 -0
- package/src/compare/index.ts +46 -0
- package/src/drawing/registry.ts +106 -0
- package/src/index.ts +201 -0
- package/src/indicator.ts +185 -0
- package/src/input.ts +280 -0
- package/src/label/index.ts +490 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/zigzag/index.ts +13 -0
- package/src/lib/zigzag/zigzag.ts +318 -0
- package/src/line/index.ts +530 -0
- package/src/linefill/index.ts +152 -0
- package/src/map/index.ts +115 -0
- package/src/math/index.ts +1071 -0
- package/src/matrix/index.ts +2697 -0
- package/src/plot.ts +121 -0
- package/src/polyline/index.ts +184 -0
- package/src/runtime/adapters/LightweightChartsAdapter.ts +201 -0
- package/src/runtime/adapters/SimpleInputAdapter.ts +132 -0
- package/src/runtime/index.ts +52 -0
- package/src/runtime/inputs.ts +377 -0
- package/src/runtime/runtime.ts +241 -0
- package/src/runtime/series.ts +644 -0
- package/src/runtime/types.ts +292 -0
- package/src/script/index.ts +1865 -0
- package/src/security/resample.ts +119 -0
- package/src/session/bars.ts +262 -0
- package/src/session/calendar.ts +199 -0
- package/src/str/dateformat.ts +104 -0
- package/src/str/index.ts +557 -0
- package/src/str/messageformat.ts +109 -0
- package/src/str/numberformat.ts +197 -0
- package/src/strategy/index.ts +281 -0
- package/src/ta/index.ts +3580 -0
- package/src/ta/running-sum.ts +117 -0
- package/src/ta-series.ts +1036 -0
- package/src/text/index.ts +14 -0
- package/src/time/datestring.ts +96 -0
- package/src/time/index.ts +161 -0
- package/src/time/session.ts +79 -0
- package/src/time/timezone.ts +180 -0
- package/src/timeframe/index.ts +144 -0
- package/src/types/index.ts +398 -0
- package/src/types/metadata.ts +334 -0
- package/src/utils/index.ts +334 -0
- package/dist/array/index.d.ts +0 -57
- package/dist/array/index.d.ts.map +0 -1
- package/dist/box/index.d.ts +0 -37
- package/dist/box/index.d.ts.map +0 -1
- package/dist/callsite/index.d.ts +0 -7
- package/dist/callsite/index.d.ts.map +0 -1
- package/dist/chartpoint/index.d.ts +0 -8
- package/dist/chartpoint/index.d.ts.map +0 -1
- package/dist/color/index.d.ts +0 -28
- package/dist/color/index.d.ts.map +0 -1
- package/dist/compare/index.d.ts +0 -8
- package/dist/compare/index.d.ts.map +0 -1
- package/dist/drawing/registry.d.ts +0 -19
- package/dist/drawing/registry.d.ts.map +0 -1
- package/dist/index.cjs +0 -7979
- package/dist/index.d.ts +0 -64
- package/dist/index.d.ts.map +0 -1
- package/dist/index.mjs +0 -7962
- package/dist/indicator.d.ts +0 -42
- package/dist/indicator.d.ts.map +0 -1
- package/dist/input.d.ts +0 -47
- package/dist/input.d.ts.map +0 -1
- package/dist/label/index.d.ts +0 -30
- package/dist/label/index.d.ts.map +0 -1
- package/dist/lib/index.d.ts +0 -2
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/zigzag/index.d.ts.map +0 -1
- package/dist/lib/zigzag/zigzag.d.ts +0 -47
- package/dist/lib/zigzag/zigzag.d.ts.map +0 -1
- package/dist/line/index.d.ts +0 -30
- package/dist/line/index.d.ts.map +0 -1
- package/dist/linefill/index.d.ts +0 -10
- package/dist/linefill/index.d.ts.map +0 -1
- package/dist/map/index.d.ts +0 -14
- package/dist/map/index.d.ts.map +0 -1
- package/dist/math/index.d.ts +0 -53
- package/dist/math/index.d.ts.map +0 -1
- package/dist/matrix/index.d.ts +0 -52
- package/dist/matrix/index.d.ts.map +0 -1
- package/dist/plot.d.ts +0 -20
- package/dist/plot.d.ts.map +0 -1
- package/dist/polyline/index.d.ts +0 -11
- package/dist/polyline/index.d.ts.map +0 -1
- package/dist/runtime/adapters/LightweightChartsAdapter.d.ts +0 -15
- package/dist/runtime/adapters/LightweightChartsAdapter.d.ts.map +0 -1
- package/dist/runtime/adapters/SimpleInputAdapter.d.ts +0 -16
- package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +0 -1
- package/dist/runtime/index.cjs +0 -600
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.mjs +0 -577
- package/dist/runtime/inputs.d.ts +0 -13
- package/dist/runtime/inputs.d.ts.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -16
- package/dist/runtime/runtime.d.ts.map +0 -1
- package/dist/runtime/series.d.ts +0 -60
- package/dist/runtime/series.d.ts.map +0 -1
- package/dist/runtime/types.d.ts +0 -122
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/script/index.cjs +0 -6372
- package/dist/script/index.d.ts +0 -709
- package/dist/script/index.d.ts.map +0 -1
- package/dist/script/index.mjs +0 -6355
- package/dist/security/resample.d.ts +0 -13
- package/dist/security/resample.d.ts.map +0 -1
- package/dist/session/bars.d.ts +0 -34
- package/dist/session/bars.d.ts.map +0 -1
- package/dist/session/calendar.d.ts +0 -31
- package/dist/session/calendar.d.ts.map +0 -1
- package/dist/str/dateformat.d.ts +0 -2
- package/dist/str/dateformat.d.ts.map +0 -1
- package/dist/str/index.d.ts +0 -24
- package/dist/str/index.d.ts.map +0 -1
- package/dist/str/messageformat.d.ts +0 -2
- package/dist/str/messageformat.d.ts.map +0 -1
- package/dist/str/numberformat.d.ts +0 -3
- package/dist/str/numberformat.d.ts.map +0 -1
- package/dist/strategy/index.d.ts.map +0 -1
- package/dist/ta/index.d.ts +0 -72
- package/dist/ta/index.d.ts.map +0 -1
- package/dist/ta-series.d.ts +0 -143
- package/dist/ta-series.d.ts.map +0 -1
- package/dist/text/index.d.ts +0 -4
- package/dist/text/index.d.ts.map +0 -1
- package/dist/time/datestring.d.ts +0 -2
- package/dist/time/datestring.d.ts.map +0 -1
- package/dist/time/index.d.ts +0 -15
- package/dist/time/index.d.ts.map +0 -1
- package/dist/time/session.d.ts +0 -2
- package/dist/time/session.d.ts.map +0 -1
- package/dist/time/timezone.d.ts +0 -13
- package/dist/time/timezone.d.ts.map +0 -1
- package/dist/timeframe/index.d.ts +0 -17
- package/dist/timeframe/index.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -181
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/metadata.d.ts +0 -131
- package/dist/types/metadata.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -26
- package/dist/utils/index.d.ts.map +0 -1
|
@@ -0,0 +1,1715 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var ta_exports = {};
|
|
20
|
+
__export(ta_exports, {
|
|
21
|
+
accdist: () => accdist,
|
|
22
|
+
alma: () => alma,
|
|
23
|
+
atr: () => atr,
|
|
24
|
+
barssince: () => barssince,
|
|
25
|
+
bb: () => bb,
|
|
26
|
+
bbw: () => bbw,
|
|
27
|
+
cci: () => cci,
|
|
28
|
+
change: () => change,
|
|
29
|
+
cmo: () => cmo,
|
|
30
|
+
cog: () => cog,
|
|
31
|
+
correlation: () => correlation,
|
|
32
|
+
cross: () => cross,
|
|
33
|
+
crossover: () => crossover,
|
|
34
|
+
crossunder: () => crossunder,
|
|
35
|
+
cum: () => cum,
|
|
36
|
+
dev: () => dev,
|
|
37
|
+
dmi: () => dmi,
|
|
38
|
+
ema: () => ema,
|
|
39
|
+
falling: () => falling,
|
|
40
|
+
highest: () => highest,
|
|
41
|
+
highestbars: () => highestbars,
|
|
42
|
+
hma: () => hma,
|
|
43
|
+
ichimoku: () => ichimoku,
|
|
44
|
+
iii: () => iii,
|
|
45
|
+
kc: () => kc,
|
|
46
|
+
kcw: () => kcw,
|
|
47
|
+
linreg: () => linreg,
|
|
48
|
+
lowest: () => lowest,
|
|
49
|
+
lowestbars: () => lowestbars,
|
|
50
|
+
macd: () => macd,
|
|
51
|
+
max: () => max,
|
|
52
|
+
median: () => median,
|
|
53
|
+
mfi: () => mfi,
|
|
54
|
+
min: () => min,
|
|
55
|
+
mode: () => mode,
|
|
56
|
+
mom: () => mom,
|
|
57
|
+
nvi: () => nvi,
|
|
58
|
+
obv: () => obv,
|
|
59
|
+
percentile_linear_interpolation: () => percentile_linear_interpolation,
|
|
60
|
+
percentile_nearest_rank: () => percentile_nearest_rank,
|
|
61
|
+
percentrank: () => percentrank,
|
|
62
|
+
pivot_point_levels: () => pivot_point_levels,
|
|
63
|
+
pivothigh: () => pivothigh,
|
|
64
|
+
pivotlow: () => pivotlow,
|
|
65
|
+
pvi: () => pvi,
|
|
66
|
+
pvt: () => pvt,
|
|
67
|
+
range: () => range,
|
|
68
|
+
rci: () => rci,
|
|
69
|
+
rising: () => rising,
|
|
70
|
+
rma: () => rma,
|
|
71
|
+
roc: () => roc,
|
|
72
|
+
rsi: () => rsi,
|
|
73
|
+
sar: () => sar,
|
|
74
|
+
sma: () => sma,
|
|
75
|
+
stdev: () => stdev,
|
|
76
|
+
stoch: () => stoch,
|
|
77
|
+
supertrend: () => supertrend,
|
|
78
|
+
swma: () => swma,
|
|
79
|
+
tr: () => tr,
|
|
80
|
+
tsi: () => tsi,
|
|
81
|
+
valuewhen: () => valuewhen,
|
|
82
|
+
variance: () => variance,
|
|
83
|
+
vwap: () => vwap,
|
|
84
|
+
vwma: () => vwma,
|
|
85
|
+
wad: () => wad,
|
|
86
|
+
wma: () => wma,
|
|
87
|
+
wpr: () => wpr,
|
|
88
|
+
wvad: () => wvad,
|
|
89
|
+
zigzag: () => zigzag
|
|
90
|
+
});
|
|
91
|
+
module.exports = __toCommonJS(ta_exports);
|
|
92
|
+
var import_compare = require("../compare/index.js");
|
|
93
|
+
var import_running_sum = require("./running-sum.js");
|
|
94
|
+
function sma(source, length) {
|
|
95
|
+
const len = Math.floor(length);
|
|
96
|
+
return (0, import_running_sum.runningSum)(source, len).map((sum) => sum / len);
|
|
97
|
+
}
|
|
98
|
+
function strictWindowMean(source, length) {
|
|
99
|
+
const len = Math.floor(length);
|
|
100
|
+
return Array.from({ length: source.length }, (_, i) => {
|
|
101
|
+
if (i < len - 1) return NaN;
|
|
102
|
+
let sum = 0;
|
|
103
|
+
for (let j = 0; j < len; j++) sum += source[i - j];
|
|
104
|
+
return sum / len;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function ema(source, length) {
|
|
108
|
+
const result = [];
|
|
109
|
+
const len = Math.floor(length);
|
|
110
|
+
const multiplier = 2 / (len + 1);
|
|
111
|
+
let firstValidIndex = -1;
|
|
112
|
+
let validCount = 0;
|
|
113
|
+
let initSum = 0;
|
|
114
|
+
for (let i = 0; i < source.length; i++) {
|
|
115
|
+
const val = source[i];
|
|
116
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
117
|
+
initSum += val;
|
|
118
|
+
validCount++;
|
|
119
|
+
if (validCount === len) {
|
|
120
|
+
firstValidIndex = i;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let emaValue = validCount > 0 ? initSum / validCount : NaN;
|
|
126
|
+
const emaInitialized = firstValidIndex >= 0;
|
|
127
|
+
for (let i = 0; i < source.length; i++) {
|
|
128
|
+
if (!emaInitialized || i < firstValidIndex) {
|
|
129
|
+
result.push(NaN);
|
|
130
|
+
} else if (i === firstValidIndex) {
|
|
131
|
+
result.push(emaValue);
|
|
132
|
+
} else {
|
|
133
|
+
const val = source[i];
|
|
134
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
135
|
+
emaValue = (val - emaValue) * multiplier + emaValue;
|
|
136
|
+
result.push(emaValue);
|
|
137
|
+
} else {
|
|
138
|
+
result.push(NaN);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function rsi(source, length) {
|
|
145
|
+
const result = [];
|
|
146
|
+
const changes = [];
|
|
147
|
+
for (let i = 1; i < source.length; i++) {
|
|
148
|
+
changes.push(source[i] - source[i - 1]);
|
|
149
|
+
}
|
|
150
|
+
const gains = changes.map((c) => Number.isNaN(c) ? NaN : c > 0 ? c : 0);
|
|
151
|
+
const losses = changes.map((c) => Number.isNaN(c) ? NaN : c < 0 ? -c : 0);
|
|
152
|
+
const avgGains = rma(gains, length);
|
|
153
|
+
const avgLosses = rma(losses, length);
|
|
154
|
+
result.push(NaN);
|
|
155
|
+
for (let i = 0; i < avgGains.length; i++) {
|
|
156
|
+
if (avgLosses[i] === 0) {
|
|
157
|
+
result.push(100);
|
|
158
|
+
} else {
|
|
159
|
+
const rs = avgGains[i] / avgLosses[i];
|
|
160
|
+
result.push(100 - 100 / (1 + rs));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
function macd(source, fastLength, slowLength, signalLength) {
|
|
166
|
+
const fastEma = ema(source, fastLength);
|
|
167
|
+
const slowEma = ema(source, slowLength);
|
|
168
|
+
const macdLine = [];
|
|
169
|
+
for (let i = 0; i < source.length; i++) {
|
|
170
|
+
macdLine.push(fastEma[i] - slowEma[i]);
|
|
171
|
+
}
|
|
172
|
+
const signalLine = ema(macdLine, signalLength);
|
|
173
|
+
const histogram = [];
|
|
174
|
+
for (let i = 0; i < source.length; i++) {
|
|
175
|
+
histogram.push(macdLine[i] - signalLine[i]);
|
|
176
|
+
}
|
|
177
|
+
return [macdLine, signalLine, histogram];
|
|
178
|
+
}
|
|
179
|
+
function bb(series, length, mult) {
|
|
180
|
+
const basis = sma(series, length);
|
|
181
|
+
const dev2 = stdev(series, length);
|
|
182
|
+
const upper = [];
|
|
183
|
+
const lower = [];
|
|
184
|
+
for (let i = 0; i < series.length; i++) {
|
|
185
|
+
upper.push(basis[i] + mult * dev2[i]);
|
|
186
|
+
lower.push(basis[i] - mult * dev2[i]);
|
|
187
|
+
}
|
|
188
|
+
return [basis, upper, lower];
|
|
189
|
+
}
|
|
190
|
+
function stdev(source, length, biased = true) {
|
|
191
|
+
return variance(source, length, biased).map((v) => Number.isNaN(v) ? NaN : v > 0 ? Math.sqrt(v) : 0);
|
|
192
|
+
}
|
|
193
|
+
function lastValues(source, i, length) {
|
|
194
|
+
const values = [];
|
|
195
|
+
for (let j = i; j >= 0 && values.length < length; j--) {
|
|
196
|
+
const x = source[j];
|
|
197
|
+
if (!Number.isNaN(x)) values.push(x);
|
|
198
|
+
}
|
|
199
|
+
return values.length === length ? values : null;
|
|
200
|
+
}
|
|
201
|
+
function windowExtremes(source, length, lowest2) {
|
|
202
|
+
const n = source.length;
|
|
203
|
+
const span = length > 0 ? Math.ceil(length) : 0;
|
|
204
|
+
const at = new Int32Array(n).fill(-1);
|
|
205
|
+
const zeros = new Uint8Array(n);
|
|
206
|
+
const queue = new Int32Array(n);
|
|
207
|
+
const preferredZero = lowest2 ? -0 : 0;
|
|
208
|
+
let head = 0;
|
|
209
|
+
let tail = 0;
|
|
210
|
+
let zeroCount = 0;
|
|
211
|
+
let lastNa = -1;
|
|
212
|
+
const isPreferredZero = (k) => Object.is(source[k], preferredZero);
|
|
213
|
+
for (let i = 0; i < n; i++) {
|
|
214
|
+
const x = source[i];
|
|
215
|
+
if (Number.isNaN(x)) {
|
|
216
|
+
lastNa = i;
|
|
217
|
+
head = tail = 0;
|
|
218
|
+
zeroCount = 0;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
while (tail > head && (lowest2 ? source[queue[tail - 1]] > x : source[queue[tail - 1]] < x)) {
|
|
222
|
+
if (isPreferredZero(queue[--tail])) zeroCount--;
|
|
223
|
+
}
|
|
224
|
+
queue[tail++] = i;
|
|
225
|
+
if (isPreferredZero(i)) zeroCount++;
|
|
226
|
+
const start = Math.max(i - span + 1, lastNa + 1);
|
|
227
|
+
while (head < tail && queue[head] < start) {
|
|
228
|
+
if (isPreferredZero(queue[head++])) zeroCount--;
|
|
229
|
+
}
|
|
230
|
+
if (head < tail) {
|
|
231
|
+
at[i] = queue[head];
|
|
232
|
+
zeros[i] = zeroCount > 0 ? 1 : 0;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return { at, zeros };
|
|
236
|
+
}
|
|
237
|
+
function extremeOffset(source, length, lowest2) {
|
|
238
|
+
const { at } = windowExtremes(source, length, lowest2);
|
|
239
|
+
return source.map((_, i) => i < length - 1 ? NaN : at[i] < 0 ? 0 : -(i - at[i]));
|
|
240
|
+
}
|
|
241
|
+
function extremeValue(source, length, lowest2) {
|
|
242
|
+
const { at, zeros } = windowExtremes(source, length, lowest2);
|
|
243
|
+
return source.map((_, i) => {
|
|
244
|
+
if (i < length - 1 || at[i] < 0) return NaN;
|
|
245
|
+
const v = source[at[i]];
|
|
246
|
+
return v === 0 && zeros[i] ? lowest2 ? -0 : 0 : v;
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
function crossover(series1, series2) {
|
|
250
|
+
const result = [];
|
|
251
|
+
for (let i = 0; i < series1.length; i++) {
|
|
252
|
+
if (i === 0) {
|
|
253
|
+
result.push(false);
|
|
254
|
+
} else {
|
|
255
|
+
result.push(series1[i] > series2[i] && series1[i - 1] <= series2[i - 1]);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
function crossunder(series1, series2) {
|
|
261
|
+
const result = [];
|
|
262
|
+
for (let i = 0; i < series1.length; i++) {
|
|
263
|
+
if (i === 0) {
|
|
264
|
+
result.push(false);
|
|
265
|
+
} else {
|
|
266
|
+
result.push(series1[i] < series2[i] && series1[i - 1] >= series2[i - 1]);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
function change(source, length = 1) {
|
|
272
|
+
const result = [];
|
|
273
|
+
for (let i = 0; i < source.length; i++) {
|
|
274
|
+
if (i < length) {
|
|
275
|
+
result.push(NaN);
|
|
276
|
+
} else {
|
|
277
|
+
result.push(source[i] - source[i - length]);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
function tr(handle_na = false, high, low, close) {
|
|
283
|
+
if (!high || !low || !close) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
"ta.tr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
const result = [];
|
|
289
|
+
for (let i = 0; i < high.length; i++) {
|
|
290
|
+
if (i === 0) {
|
|
291
|
+
result.push(handle_na ? high[i] - low[i] : NaN);
|
|
292
|
+
} else {
|
|
293
|
+
const prevClose = close[i - 1];
|
|
294
|
+
if (isNaN(prevClose)) {
|
|
295
|
+
if (handle_na) {
|
|
296
|
+
result.push(high[i] - low[i]);
|
|
297
|
+
} else {
|
|
298
|
+
result.push(NaN);
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
const tr2 = Math.max(
|
|
302
|
+
high[i] - low[i],
|
|
303
|
+
Math.abs(high[i] - prevClose),
|
|
304
|
+
Math.abs(low[i] - prevClose)
|
|
305
|
+
);
|
|
306
|
+
result.push(tr2);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
function atr(length, high, low, close) {
|
|
313
|
+
if (!high || !low || !close) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
"ta.atr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
const trueRange = tr(true, high, low, close);
|
|
319
|
+
return rma(trueRange, length);
|
|
320
|
+
}
|
|
321
|
+
function supertrend(factor, atrPeriod, high, low, close, wicks = false) {
|
|
322
|
+
if (!high || !low || !close) {
|
|
323
|
+
throw new Error(
|
|
324
|
+
"ta.supertrend() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
const supertrendValues = [];
|
|
328
|
+
const directions = [];
|
|
329
|
+
const source = [];
|
|
330
|
+
for (let i = 0; i < high.length; i++) {
|
|
331
|
+
source.push((high[i] + low[i]) / 2);
|
|
332
|
+
}
|
|
333
|
+
const atrValues = atr(atrPeriod, high, low, close);
|
|
334
|
+
let prevLowerBand = NaN;
|
|
335
|
+
let prevUpperBand = NaN;
|
|
336
|
+
let prevSuperTrend = NaN;
|
|
337
|
+
for (let i = 0; i < source.length; i++) {
|
|
338
|
+
const atrValue = atrValues[i] * factor;
|
|
339
|
+
if (isNaN(atrValue)) {
|
|
340
|
+
supertrendValues.push(NaN);
|
|
341
|
+
directions.push(1);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
let upperBand = source[i] + atrValue;
|
|
345
|
+
let lowerBand = source[i] - atrValue;
|
|
346
|
+
const highPrice = wicks ? high[i] : close[i];
|
|
347
|
+
const lowPrice = wicks ? low[i] : close[i];
|
|
348
|
+
const prevLowPrice = i > 0 ? wicks ? low[i - 1] : close[i - 1] : 0;
|
|
349
|
+
const prevHighPrice = i > 0 ? wicks ? high[i - 1] : close[i - 1] : 0;
|
|
350
|
+
if (i > 0 && !isNaN(prevLowerBand) && !isNaN(prevUpperBand)) {
|
|
351
|
+
lowerBand = lowerBand > prevLowerBand || prevLowPrice < prevLowerBand ? lowerBand : prevLowerBand;
|
|
352
|
+
upperBand = upperBand < prevUpperBand || prevHighPrice > prevUpperBand ? upperBand : prevUpperBand;
|
|
353
|
+
}
|
|
354
|
+
let currentDirection;
|
|
355
|
+
if (isNaN(prevSuperTrend)) {
|
|
356
|
+
currentDirection = 1;
|
|
357
|
+
} else if (prevSuperTrend === prevUpperBand) {
|
|
358
|
+
currentDirection = highPrice > upperBand ? -1 : 1;
|
|
359
|
+
} else {
|
|
360
|
+
currentDirection = lowPrice < lowerBand ? 1 : -1;
|
|
361
|
+
}
|
|
362
|
+
const superTrendValue = currentDirection === -1 ? lowerBand : upperBand;
|
|
363
|
+
supertrendValues.push(superTrendValue);
|
|
364
|
+
directions.push(currentDirection);
|
|
365
|
+
prevLowerBand = lowerBand;
|
|
366
|
+
prevUpperBand = upperBand;
|
|
367
|
+
prevSuperTrend = superTrendValue;
|
|
368
|
+
}
|
|
369
|
+
return [supertrendValues, directions];
|
|
370
|
+
}
|
|
371
|
+
function rma(source, length) {
|
|
372
|
+
const result = [];
|
|
373
|
+
const len = Math.floor(length);
|
|
374
|
+
let firstValidIndex = -1;
|
|
375
|
+
let validCount = 0;
|
|
376
|
+
let initSum = 0;
|
|
377
|
+
for (let i = 0; i < source.length; i++) {
|
|
378
|
+
const val = source[i];
|
|
379
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
380
|
+
initSum += val;
|
|
381
|
+
validCount++;
|
|
382
|
+
if (validCount === len) {
|
|
383
|
+
firstValidIndex = i;
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
let rmaValue = validCount > 0 ? initSum / validCount : NaN;
|
|
389
|
+
const rmaInitialized = firstValidIndex >= 0;
|
|
390
|
+
for (let i = 0; i < source.length; i++) {
|
|
391
|
+
if (!rmaInitialized || i < firstValidIndex) {
|
|
392
|
+
result.push(NaN);
|
|
393
|
+
} else if (i === firstValidIndex) {
|
|
394
|
+
result.push(rmaValue);
|
|
395
|
+
} else {
|
|
396
|
+
const val = source[i];
|
|
397
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
398
|
+
rmaValue = (val + (len - 1) * rmaValue) / len;
|
|
399
|
+
result.push(rmaValue);
|
|
400
|
+
} else {
|
|
401
|
+
result.push(NaN);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
function wma(source, length) {
|
|
408
|
+
const result = [];
|
|
409
|
+
const len = Math.floor(length);
|
|
410
|
+
const filled = [];
|
|
411
|
+
let last = NaN;
|
|
412
|
+
let count = 0;
|
|
413
|
+
for (let i = 0; i < source.length; i++) {
|
|
414
|
+
const v = source[i];
|
|
415
|
+
const isNa = v === void 0 || v === null || !Number.isFinite(v);
|
|
416
|
+
if (!isNa) {
|
|
417
|
+
last = v;
|
|
418
|
+
count++;
|
|
419
|
+
}
|
|
420
|
+
filled.push(last);
|
|
421
|
+
if (isNa || count < len) {
|
|
422
|
+
result.push(NaN);
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
let sum = 0;
|
|
426
|
+
let weightSum = 0;
|
|
427
|
+
for (let j = len - 1; j >= 0; j--) {
|
|
428
|
+
const weight = len - j;
|
|
429
|
+
sum += filled[i - j] * weight;
|
|
430
|
+
weightSum += weight;
|
|
431
|
+
}
|
|
432
|
+
result.push(sum / weightSum);
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
function highest(source, length) {
|
|
437
|
+
return extremeValue(source, length, false);
|
|
438
|
+
}
|
|
439
|
+
function lowest(source, length) {
|
|
440
|
+
return extremeValue(source, length, true);
|
|
441
|
+
}
|
|
442
|
+
function cum(source) {
|
|
443
|
+
let sum = 0;
|
|
444
|
+
return source.map((v) => {
|
|
445
|
+
if (!Number.isFinite(v)) return NaN;
|
|
446
|
+
sum += v;
|
|
447
|
+
return sum;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
function cross(source1, source2) {
|
|
451
|
+
const result = [];
|
|
452
|
+
for (let i = 0; i < source1.length; i++) {
|
|
453
|
+
if (i === 0) {
|
|
454
|
+
result.push(false);
|
|
455
|
+
} else {
|
|
456
|
+
const crossedUp = source1[i] > source2[i] && source1[i - 1] <= source2[i - 1];
|
|
457
|
+
const crossedDown = source1[i] < source2[i] && source1[i - 1] >= source2[i - 1];
|
|
458
|
+
result.push(crossedUp || crossedDown);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return result;
|
|
462
|
+
}
|
|
463
|
+
function monotonic(source, length, step) {
|
|
464
|
+
const result = [];
|
|
465
|
+
const values = [];
|
|
466
|
+
for (let i = 0; i < source.length; i++) {
|
|
467
|
+
const v = source[i];
|
|
468
|
+
if (!Number.isNaN(v)) values.push(v);
|
|
469
|
+
const n = values.length;
|
|
470
|
+
let ok = n > length;
|
|
471
|
+
for (let j = 1; ok && j <= length; j++) ok = step(values[n - j], values[n - j - 1]);
|
|
472
|
+
result.push(ok);
|
|
473
|
+
}
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
function rising(source, length) {
|
|
477
|
+
return monotonic(source, length, import_compare.gt);
|
|
478
|
+
}
|
|
479
|
+
function falling(source, length) {
|
|
480
|
+
return monotonic(source, length, import_compare.lt);
|
|
481
|
+
}
|
|
482
|
+
function roc(source, length) {
|
|
483
|
+
const result = [];
|
|
484
|
+
for (let i = 0; i < source.length; i++) {
|
|
485
|
+
if (i < length) {
|
|
486
|
+
result.push(NaN);
|
|
487
|
+
} else {
|
|
488
|
+
const oldValue = source[i - length];
|
|
489
|
+
if (oldValue === 0 || isNaN(oldValue) || isNaN(source[i])) {
|
|
490
|
+
result.push(NaN);
|
|
491
|
+
} else {
|
|
492
|
+
const changeValue = source[i] - oldValue;
|
|
493
|
+
result.push(100 * changeValue / oldValue);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
function mom(source, length) {
|
|
500
|
+
const result = [];
|
|
501
|
+
for (let i = 0; i < source.length; i++) {
|
|
502
|
+
if (i < length) {
|
|
503
|
+
result.push(NaN);
|
|
504
|
+
} else {
|
|
505
|
+
if (isNaN(source[i]) || isNaN(source[i - length])) {
|
|
506
|
+
result.push(NaN);
|
|
507
|
+
} else {
|
|
508
|
+
result.push(source[i] - source[i - length]);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return result;
|
|
513
|
+
}
|
|
514
|
+
function dev(source, length) {
|
|
515
|
+
const result = [];
|
|
516
|
+
const meanValues = strictWindowMean(source, length);
|
|
517
|
+
for (let i = 0; i < source.length; i++) {
|
|
518
|
+
if (i < length - 1 || isNaN(meanValues[i])) {
|
|
519
|
+
result.push(NaN);
|
|
520
|
+
} else {
|
|
521
|
+
let sum = 0;
|
|
522
|
+
for (let j = 0; j < length; j++) {
|
|
523
|
+
if (!isNaN(source[i - j])) {
|
|
524
|
+
sum += Math.abs(source[i - j] - meanValues[i]);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
result.push(sum / length);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return result;
|
|
531
|
+
}
|
|
532
|
+
function variance(source, length, biased = true) {
|
|
533
|
+
const len = Math.floor(length);
|
|
534
|
+
if ((biased ? len : len - 1) <= 0) return source.map(() => NaN);
|
|
535
|
+
return (0, import_running_sum.runningVariance)(source, len, biased);
|
|
536
|
+
}
|
|
537
|
+
function median(source, length) {
|
|
538
|
+
const len = Math.floor(length);
|
|
539
|
+
const n = source.length;
|
|
540
|
+
const out = new Array(n).fill(NaN);
|
|
541
|
+
if (!(len >= 1)) return out;
|
|
542
|
+
const sorted = [];
|
|
543
|
+
const kept = new Float64Array(n);
|
|
544
|
+
let count = 0;
|
|
545
|
+
const bound = (v, after) => {
|
|
546
|
+
let lo = 0;
|
|
547
|
+
let hi = sorted.length;
|
|
548
|
+
while (lo < hi) {
|
|
549
|
+
const m = lo + hi >> 1;
|
|
550
|
+
if (after ? sorted[m] <= v : sorted[m] < v) lo = m + 1;
|
|
551
|
+
else hi = m;
|
|
552
|
+
}
|
|
553
|
+
return lo;
|
|
554
|
+
};
|
|
555
|
+
const mid = Math.floor(len / 2);
|
|
556
|
+
for (let i = 0; i < n; i++) {
|
|
557
|
+
const x = source[i];
|
|
558
|
+
if (!Number.isNaN(x)) {
|
|
559
|
+
kept[count++] = x;
|
|
560
|
+
sorted.splice(bound(x, false), 0, x);
|
|
561
|
+
if (count > len) sorted.splice(bound(kept[count - 1 - len], true) - 1, 1);
|
|
562
|
+
}
|
|
563
|
+
if (count >= len) out[i] = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
564
|
+
}
|
|
565
|
+
return out;
|
|
566
|
+
}
|
|
567
|
+
function swma(source) {
|
|
568
|
+
const result = [];
|
|
569
|
+
for (let i = 0; i < source.length; i++) {
|
|
570
|
+
if (i < 3) {
|
|
571
|
+
result.push(NaN);
|
|
572
|
+
} else {
|
|
573
|
+
if (isNaN(source[i]) || isNaN(source[i - 1]) || isNaN(source[i - 2]) || isNaN(source[i - 3])) {
|
|
574
|
+
result.push(NaN);
|
|
575
|
+
} else {
|
|
576
|
+
const value = source[i - 3] * (1 / 6) + source[i - 2] * (2 / 6) + source[i - 1] * (2 / 6) + source[i] * (1 / 6);
|
|
577
|
+
result.push(value);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
function vwma(source, length, volume) {
|
|
584
|
+
if (!volume) {
|
|
585
|
+
throw new Error(
|
|
586
|
+
"ta.vwma() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
const sourceTimesVolume = [];
|
|
590
|
+
for (let i = 0; i < source.length; i++) {
|
|
591
|
+
sourceTimesVolume.push(source[i] * volume[i]);
|
|
592
|
+
}
|
|
593
|
+
const numerator = sma(sourceTimesVolume, length);
|
|
594
|
+
const denominator = sma(volume, length);
|
|
595
|
+
const result = [];
|
|
596
|
+
for (let i = 0; i < source.length; i++) {
|
|
597
|
+
if (denominator[i] === 0 || isNaN(denominator[i])) {
|
|
598
|
+
result.push(NaN);
|
|
599
|
+
} else {
|
|
600
|
+
result.push(numerator[i] / denominator[i]);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return result;
|
|
604
|
+
}
|
|
605
|
+
function linreg(source, length, offset = 0) {
|
|
606
|
+
const result = [];
|
|
607
|
+
const len = Math.floor(length);
|
|
608
|
+
for (let i = 0; i < source.length; i++) {
|
|
609
|
+
if (i < len - 1) {
|
|
610
|
+
result.push(NaN);
|
|
611
|
+
} else {
|
|
612
|
+
let hasNaN = false;
|
|
613
|
+
for (let j = 0; j < len; j++) {
|
|
614
|
+
if (isNaN(source[i - j])) {
|
|
615
|
+
hasNaN = true;
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (hasNaN) {
|
|
620
|
+
result.push(NaN);
|
|
621
|
+
} else {
|
|
622
|
+
let sumX = 0;
|
|
623
|
+
let sumY = 0;
|
|
624
|
+
let sumXY = 0;
|
|
625
|
+
let sumX2 = 0;
|
|
626
|
+
for (let j = 0; j < len; j++) {
|
|
627
|
+
const x2 = j;
|
|
628
|
+
const y = source[i - (len - 1 - j)];
|
|
629
|
+
sumX += x2;
|
|
630
|
+
sumY += y;
|
|
631
|
+
sumXY += x2 * y;
|
|
632
|
+
sumX2 += x2 * x2;
|
|
633
|
+
}
|
|
634
|
+
const slope = (len * sumXY - sumX * sumY) / (len * sumX2 - sumX * sumX);
|
|
635
|
+
const intercept = (sumY - slope * sumX) / len;
|
|
636
|
+
const x = len - 1 - offset;
|
|
637
|
+
result.push(intercept + slope * x);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
function correlation(source1, source2, length) {
|
|
644
|
+
const result = [];
|
|
645
|
+
const span = length > 0 ? Math.ceil(length) : 0;
|
|
646
|
+
const a = new Float64Array(span);
|
|
647
|
+
const b = new Float64Array(span);
|
|
648
|
+
for (let i = 0; i < source1.length; i++) {
|
|
649
|
+
if (i < length - 1) {
|
|
650
|
+
result.push(NaN);
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
let m = 0;
|
|
654
|
+
for (let j = 0; j < length; j++) {
|
|
655
|
+
const v1 = source1[i - j];
|
|
656
|
+
const v2 = source2[i - j];
|
|
657
|
+
if (!isNaN(v1) && !isNaN(v2)) {
|
|
658
|
+
a[m] = v1;
|
|
659
|
+
b[m] = v2;
|
|
660
|
+
m++;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (m === 0) {
|
|
664
|
+
result.push(NaN);
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
let sum1 = 0;
|
|
668
|
+
let sum2 = 0;
|
|
669
|
+
for (let k = 0; k < m; k++) {
|
|
670
|
+
sum1 += a[k];
|
|
671
|
+
sum2 += b[k];
|
|
672
|
+
}
|
|
673
|
+
const mean1 = sum1 / m;
|
|
674
|
+
const mean2 = sum2 / m;
|
|
675
|
+
let numerator = 0;
|
|
676
|
+
let sum1Sq = 0;
|
|
677
|
+
let sum2Sq = 0;
|
|
678
|
+
for (let k = 0; k < m; k++) {
|
|
679
|
+
const dev1 = a[k] - mean1;
|
|
680
|
+
const dev2 = b[k] - mean2;
|
|
681
|
+
numerator += dev1 * dev2;
|
|
682
|
+
sum1Sq += dev1 * dev1;
|
|
683
|
+
sum2Sq += dev2 * dev2;
|
|
684
|
+
}
|
|
685
|
+
const denominator = Math.sqrt(sum1Sq * sum2Sq);
|
|
686
|
+
result.push(denominator === 0 ? NaN : numerator / denominator);
|
|
687
|
+
}
|
|
688
|
+
return result;
|
|
689
|
+
}
|
|
690
|
+
function percentrank(source, length) {
|
|
691
|
+
const result = [];
|
|
692
|
+
for (let i = 0; i < source.length; i++) {
|
|
693
|
+
const currentValue = source[i];
|
|
694
|
+
if (i < length || Number.isNaN(currentValue)) {
|
|
695
|
+
result.push(NaN);
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
let countLessOrEqual = 0;
|
|
699
|
+
for (let j = 1; j <= length; j++) {
|
|
700
|
+
if ((0, import_compare.le)(source[i - j], currentValue)) countLessOrEqual++;
|
|
701
|
+
}
|
|
702
|
+
result.push(countLessOrEqual / length * 100);
|
|
703
|
+
}
|
|
704
|
+
return result;
|
|
705
|
+
}
|
|
706
|
+
function cci(source, length) {
|
|
707
|
+
const result = [];
|
|
708
|
+
const smaValues = sma(source, length);
|
|
709
|
+
const devValues = dev(source, length);
|
|
710
|
+
for (let i = 0; i < source.length; i++) {
|
|
711
|
+
if (isNaN(smaValues[i]) || isNaN(devValues[i]) || devValues[i] === 0) {
|
|
712
|
+
result.push(NaN);
|
|
713
|
+
} else {
|
|
714
|
+
const cci2 = (source[i] - smaValues[i]) / (0.015 * devValues[i]);
|
|
715
|
+
result.push(cci2);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return result;
|
|
719
|
+
}
|
|
720
|
+
function stoch(source, high, low, length) {
|
|
721
|
+
const result = [];
|
|
722
|
+
const lowestValues = lowest(low, length);
|
|
723
|
+
const highestValues = highest(high, length);
|
|
724
|
+
for (let i = 0; i < source.length; i++) {
|
|
725
|
+
if (isNaN(lowestValues[i]) || isNaN(highestValues[i])) {
|
|
726
|
+
result.push(NaN);
|
|
727
|
+
} else {
|
|
728
|
+
const range2 = highestValues[i] - lowestValues[i];
|
|
729
|
+
if (range2 === 0) {
|
|
730
|
+
result.push(NaN);
|
|
731
|
+
} else {
|
|
732
|
+
const stochValue = 100 * (source[i] - lowestValues[i]) / range2;
|
|
733
|
+
result.push(stochValue);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return result;
|
|
738
|
+
}
|
|
739
|
+
function mfi(source, length, volume) {
|
|
740
|
+
if (!volume) {
|
|
741
|
+
throw new Error(
|
|
742
|
+
"ta.mfi() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
const upperFlow = [];
|
|
746
|
+
const lowerFlow = [];
|
|
747
|
+
for (let i = 0; i < source.length; i++) {
|
|
748
|
+
const change2 = i === 0 ? NaN : source[i] - source[i - 1];
|
|
749
|
+
const flow = volume[i] * source[i];
|
|
750
|
+
upperFlow.push((0, import_compare.le)(change2, 0) ? 0 : flow);
|
|
751
|
+
lowerFlow.push((0, import_compare.ge)(change2, 0) ? 0 : flow);
|
|
752
|
+
}
|
|
753
|
+
const upper = (0, import_running_sum.runningSum)(upperFlow, length);
|
|
754
|
+
const lower = (0, import_running_sum.runningSum)(lowerFlow, length);
|
|
755
|
+
return upper.map((u, i) => {
|
|
756
|
+
const l = lower[i];
|
|
757
|
+
if (Number.isNaN(u) || Number.isNaN(l)) return NaN;
|
|
758
|
+
if (l === 0) return 100;
|
|
759
|
+
return 100 - 100 / (1 + u / l);
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
function hma(source, length) {
|
|
763
|
+
const halfLength = Math.floor(length / 2);
|
|
764
|
+
const sqrtLength = Math.floor(Math.sqrt(length));
|
|
765
|
+
const wmaHalf = wma(source, halfLength);
|
|
766
|
+
const wmaFull = wma(source, length);
|
|
767
|
+
const diff = [];
|
|
768
|
+
for (let i = 0; i < source.length; i++) {
|
|
769
|
+
diff.push(2 * wmaHalf[i] - wmaFull[i]);
|
|
770
|
+
}
|
|
771
|
+
return wma(diff, sqrtLength);
|
|
772
|
+
}
|
|
773
|
+
function sar(start, inc, max2, high, low, close) {
|
|
774
|
+
if (!high || !low || !close) {
|
|
775
|
+
throw new Error(
|
|
776
|
+
"ta.sar() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
const result = [];
|
|
780
|
+
let sarValue = NaN;
|
|
781
|
+
let extremePoint = NaN;
|
|
782
|
+
let acceleration = start;
|
|
783
|
+
let isUpTrend = false;
|
|
784
|
+
let isFirstTrendBar = false;
|
|
785
|
+
for (let i = 0; i < close.length; i++) {
|
|
786
|
+
if (i === 0) {
|
|
787
|
+
result.push(NaN);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
if (i === 1) {
|
|
791
|
+
if (close[i] > close[i - 1]) {
|
|
792
|
+
isUpTrend = true;
|
|
793
|
+
extremePoint = high[i];
|
|
794
|
+
sarValue = low[i - 1];
|
|
795
|
+
} else {
|
|
796
|
+
isUpTrend = false;
|
|
797
|
+
extremePoint = low[i];
|
|
798
|
+
sarValue = high[i - 1];
|
|
799
|
+
}
|
|
800
|
+
isFirstTrendBar = true;
|
|
801
|
+
acceleration = start;
|
|
802
|
+
}
|
|
803
|
+
sarValue = sarValue + acceleration * (extremePoint - sarValue);
|
|
804
|
+
if (isUpTrend) {
|
|
805
|
+
if (sarValue > low[i]) {
|
|
806
|
+
isFirstTrendBar = true;
|
|
807
|
+
isUpTrend = false;
|
|
808
|
+
sarValue = Math.max(high[i], extremePoint);
|
|
809
|
+
extremePoint = low[i];
|
|
810
|
+
acceleration = start;
|
|
811
|
+
}
|
|
812
|
+
} else {
|
|
813
|
+
if (sarValue < high[i]) {
|
|
814
|
+
isFirstTrendBar = true;
|
|
815
|
+
isUpTrend = true;
|
|
816
|
+
sarValue = Math.min(low[i], extremePoint);
|
|
817
|
+
extremePoint = high[i];
|
|
818
|
+
acceleration = start;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
if (!isFirstTrendBar) {
|
|
822
|
+
if (isUpTrend) {
|
|
823
|
+
if (high[i] > extremePoint) {
|
|
824
|
+
extremePoint = high[i];
|
|
825
|
+
acceleration = Math.min(acceleration + inc, max2);
|
|
826
|
+
}
|
|
827
|
+
} else {
|
|
828
|
+
if (low[i] < extremePoint) {
|
|
829
|
+
extremePoint = low[i];
|
|
830
|
+
acceleration = Math.min(acceleration + inc, max2);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
if (isUpTrend) {
|
|
835
|
+
sarValue = Math.min(sarValue, low[i - 1]);
|
|
836
|
+
if (i > 1) {
|
|
837
|
+
sarValue = Math.min(sarValue, low[i - 2]);
|
|
838
|
+
}
|
|
839
|
+
} else {
|
|
840
|
+
sarValue = Math.max(sarValue, high[i - 1]);
|
|
841
|
+
if (i > 1) {
|
|
842
|
+
sarValue = Math.max(sarValue, high[i - 2]);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
result.push(sarValue);
|
|
846
|
+
isFirstTrendBar = false;
|
|
847
|
+
}
|
|
848
|
+
return result;
|
|
849
|
+
}
|
|
850
|
+
function pivot(source, leftbars, rightbars, isHigh) {
|
|
851
|
+
const beatsLeft = isHigh ? (x, v) => x > v : (x, v) => x < v;
|
|
852
|
+
const beatsRight = isHigh ? (x, v) => x >= v : (x, v) => x <= v;
|
|
853
|
+
return source.map((_, i) => {
|
|
854
|
+
const center = i - rightbars;
|
|
855
|
+
if (center - leftbars < 0) return NaN;
|
|
856
|
+
const v = source[center];
|
|
857
|
+
if (Number.isNaN(v)) return NaN;
|
|
858
|
+
for (let j = 1; j <= leftbars; j++) {
|
|
859
|
+
const x = source[center - j];
|
|
860
|
+
if (Number.isNaN(x)) break;
|
|
861
|
+
if (beatsLeft(x, v)) return NaN;
|
|
862
|
+
}
|
|
863
|
+
for (let j = 1; j <= rightbars; j++) {
|
|
864
|
+
const x = source[center + j];
|
|
865
|
+
if (Number.isNaN(x)) break;
|
|
866
|
+
if (beatsRight(x, v)) return NaN;
|
|
867
|
+
}
|
|
868
|
+
return v;
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
function pivothigh(sourceOrLeftbars, leftbarsOrRightbars, rightbars, high) {
|
|
872
|
+
if (rightbars === void 0) {
|
|
873
|
+
if (!high) {
|
|
874
|
+
throw new Error("ta.pivothigh() requires high series when using two-parameter version.");
|
|
875
|
+
}
|
|
876
|
+
return pivot(high, sourceOrLeftbars, leftbarsOrRightbars, true);
|
|
877
|
+
}
|
|
878
|
+
return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, true);
|
|
879
|
+
}
|
|
880
|
+
function pivotlow(sourceOrLeftbars, leftbarsOrRightbars, rightbars, low) {
|
|
881
|
+
if (rightbars === void 0) {
|
|
882
|
+
if (!low) {
|
|
883
|
+
throw new Error("ta.pivotlow() requires low series when using two-parameter version.");
|
|
884
|
+
}
|
|
885
|
+
return pivot(low, sourceOrLeftbars, leftbarsOrRightbars, false);
|
|
886
|
+
}
|
|
887
|
+
return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, false);
|
|
888
|
+
}
|
|
889
|
+
function barssince(condition) {
|
|
890
|
+
const result = [];
|
|
891
|
+
let barsSinceTrue = NaN;
|
|
892
|
+
for (let i = 0; i < condition.length; i++) {
|
|
893
|
+
if (condition[i]) {
|
|
894
|
+
barsSinceTrue = 0;
|
|
895
|
+
} else if (!isNaN(barsSinceTrue)) {
|
|
896
|
+
barsSinceTrue++;
|
|
897
|
+
}
|
|
898
|
+
result.push(barsSinceTrue);
|
|
899
|
+
}
|
|
900
|
+
return result;
|
|
901
|
+
}
|
|
902
|
+
function valuewhen(condition, source, occurrence) {
|
|
903
|
+
const result = [];
|
|
904
|
+
for (let i = 0; i < condition.length; i++) {
|
|
905
|
+
let occurrenceCount = 0;
|
|
906
|
+
let foundValue = NaN;
|
|
907
|
+
for (let j = i; j >= 0; j--) {
|
|
908
|
+
if (condition[j]) {
|
|
909
|
+
if (occurrenceCount === occurrence) {
|
|
910
|
+
foundValue = source[j];
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
occurrenceCount++;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
result.push(foundValue);
|
|
917
|
+
}
|
|
918
|
+
return result;
|
|
919
|
+
}
|
|
920
|
+
function dmi(diLength, adxSmoothing, high, low, close) {
|
|
921
|
+
const len = Math.max(high.length, low.length, close.length);
|
|
922
|
+
const plusDM = [];
|
|
923
|
+
const minusDM = [];
|
|
924
|
+
for (let i = 0; i < len; i++) {
|
|
925
|
+
const up = i === 0 ? NaN : high[i] - high[i - 1];
|
|
926
|
+
const down = i === 0 ? NaN : low[i - 1] - low[i];
|
|
927
|
+
plusDM.push(Number.isNaN(up) ? NaN : (0, import_compare.gt)(up, down) && (0, import_compare.gt)(up, 0) ? up : 0);
|
|
928
|
+
minusDM.push(Number.isNaN(down) ? NaN : (0, import_compare.gt)(down, up) && (0, import_compare.gt)(down, 0) ? down : 0);
|
|
929
|
+
}
|
|
930
|
+
const trur = rma(tr(false, high, low, close), diLength);
|
|
931
|
+
const smoothedPlus = rma(plusDM, diLength);
|
|
932
|
+
const smoothedMinus = rma(minusDM, diLength);
|
|
933
|
+
const directional = (smoothed) => {
|
|
934
|
+
let last = NaN;
|
|
935
|
+
return smoothed.map((v, i) => {
|
|
936
|
+
const t = trur[i];
|
|
937
|
+
const value = t === 0 ? NaN : 100 * v / t;
|
|
938
|
+
if (!Number.isNaN(value)) last = value;
|
|
939
|
+
return last;
|
|
940
|
+
});
|
|
941
|
+
};
|
|
942
|
+
const plusDI = directional(smoothedPlus);
|
|
943
|
+
const minusDI = directional(smoothedMinus);
|
|
944
|
+
const dx = plusDI.map((plus, i) => {
|
|
945
|
+
const minus = minusDI[i];
|
|
946
|
+
const sum = plus + minus;
|
|
947
|
+
return Math.abs(plus - minus) / ((0, import_compare.eq)(sum, 0) ? 1 : sum);
|
|
948
|
+
});
|
|
949
|
+
const adx = rma(dx, adxSmoothing).map((v) => 100 * v);
|
|
950
|
+
return [plusDI, minusDI, adx];
|
|
951
|
+
}
|
|
952
|
+
function tsi(source, shortLength, longLength) {
|
|
953
|
+
const momentum = [];
|
|
954
|
+
for (let i = 0; i < source.length; i++) {
|
|
955
|
+
if (i === 0) {
|
|
956
|
+
momentum.push(NaN);
|
|
957
|
+
} else {
|
|
958
|
+
momentum.push(source[i] - source[i - 1]);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
const smoothedMomentum = ema(ema(momentum, longLength), shortLength);
|
|
962
|
+
const absMomentum = momentum.map(Math.abs);
|
|
963
|
+
const smoothedAbsMomentum = ema(ema(absMomentum, longLength), shortLength);
|
|
964
|
+
const result = [];
|
|
965
|
+
for (let i = 0; i < source.length; i++) {
|
|
966
|
+
if (smoothedAbsMomentum[i] === 0) {
|
|
967
|
+
result.push(0);
|
|
968
|
+
} else {
|
|
969
|
+
result.push(smoothedMomentum[i] / smoothedAbsMomentum[i] * 100);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
return result;
|
|
973
|
+
}
|
|
974
|
+
function cmo(source, length) {
|
|
975
|
+
const result = [];
|
|
976
|
+
for (let i = 0; i < source.length; i++) {
|
|
977
|
+
if (i < length) {
|
|
978
|
+
result.push(NaN);
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
let sumGains = 0;
|
|
982
|
+
let sumLosses = 0;
|
|
983
|
+
for (let j = 0; j < length; j++) {
|
|
984
|
+
const change2 = source[i - j] - source[i - j - 1];
|
|
985
|
+
if (change2 > 0) {
|
|
986
|
+
sumGains += change2;
|
|
987
|
+
} else {
|
|
988
|
+
sumLosses += Math.abs(change2);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
const totalMovement = sumGains + sumLosses;
|
|
992
|
+
if (totalMovement === 0) {
|
|
993
|
+
result.push(0);
|
|
994
|
+
} else {
|
|
995
|
+
const cmoValue = (sumGains - sumLosses) / totalMovement * 100;
|
|
996
|
+
result.push(cmoValue);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return result;
|
|
1000
|
+
}
|
|
1001
|
+
function kc(source, length, mult, useTrueRange = true, high, low, close) {
|
|
1002
|
+
const middle = ema(source, length);
|
|
1003
|
+
let range2;
|
|
1004
|
+
if (useTrueRange) {
|
|
1005
|
+
if (!high || !low || !close) {
|
|
1006
|
+
throw new Error("ta.kc() with useTrueRange=true requires high, low, and close data");
|
|
1007
|
+
}
|
|
1008
|
+
range2 = tr(false, high, low, close);
|
|
1009
|
+
} else {
|
|
1010
|
+
if (!high || !low) {
|
|
1011
|
+
throw new Error("ta.kc() requires high and low data");
|
|
1012
|
+
}
|
|
1013
|
+
range2 = [];
|
|
1014
|
+
for (let i = 0; i < high.length; i++) {
|
|
1015
|
+
range2.push(high[i] - low[i]);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
const rangeEma = ema(range2, length);
|
|
1019
|
+
const upper = [];
|
|
1020
|
+
const lower = [];
|
|
1021
|
+
for (let i = 0; i < middle.length; i++) {
|
|
1022
|
+
upper.push(middle[i] + rangeEma[i] * mult);
|
|
1023
|
+
lower.push(middle[i] - rangeEma[i] * mult);
|
|
1024
|
+
}
|
|
1025
|
+
return [middle, upper, lower];
|
|
1026
|
+
}
|
|
1027
|
+
function bbw(source, length, mult) {
|
|
1028
|
+
const [basis, upper, lower] = bb(source, length, mult);
|
|
1029
|
+
const result = [];
|
|
1030
|
+
for (let i = 0; i < source.length; i++) {
|
|
1031
|
+
if (basis[i] === 0) {
|
|
1032
|
+
result.push(NaN);
|
|
1033
|
+
} else {
|
|
1034
|
+
const width = (upper[i] - lower[i]) / basis[i] * 100;
|
|
1035
|
+
result.push(width);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return result;
|
|
1039
|
+
}
|
|
1040
|
+
function wpr(high, low, close, length = 14) {
|
|
1041
|
+
const result = [];
|
|
1042
|
+
for (let i = 0; i < close.length; i++) {
|
|
1043
|
+
if (i < length - 1) {
|
|
1044
|
+
result.push(NaN);
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
let highestHigh = high[i - length + 1];
|
|
1048
|
+
let lowestLow = low[i - length + 1];
|
|
1049
|
+
for (let j = i - length + 2; j <= i; j++) {
|
|
1050
|
+
if (high[j] > highestHigh) highestHigh = high[j];
|
|
1051
|
+
if (low[j] < lowestLow) lowestLow = low[j];
|
|
1052
|
+
}
|
|
1053
|
+
const range2 = highestHigh - lowestLow;
|
|
1054
|
+
if (range2 === 0) {
|
|
1055
|
+
result.push(NaN);
|
|
1056
|
+
} else {
|
|
1057
|
+
const wprValue = (highestHigh - close[i]) / range2 * -100;
|
|
1058
|
+
result.push(wprValue);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return result;
|
|
1062
|
+
}
|
|
1063
|
+
function vwap(source, volume, anchor, stdev_mult) {
|
|
1064
|
+
if (source.length !== volume.length) {
|
|
1065
|
+
throw new Error("ta.vwap: source and volume must have the same length");
|
|
1066
|
+
}
|
|
1067
|
+
const mid = [];
|
|
1068
|
+
const upper = [];
|
|
1069
|
+
const lower = [];
|
|
1070
|
+
let sumPV = 0;
|
|
1071
|
+
let sumV = 0;
|
|
1072
|
+
let sumPPV = 0;
|
|
1073
|
+
for (let i = 0; i < source.length; i++) {
|
|
1074
|
+
if (anchor && anchor[i]) {
|
|
1075
|
+
sumPV = 0;
|
|
1076
|
+
sumV = 0;
|
|
1077
|
+
sumPPV = 0;
|
|
1078
|
+
}
|
|
1079
|
+
const s = source[i];
|
|
1080
|
+
const v = volume[i];
|
|
1081
|
+
if (!Number.isNaN(s) && !Number.isNaN(v)) {
|
|
1082
|
+
sumPV += s * v;
|
|
1083
|
+
sumV += v;
|
|
1084
|
+
sumPPV += s * s * v;
|
|
1085
|
+
}
|
|
1086
|
+
const m = sumV === 0 ? NaN : sumPV / sumV;
|
|
1087
|
+
mid.push(m);
|
|
1088
|
+
if (stdev_mult !== void 0) {
|
|
1089
|
+
const sd = Math.sqrt(Math.max(0, sumPPV / sumV - m * m));
|
|
1090
|
+
upper.push(m + stdev_mult * sd);
|
|
1091
|
+
lower.push(m - stdev_mult * sd);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return stdev_mult === void 0 ? mid : [mid, upper, lower];
|
|
1095
|
+
}
|
|
1096
|
+
function alma(source, length = 9, offset = 0.85, sigma = 6, floor = false) {
|
|
1097
|
+
const result = [];
|
|
1098
|
+
const m = floor ? Math.floor(offset * (length - 1)) : offset * (length - 1);
|
|
1099
|
+
const s = length / sigma;
|
|
1100
|
+
const weights = [];
|
|
1101
|
+
let weightSum = 0;
|
|
1102
|
+
for (let i = 0; i < length; i++) {
|
|
1103
|
+
const weight = Math.exp(-1 * Math.pow(i - m, 2) / (2 * Math.pow(s, 2)));
|
|
1104
|
+
weights.push(weight);
|
|
1105
|
+
weightSum += weight;
|
|
1106
|
+
}
|
|
1107
|
+
for (let i = 0; i < length; i++) {
|
|
1108
|
+
weights[i] /= weightSum;
|
|
1109
|
+
}
|
|
1110
|
+
for (let i = 0; i < source.length; i++) {
|
|
1111
|
+
if (i < length - 1) {
|
|
1112
|
+
result.push(NaN);
|
|
1113
|
+
continue;
|
|
1114
|
+
}
|
|
1115
|
+
let almaValue = 0;
|
|
1116
|
+
for (let j = 0; j < length; j++) {
|
|
1117
|
+
almaValue += source[i - length + 1 + j] * weights[j];
|
|
1118
|
+
}
|
|
1119
|
+
result.push(almaValue);
|
|
1120
|
+
}
|
|
1121
|
+
return result;
|
|
1122
|
+
}
|
|
1123
|
+
function kcw(source, length = 20, mult = 2, useTrueRange = true, high, low, close) {
|
|
1124
|
+
const [basis, upper, lower] = kc(source, length, mult, useTrueRange, high, low, close);
|
|
1125
|
+
const result = [];
|
|
1126
|
+
for (let i = 0; i < source.length; i++) {
|
|
1127
|
+
if (isNaN(basis[i]) || basis[i] === 0) {
|
|
1128
|
+
result.push(NaN);
|
|
1129
|
+
} else {
|
|
1130
|
+
const width = (upper[i] - lower[i]) / basis[i] * 100;
|
|
1131
|
+
result.push(width);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return result;
|
|
1135
|
+
}
|
|
1136
|
+
function range(source, length) {
|
|
1137
|
+
return source.map((_, i) => {
|
|
1138
|
+
const values = lastValues(source, i, length);
|
|
1139
|
+
return values ? Math.max(...values) - Math.min(...values) : NaN;
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
function highestbars(source, length) {
|
|
1143
|
+
return extremeOffset(source, length, false);
|
|
1144
|
+
}
|
|
1145
|
+
function lowestbars(source, length) {
|
|
1146
|
+
return extremeOffset(source, length, true);
|
|
1147
|
+
}
|
|
1148
|
+
function max(source) {
|
|
1149
|
+
let best = NaN;
|
|
1150
|
+
return source.map((x) => {
|
|
1151
|
+
if (!Number.isNaN(x) && !(x <= best)) best = x;
|
|
1152
|
+
return best;
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
function min(source) {
|
|
1156
|
+
let best = NaN;
|
|
1157
|
+
return source.map((x) => {
|
|
1158
|
+
if (!Number.isNaN(x) && !(x >= best)) best = x;
|
|
1159
|
+
return best;
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
function cog(source, length = 10) {
|
|
1163
|
+
const result = [];
|
|
1164
|
+
for (let i = 0; i < source.length; i++) {
|
|
1165
|
+
if (i < length - 1) {
|
|
1166
|
+
result.push(NaN);
|
|
1167
|
+
continue;
|
|
1168
|
+
}
|
|
1169
|
+
let numerator = 0;
|
|
1170
|
+
let denominator = 0;
|
|
1171
|
+
for (let j = 0; j < length; j++) {
|
|
1172
|
+
const weight = j + 1;
|
|
1173
|
+
const price = source[i - length + 1 + j];
|
|
1174
|
+
numerator += weight * price;
|
|
1175
|
+
denominator += price;
|
|
1176
|
+
}
|
|
1177
|
+
if (denominator === 0) {
|
|
1178
|
+
result.push(NaN);
|
|
1179
|
+
} else {
|
|
1180
|
+
const cog2 = -1 * (numerator / denominator) + (length + 1) / 2;
|
|
1181
|
+
result.push(cog2);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return result;
|
|
1185
|
+
}
|
|
1186
|
+
function mode(source, length) {
|
|
1187
|
+
const result = [];
|
|
1188
|
+
for (let i = 0; i < source.length; i++) {
|
|
1189
|
+
if (i < length - 1) {
|
|
1190
|
+
result.push(NaN);
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
const values = [];
|
|
1194
|
+
for (let j = 0; j < length; j++) {
|
|
1195
|
+
const value = source[i - j];
|
|
1196
|
+
if (!isNaN(value)) {
|
|
1197
|
+
values.push(value);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
if (values.length === 0) {
|
|
1201
|
+
result.push(NaN);
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
const frequencyMap = /* @__PURE__ */ new Map();
|
|
1205
|
+
for (const value of values) {
|
|
1206
|
+
frequencyMap.set(value, (frequencyMap.get(value) || 0) + 1);
|
|
1207
|
+
}
|
|
1208
|
+
let maxFrequency = 0;
|
|
1209
|
+
frequencyMap.forEach((freq) => {
|
|
1210
|
+
if (freq > maxFrequency) {
|
|
1211
|
+
maxFrequency = freq;
|
|
1212
|
+
}
|
|
1213
|
+
});
|
|
1214
|
+
const modesWithMaxFreq = [];
|
|
1215
|
+
frequencyMap.forEach((freq, value) => {
|
|
1216
|
+
if (freq === maxFrequency) {
|
|
1217
|
+
modesWithMaxFreq.push(value);
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
result.push(Math.min(...modesWithMaxFreq));
|
|
1221
|
+
}
|
|
1222
|
+
return result;
|
|
1223
|
+
}
|
|
1224
|
+
function percentile_linear_interpolation(source, length, percentage) {
|
|
1225
|
+
return sortedWindow(source, length, (s) => {
|
|
1226
|
+
const pos = percentage / 100 * length - 0.5;
|
|
1227
|
+
if (pos <= 0) return s[0];
|
|
1228
|
+
if (pos >= length - 1) return s[length - 1];
|
|
1229
|
+
const lo = Math.floor(pos);
|
|
1230
|
+
return s[lo] + (pos - lo) * (s[lo + 1] - s[lo]);
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
function sortedWindow(source, length, fn) {
|
|
1234
|
+
const result = [];
|
|
1235
|
+
const values = [];
|
|
1236
|
+
const bars = [];
|
|
1237
|
+
for (let i = 0; i < source.length; i++) {
|
|
1238
|
+
const v = source[i];
|
|
1239
|
+
let k = 0;
|
|
1240
|
+
while (k < values.length && !(values[k] >= v)) k++;
|
|
1241
|
+
values.splice(k, 0, v);
|
|
1242
|
+
bars.splice(k, 0, i);
|
|
1243
|
+
if (i >= length) {
|
|
1244
|
+
const old = bars.indexOf(i - length);
|
|
1245
|
+
values.splice(old, 1);
|
|
1246
|
+
bars.splice(old, 1);
|
|
1247
|
+
}
|
|
1248
|
+
result.push(i < length - 1 ? NaN : fn(values));
|
|
1249
|
+
}
|
|
1250
|
+
return result;
|
|
1251
|
+
}
|
|
1252
|
+
function percentile_nearest_rank(source, length, percentage) {
|
|
1253
|
+
const rank = Math.min(length, Math.max(1, Math.ceil(percentage / 100 * length)));
|
|
1254
|
+
return sortedWindow(source, length, (s) => s[rank - 1]);
|
|
1255
|
+
}
|
|
1256
|
+
function rci(source, length) {
|
|
1257
|
+
const result = [];
|
|
1258
|
+
for (let i = 0; i < source.length; i++) {
|
|
1259
|
+
if (i < length - 1) {
|
|
1260
|
+
result.push(NaN);
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
const values = [];
|
|
1264
|
+
for (let j = 0; j < length; j++) {
|
|
1265
|
+
values.push(source[i - length + 1 + j]);
|
|
1266
|
+
}
|
|
1267
|
+
if (values.some((v) => isNaN(v))) {
|
|
1268
|
+
result.push(NaN);
|
|
1269
|
+
continue;
|
|
1270
|
+
}
|
|
1271
|
+
const indexed = values.map((value, index) => ({ value, index }));
|
|
1272
|
+
const sorted = [...indexed].sort((a, b) => a.value - b.value);
|
|
1273
|
+
const ranks = new Array(length).fill(0);
|
|
1274
|
+
let currentRank = 1;
|
|
1275
|
+
for (let j = 0; j < sorted.length; j++) {
|
|
1276
|
+
let tieCount = 1;
|
|
1277
|
+
while (j + tieCount < sorted.length && sorted[j].value === sorted[j + tieCount].value) {
|
|
1278
|
+
tieCount++;
|
|
1279
|
+
}
|
|
1280
|
+
const avgRank = (currentRank + (currentRank + tieCount - 1)) / 2;
|
|
1281
|
+
for (let k = 0; k < tieCount; k++) {
|
|
1282
|
+
ranks[sorted[j + k].index] = avgRank;
|
|
1283
|
+
}
|
|
1284
|
+
j += tieCount - 1;
|
|
1285
|
+
currentRank += tieCount;
|
|
1286
|
+
}
|
|
1287
|
+
let sumSquaredDiff = 0;
|
|
1288
|
+
for (let j = 0; j < length; j++) {
|
|
1289
|
+
const timeRank = j + 1;
|
|
1290
|
+
const diff = ranks[j] - timeRank;
|
|
1291
|
+
sumSquaredDiff += diff * diff;
|
|
1292
|
+
}
|
|
1293
|
+
const n = length;
|
|
1294
|
+
const base = (n * n * n - n) / 12;
|
|
1295
|
+
let tieCorrection = 0;
|
|
1296
|
+
for (let j = 0; j < sorted.length; ) {
|
|
1297
|
+
let tieCount = 1;
|
|
1298
|
+
while (j + tieCount < sorted.length && sorted[j].value === sorted[j + tieCount].value) {
|
|
1299
|
+
tieCount++;
|
|
1300
|
+
}
|
|
1301
|
+
if (tieCount > 1) {
|
|
1302
|
+
tieCorrection += (tieCount * tieCount * tieCount - tieCount) / 12;
|
|
1303
|
+
}
|
|
1304
|
+
j += tieCount;
|
|
1305
|
+
}
|
|
1306
|
+
const A = base - tieCorrection;
|
|
1307
|
+
const B = base;
|
|
1308
|
+
let rho;
|
|
1309
|
+
if (A === 0 || B === 0) {
|
|
1310
|
+
rho = 0;
|
|
1311
|
+
} else {
|
|
1312
|
+
rho = (A + B - sumSquaredDiff) / (2 * Math.sqrt(A * B));
|
|
1313
|
+
}
|
|
1314
|
+
result.push(rho * 100);
|
|
1315
|
+
}
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
function pivot_point_levels(type, anchor, developing = false, high, low, close, open) {
|
|
1319
|
+
const typeStr = typeof type === "string" ? type : String(type[0]);
|
|
1320
|
+
const isDeveloping = typeof developing === "boolean" ? developing : developing[0];
|
|
1321
|
+
if (typeStr === "Woodie" && isDeveloping) {
|
|
1322
|
+
throw new Error("ta.pivot_point_levels: Woodie type cannot use developing=true");
|
|
1323
|
+
}
|
|
1324
|
+
const length = anchor.length;
|
|
1325
|
+
if (high && high.length !== length) throw new Error("High series length mismatch");
|
|
1326
|
+
if (low && low.length !== length) throw new Error("Low series length mismatch");
|
|
1327
|
+
if (close && close.length !== length) throw new Error("Close series length mismatch");
|
|
1328
|
+
if (open && open.length !== length) throw new Error("Open series length mismatch");
|
|
1329
|
+
const results = Array.from({ length: 11 }, () => []);
|
|
1330
|
+
let lastH = NaN, lastL = NaN, lastC = NaN, lastO = NaN;
|
|
1331
|
+
let lastAnchorIndex = -1;
|
|
1332
|
+
for (let i = 0; i < length; i++) {
|
|
1333
|
+
if (anchor[i]) {
|
|
1334
|
+
lastAnchorIndex = i;
|
|
1335
|
+
lastH = high ? high[i] : NaN;
|
|
1336
|
+
lastL = low ? low[i] : NaN;
|
|
1337
|
+
lastC = close ? close[i] : NaN;
|
|
1338
|
+
lastO = open ? open[i] : NaN;
|
|
1339
|
+
}
|
|
1340
|
+
let h, l, c, o;
|
|
1341
|
+
if (isDeveloping && lastAnchorIndex >= 0) {
|
|
1342
|
+
h = high ? Math.max(...high.slice(lastAnchorIndex, i + 1).filter((v) => !isNaN(v))) : NaN;
|
|
1343
|
+
l = low ? Math.min(...low.slice(lastAnchorIndex, i + 1).filter((v) => !isNaN(v))) : NaN;
|
|
1344
|
+
c = close ? close[i] : NaN;
|
|
1345
|
+
o = open && lastAnchorIndex >= 0 ? open[lastAnchorIndex] : NaN;
|
|
1346
|
+
} else {
|
|
1347
|
+
h = lastH;
|
|
1348
|
+
l = lastL;
|
|
1349
|
+
c = lastC;
|
|
1350
|
+
o = lastO;
|
|
1351
|
+
}
|
|
1352
|
+
const levels = calculatePivotLevels(typeStr, h, l, c, o);
|
|
1353
|
+
for (let j = 0; j < 11; j++) {
|
|
1354
|
+
results[j].push(levels[j]);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return results;
|
|
1358
|
+
}
|
|
1359
|
+
function calculatePivotLevels(type, h, l, c, o) {
|
|
1360
|
+
if (isNaN(h) || isNaN(l) || isNaN(c)) {
|
|
1361
|
+
return Array(11).fill(NaN);
|
|
1362
|
+
}
|
|
1363
|
+
const levels = Array(11).fill(NaN);
|
|
1364
|
+
let P;
|
|
1365
|
+
switch (type) {
|
|
1366
|
+
case "Traditional":
|
|
1367
|
+
case "Fibonacci":
|
|
1368
|
+
case "Classic":
|
|
1369
|
+
P = (h + l + c) / 3;
|
|
1370
|
+
break;
|
|
1371
|
+
case "Woodie":
|
|
1372
|
+
P = (h + l + 2 * c) / 4;
|
|
1373
|
+
break;
|
|
1374
|
+
case "DM":
|
|
1375
|
+
P = (h + l + c) / 3;
|
|
1376
|
+
break;
|
|
1377
|
+
case "Camarilla":
|
|
1378
|
+
P = (h + l + c) / 3;
|
|
1379
|
+
break;
|
|
1380
|
+
default:
|
|
1381
|
+
P = (h + l + c) / 3;
|
|
1382
|
+
}
|
|
1383
|
+
levels[0] = P;
|
|
1384
|
+
switch (type) {
|
|
1385
|
+
case "Traditional":
|
|
1386
|
+
case "Classic":
|
|
1387
|
+
levels[1] = 2 * P - l;
|
|
1388
|
+
levels[2] = 2 * P - h;
|
|
1389
|
+
levels[3] = P + (h - l);
|
|
1390
|
+
levels[4] = P - (h - l);
|
|
1391
|
+
levels[5] = h + 2 * (P - l);
|
|
1392
|
+
levels[6] = l - 2 * (h - P);
|
|
1393
|
+
levels[7] = levels[5] + (h - l);
|
|
1394
|
+
levels[8] = levels[6] - (h - l);
|
|
1395
|
+
levels[9] = levels[7] + (h - l);
|
|
1396
|
+
levels[10] = levels[8] - (h - l);
|
|
1397
|
+
break;
|
|
1398
|
+
case "Fibonacci":
|
|
1399
|
+
levels[1] = P + 0.382 * (h - l);
|
|
1400
|
+
levels[2] = P - 0.382 * (h - l);
|
|
1401
|
+
levels[3] = P + 0.618 * (h - l);
|
|
1402
|
+
levels[4] = P - 0.618 * (h - l);
|
|
1403
|
+
levels[5] = P + (h - l);
|
|
1404
|
+
levels[6] = P - (h - l);
|
|
1405
|
+
levels[7] = levels[5] + 0.618 * (h - l);
|
|
1406
|
+
levels[8] = levels[6] - 0.618 * (h - l);
|
|
1407
|
+
levels[9] = levels[7] + 0.382 * (h - l);
|
|
1408
|
+
levels[10] = levels[8] - 0.382 * (h - l);
|
|
1409
|
+
break;
|
|
1410
|
+
case "Woodie":
|
|
1411
|
+
levels[1] = 2 * P - l;
|
|
1412
|
+
levels[2] = 2 * P - h;
|
|
1413
|
+
levels[3] = P + (h - l);
|
|
1414
|
+
levels[4] = P - (h - l);
|
|
1415
|
+
levels[5] = h + 2 * (P - l);
|
|
1416
|
+
levels[6] = l - 2 * (h - P);
|
|
1417
|
+
levels[7] = levels[5] + (h - l);
|
|
1418
|
+
levels[8] = levels[6] - (h - l);
|
|
1419
|
+
levels[9] = levels[7] + (h - l);
|
|
1420
|
+
levels[10] = levels[8] - (h - l);
|
|
1421
|
+
break;
|
|
1422
|
+
case "DM": {
|
|
1423
|
+
const x = h + l + c * 2 + (isNaN(o) ? c : o);
|
|
1424
|
+
const newP = x / (isNaN(o) ? 4 : 5);
|
|
1425
|
+
levels[0] = newP;
|
|
1426
|
+
levels[1] = x / 2 - l;
|
|
1427
|
+
levels[2] = x / 2 - h;
|
|
1428
|
+
break;
|
|
1429
|
+
}
|
|
1430
|
+
case "Camarilla": {
|
|
1431
|
+
const range2 = h - l;
|
|
1432
|
+
levels[1] = c + range2 * 1.1 / 12;
|
|
1433
|
+
levels[2] = c - range2 * 1.1 / 12;
|
|
1434
|
+
levels[3] = c + range2 * 1.1 / 6;
|
|
1435
|
+
levels[4] = c - range2 * 1.1 / 6;
|
|
1436
|
+
levels[5] = c + range2 * 1.1 / 4;
|
|
1437
|
+
levels[6] = c - range2 * 1.1 / 4;
|
|
1438
|
+
levels[7] = c + range2 * 1.1 / 2;
|
|
1439
|
+
levels[8] = c - range2 * 1.1 / 2;
|
|
1440
|
+
levels[9] = h;
|
|
1441
|
+
levels[10] = l;
|
|
1442
|
+
break;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
return levels;
|
|
1446
|
+
}
|
|
1447
|
+
function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacement, high, low, close) {
|
|
1448
|
+
const length = high.length;
|
|
1449
|
+
const highestConversion = highest(high, conversionPeriods);
|
|
1450
|
+
const lowestConversion = lowest(low, conversionPeriods);
|
|
1451
|
+
const tenkanSen = [];
|
|
1452
|
+
for (let i = 0; i < length; i++) {
|
|
1453
|
+
if (isNaN(highestConversion[i]) || isNaN(lowestConversion[i])) {
|
|
1454
|
+
tenkanSen.push(NaN);
|
|
1455
|
+
} else {
|
|
1456
|
+
tenkanSen.push((highestConversion[i] + lowestConversion[i]) / 2);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
const highestBase = highest(high, basePeriods);
|
|
1460
|
+
const lowestBase = lowest(low, basePeriods);
|
|
1461
|
+
const kijunSen = [];
|
|
1462
|
+
for (let i = 0; i < length; i++) {
|
|
1463
|
+
if (isNaN(highestBase[i]) || isNaN(lowestBase[i])) {
|
|
1464
|
+
kijunSen.push(NaN);
|
|
1465
|
+
} else {
|
|
1466
|
+
kijunSen.push((highestBase[i] + lowestBase[i]) / 2);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
const senkouSpanA = [];
|
|
1470
|
+
for (let i = 0; i < length; i++) {
|
|
1471
|
+
const sourceIndex = i - displacement;
|
|
1472
|
+
if (sourceIndex < 0 || isNaN(tenkanSen[sourceIndex]) || isNaN(kijunSen[sourceIndex])) {
|
|
1473
|
+
senkouSpanA.push(NaN);
|
|
1474
|
+
} else {
|
|
1475
|
+
senkouSpanA.push((tenkanSen[sourceIndex] + kijunSen[sourceIndex]) / 2);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
const highestLagging = highest(high, laggingSpan2Periods);
|
|
1479
|
+
const lowestLagging = lowest(low, laggingSpan2Periods);
|
|
1480
|
+
const senkouSpanB = [];
|
|
1481
|
+
for (let i = 0; i < length; i++) {
|
|
1482
|
+
const sourceIndex = i - displacement;
|
|
1483
|
+
if (sourceIndex < 0 || isNaN(highestLagging[sourceIndex]) || isNaN(lowestLagging[sourceIndex])) {
|
|
1484
|
+
senkouSpanB.push(NaN);
|
|
1485
|
+
} else {
|
|
1486
|
+
senkouSpanB.push((highestLagging[sourceIndex] + lowestLagging[sourceIndex]) / 2);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
const chikouSpan = [];
|
|
1490
|
+
for (let i = 0; i < length; i++) {
|
|
1491
|
+
const sourceIndex = i + displacement;
|
|
1492
|
+
if (sourceIndex >= length || isNaN(close[sourceIndex])) {
|
|
1493
|
+
chikouSpan.push(NaN);
|
|
1494
|
+
} else {
|
|
1495
|
+
chikouSpan.push(close[sourceIndex]);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
return [tenkanSen, kijunSen, senkouSpanA, senkouSpanB, chikouSpan];
|
|
1499
|
+
}
|
|
1500
|
+
function zigzag(deviation = 5, depth = 10, backstep = 3, source, high, low) {
|
|
1501
|
+
let highSource;
|
|
1502
|
+
let lowSource;
|
|
1503
|
+
if (high && low) {
|
|
1504
|
+
highSource = high;
|
|
1505
|
+
lowSource = low;
|
|
1506
|
+
} else if (source) {
|
|
1507
|
+
highSource = source;
|
|
1508
|
+
lowSource = source;
|
|
1509
|
+
} else {
|
|
1510
|
+
throw new Error(
|
|
1511
|
+
"ta.zigzag() requires either source series or high/low series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
const length = highSource.length;
|
|
1515
|
+
if (lowSource.length !== length) {
|
|
1516
|
+
throw new Error("ta.zigzag: high and low must have the same length");
|
|
1517
|
+
}
|
|
1518
|
+
const zigzagValues = new Array(length).fill(NaN);
|
|
1519
|
+
const directions = new Array(length).fill(0);
|
|
1520
|
+
const isPivot = new Array(length).fill(false);
|
|
1521
|
+
const getDeviation = (price1, price2) => {
|
|
1522
|
+
if (Math.abs(price1) < 1e-10 || isNaN(price1) || isNaN(price2)) return 0;
|
|
1523
|
+
return Math.abs((price2 - price1) / price1) * 100;
|
|
1524
|
+
};
|
|
1525
|
+
let lastConfirmedPivot = null;
|
|
1526
|
+
let potentialPivot = null;
|
|
1527
|
+
let currentDirection = 0;
|
|
1528
|
+
const confirmedPivots = [];
|
|
1529
|
+
let startIndex;
|
|
1530
|
+
let initialHighest = -Infinity;
|
|
1531
|
+
let initialLowest = Infinity;
|
|
1532
|
+
let initialHighIndex = -1;
|
|
1533
|
+
let initialLowIndex = -1;
|
|
1534
|
+
for (let i = 0; i < Math.min(depth, length); i++) {
|
|
1535
|
+
if (!isNaN(highSource[i]) && highSource[i] > initialHighest) {
|
|
1536
|
+
initialHighest = highSource[i];
|
|
1537
|
+
initialHighIndex = i;
|
|
1538
|
+
}
|
|
1539
|
+
if (!isNaN(lowSource[i]) && lowSource[i] < initialLowest) {
|
|
1540
|
+
initialLowest = lowSource[i];
|
|
1541
|
+
initialLowIndex = i;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
if (initialHighIndex >= 0 && initialLowIndex >= 0) {
|
|
1545
|
+
if (initialLowIndex <= initialHighIndex) {
|
|
1546
|
+
lastConfirmedPivot = { index: initialLowIndex, price: initialLowest, type: "low" };
|
|
1547
|
+
currentDirection = 1;
|
|
1548
|
+
} else {
|
|
1549
|
+
lastConfirmedPivot = { index: initialHighIndex, price: initialHighest, type: "high" };
|
|
1550
|
+
currentDirection = -1;
|
|
1551
|
+
}
|
|
1552
|
+
confirmedPivots.push(lastConfirmedPivot);
|
|
1553
|
+
startIndex = lastConfirmedPivot.index + 1;
|
|
1554
|
+
} else {
|
|
1555
|
+
startIndex = depth;
|
|
1556
|
+
}
|
|
1557
|
+
for (let i = Math.max(startIndex, depth); i < length; i++) {
|
|
1558
|
+
const currentHigh = highSource[i];
|
|
1559
|
+
const currentLow = lowSource[i];
|
|
1560
|
+
if (isNaN(currentHigh) || isNaN(currentLow)) {
|
|
1561
|
+
directions[i] = currentDirection;
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
let isPotentialHigh = true;
|
|
1565
|
+
for (let j = 1; j <= backstep && i - j >= 0; j++) {
|
|
1566
|
+
if (!isNaN(highSource[i - j]) && highSource[i - j] >= currentHigh) {
|
|
1567
|
+
isPotentialHigh = false;
|
|
1568
|
+
break;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
let isPotentialLow = true;
|
|
1572
|
+
for (let j = 1; j <= backstep && i - j >= 0; j++) {
|
|
1573
|
+
if (!isNaN(lowSource[i - j]) && lowSource[i - j] <= currentLow) {
|
|
1574
|
+
isPotentialLow = false;
|
|
1575
|
+
break;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
if (currentDirection === 1) {
|
|
1579
|
+
if (isPotentialHigh) {
|
|
1580
|
+
if (potentialPivot === null || potentialPivot.type !== "high") {
|
|
1581
|
+
if (lastConfirmedPivot && getDeviation(lastConfirmedPivot.price, currentHigh) >= deviation) {
|
|
1582
|
+
potentialPivot = { index: i, price: currentHigh, type: "high" };
|
|
1583
|
+
}
|
|
1584
|
+
} else {
|
|
1585
|
+
if (currentHigh > potentialPivot.price) {
|
|
1586
|
+
potentialPivot = { index: i, price: currentHigh, type: "high" };
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
if (potentialPivot && potentialPivot.type === "high") {
|
|
1591
|
+
const deviationFromPotential = getDeviation(potentialPivot.price, currentLow);
|
|
1592
|
+
if (deviationFromPotential >= deviation && i - potentialPivot.index >= backstep) {
|
|
1593
|
+
confirmedPivots.push(potentialPivot);
|
|
1594
|
+
lastConfirmedPivot = potentialPivot;
|
|
1595
|
+
currentDirection = -1;
|
|
1596
|
+
potentialPivot = null;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
} else if (currentDirection === -1) {
|
|
1600
|
+
if (isPotentialLow) {
|
|
1601
|
+
if (potentialPivot === null || potentialPivot.type !== "low") {
|
|
1602
|
+
if (lastConfirmedPivot && getDeviation(lastConfirmedPivot.price, currentLow) >= deviation) {
|
|
1603
|
+
potentialPivot = { index: i, price: currentLow, type: "low" };
|
|
1604
|
+
}
|
|
1605
|
+
} else {
|
|
1606
|
+
if (currentLow < potentialPivot.price) {
|
|
1607
|
+
potentialPivot = { index: i, price: currentLow, type: "low" };
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
if (potentialPivot && potentialPivot.type === "low") {
|
|
1612
|
+
const deviationFromPotential = getDeviation(potentialPivot.price, currentHigh);
|
|
1613
|
+
if (deviationFromPotential >= deviation && i - potentialPivot.index >= backstep) {
|
|
1614
|
+
confirmedPivots.push(potentialPivot);
|
|
1615
|
+
lastConfirmedPivot = potentialPivot;
|
|
1616
|
+
currentDirection = 1;
|
|
1617
|
+
potentialPivot = null;
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
} else {
|
|
1621
|
+
if (lastConfirmedPivot) {
|
|
1622
|
+
if (lastConfirmedPivot.type === "low" && getDeviation(lastConfirmedPivot.price, currentHigh) >= deviation) {
|
|
1623
|
+
currentDirection = 1;
|
|
1624
|
+
} else if (lastConfirmedPivot.type === "high" && getDeviation(lastConfirmedPivot.price, currentLow) >= deviation) {
|
|
1625
|
+
currentDirection = -1;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
directions[i] = currentDirection;
|
|
1630
|
+
}
|
|
1631
|
+
const lastPotentialWasAdded = potentialPivot !== null;
|
|
1632
|
+
if (potentialPivot) {
|
|
1633
|
+
confirmedPivots.push(potentialPivot);
|
|
1634
|
+
}
|
|
1635
|
+
for (const pivot2 of confirmedPivots) {
|
|
1636
|
+
zigzagValues[pivot2.index] = pivot2.price;
|
|
1637
|
+
isPivot[pivot2.index] = true;
|
|
1638
|
+
}
|
|
1639
|
+
let currentDir = 0;
|
|
1640
|
+
let pivotIdx = 0;
|
|
1641
|
+
const numConfirmed = lastPotentialWasAdded ? confirmedPivots.length - 1 : confirmedPivots.length;
|
|
1642
|
+
for (let i = 0; i < length; i++) {
|
|
1643
|
+
while (pivotIdx < numConfirmed && confirmedPivots[pivotIdx].index <= i) {
|
|
1644
|
+
const pivot2 = confirmedPivots[pivotIdx];
|
|
1645
|
+
currentDir = pivot2.type === "low" ? 1 : -1;
|
|
1646
|
+
pivotIdx++;
|
|
1647
|
+
}
|
|
1648
|
+
directions[i] = currentDir;
|
|
1649
|
+
}
|
|
1650
|
+
return [zigzagValues, directions, isPivot];
|
|
1651
|
+
}
|
|
1652
|
+
function obv(close, volume) {
|
|
1653
|
+
return cum(close.map((c, i) => i === 0 ? NaN : Math.sign(c - close[i - 1]) * volume[i]));
|
|
1654
|
+
}
|
|
1655
|
+
function pvt(close, volume) {
|
|
1656
|
+
return cum(
|
|
1657
|
+
close.map((c, i) => i === 0 ? NaN : (c - close[i - 1]) / close[i - 1] * volume[i])
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
function accdist(high, low, close, volume) {
|
|
1661
|
+
return cum(
|
|
1662
|
+
close.map((c, i) => {
|
|
1663
|
+
const h = high[i];
|
|
1664
|
+
const l = low[i];
|
|
1665
|
+
return h === l ? 0 : (2 * c - l - h) / (h - l) * volume[i];
|
|
1666
|
+
})
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
function iii(high, low, close, volume) {
|
|
1670
|
+
return close.map((c, i) => {
|
|
1671
|
+
const range2 = high[i] - low[i];
|
|
1672
|
+
return range2 === 0 ? NaN : (2 * c - high[i] - low[i]) / range2 * volume[i];
|
|
1673
|
+
});
|
|
1674
|
+
}
|
|
1675
|
+
function wvad(open, high, low, close, volume) {
|
|
1676
|
+
return close.map((c, i) => {
|
|
1677
|
+
const range2 = high[i] - low[i];
|
|
1678
|
+
return range2 === 0 ? NaN : (c - open[i]) / range2 * volume[i];
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
function wad(high, low, close) {
|
|
1682
|
+
return cum(
|
|
1683
|
+
close.map((c, i) => {
|
|
1684
|
+
const prev = i === 0 ? NaN : close[i - 1];
|
|
1685
|
+
const mom2 = c - prev;
|
|
1686
|
+
if (mom2 > 0) return c - Math.min(low[i], prev);
|
|
1687
|
+
if (mom2 < 0) return c - Math.max(high[i], prev);
|
|
1688
|
+
return 0;
|
|
1689
|
+
})
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
function volumeIndex(close, volume, use) {
|
|
1693
|
+
const result = [];
|
|
1694
|
+
let prevIndex = NaN;
|
|
1695
|
+
for (let i = 0; i < close.length; i++) {
|
|
1696
|
+
const prev = !prevIndex ? 1 : prevIndex;
|
|
1697
|
+
const c = close[i];
|
|
1698
|
+
const prevC = i === 0 ? NaN : close[i - 1];
|
|
1699
|
+
let value = prev;
|
|
1700
|
+
if (c && prevC) {
|
|
1701
|
+
const prevV = i === 0 || Number.isNaN(volume[i - 1]) ? 0 : volume[i - 1];
|
|
1702
|
+
if (use(volume[i], prevV)) value = prev + (c - prevC) / prevC * prev;
|
|
1703
|
+
}
|
|
1704
|
+
result.push(value);
|
|
1705
|
+
prevIndex = value;
|
|
1706
|
+
}
|
|
1707
|
+
return result;
|
|
1708
|
+
}
|
|
1709
|
+
function nvi(close, volume) {
|
|
1710
|
+
return volumeIndex(close, volume, (v, prevV) => v < prevV);
|
|
1711
|
+
}
|
|
1712
|
+
function pvi(close, volume) {
|
|
1713
|
+
return volumeIndex(close, volume, (v, prevV) => v > prevV);
|
|
1714
|
+
}
|
|
1715
|
+
//# sourceMappingURL=index.js.map
|