oakscriptjs 0.1.5
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 +21 -0
- package/README.md +271 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 OakScriptJS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# OakScriptJS
|
|
2
|
+
|
|
3
|
+
**PineScript v6 compatible technical analysis library for JavaScript/TypeScript**
|
|
4
|
+
|
|
5
|
+
OakScriptJS provides the computational core of PineScript's API. It focuses on **calculations and data transformations** with a clean Series-based approach.
|
|
6
|
+
|
|
7
|
+
## Core Features
|
|
8
|
+
|
|
9
|
+
- **Series Class**: Lazy evaluation with operator chaining
|
|
10
|
+
- **BarData**: Versioned wrapper for automatic cache invalidation
|
|
11
|
+
- **Core Functions**: Pure array-based calculations (`taCore.*`)
|
|
12
|
+
- **TA-Series Wrappers**: Series-based technical analysis functions (`ta.*`)
|
|
13
|
+
- **Type Safety**: Full TypeScript support with type definitions
|
|
14
|
+
|
|
15
|
+
## Scope
|
|
16
|
+
|
|
17
|
+
**This library includes:**
|
|
18
|
+
- Technical Analysis (`ta.*`, `taCore.*`) - All indicators and calculations
|
|
19
|
+
- Mathematics (`math.*`) - All mathematical operations
|
|
20
|
+
- Arrays (`array.*`) - Array manipulation and operations
|
|
21
|
+
- Matrices (`matrix.*`) - Matrix operations
|
|
22
|
+
- Strings (`str.*`) - String manipulation
|
|
23
|
+
- Time (`time.*`) - Time calculations and conversions
|
|
24
|
+
- Color (`color.*`) - Color data structures and manipulation
|
|
25
|
+
- Drawing Objects (`line.*`, `box.*`, `label.*`, `linefill.*`) - Computational features only
|
|
26
|
+
- Series Class - Lazy evaluation with operator chaining
|
|
27
|
+
|
|
28
|
+
**This library does NOT include:**
|
|
29
|
+
- UI/Input functions (`input.*`) - Application responsibility
|
|
30
|
+
- Strategy execution (`strategy.*`) - Strategy engine responsibility
|
|
31
|
+
- Data fetching (`request.*`) - Data provider responsibility
|
|
32
|
+
- Alert systems (`alert.*`, `alertcondition.*`) - Application responsibility
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install oakscriptjs
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### Array-based Calculations
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { taCore } from 'oakscriptjs';
|
|
46
|
+
|
|
47
|
+
const prices = [100, 102, 101, 103, 105];
|
|
48
|
+
const sma = taCore.sma(prices, 3);
|
|
49
|
+
const rsi = taCore.rsi(prices, 14);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Series-based Calculations
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { Series, ta } from 'oakscriptjs';
|
|
56
|
+
|
|
57
|
+
const bars = [
|
|
58
|
+
{ time: '2024-01-01', open: 100, high: 105, low: 99, close: 103 },
|
|
59
|
+
{ time: '2024-01-02', open: 103, high: 107, low: 102, close: 106 }
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
const close = new Series(bars, (bar) => bar.close);
|
|
63
|
+
const rsi = ta.rsi(close, 14);
|
|
64
|
+
|
|
65
|
+
console.log(rsi.toArray());
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### BarData for Automatic Cache Invalidation
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { BarData, Series, ta } from 'oakscriptjs';
|
|
72
|
+
|
|
73
|
+
// Create BarData wrapper
|
|
74
|
+
const barData = new BarData(bars);
|
|
75
|
+
const close = Series.fromBars(barData, 'close');
|
|
76
|
+
const sma = ta.sma(close, 20);
|
|
77
|
+
|
|
78
|
+
const values1 = sma.toArray(); // Computes and caches
|
|
79
|
+
|
|
80
|
+
// Add new bar - version increments
|
|
81
|
+
barData.push({ time: '2024-01-03', open: 106, high: 108, low: 105, close: 107 });
|
|
82
|
+
|
|
83
|
+
const values2 = sma.toArray(); // Detects change, recomputes
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Memory-Efficient Closure Breaking
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { Series } from 'oakscriptjs';
|
|
90
|
+
|
|
91
|
+
// Complex expression creates closure chain
|
|
92
|
+
const complex = a.add(b).mul(c).div(d).sub(e);
|
|
93
|
+
|
|
94
|
+
// Break closure chain to free memory
|
|
95
|
+
const materialized = complex.materialize();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Supported Namespaces
|
|
99
|
+
|
|
100
|
+
### Technical Analysis (`ta` and `taCore`)
|
|
101
|
+
|
|
102
|
+
Complete implementation of PineScript's technical analysis functions:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Core (array-based)
|
|
106
|
+
import { taCore } from 'oakscriptjs';
|
|
107
|
+
taCore.sma(prices, 20)
|
|
108
|
+
taCore.ema(prices, 20)
|
|
109
|
+
taCore.rsi(prices, 14)
|
|
110
|
+
|
|
111
|
+
// Series (Series-based)
|
|
112
|
+
import { ta } from 'oakscriptjs';
|
|
113
|
+
ta.sma(closeSeries, 20)
|
|
114
|
+
ta.ema(closeSeries, 20)
|
|
115
|
+
ta.rsi(closeSeries, 14)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- **Moving Averages**: `sma()`, `ema()`, `wma()`, `vwma()`, `swma()`, etc.
|
|
119
|
+
- **Oscillators**: `rsi()`, `stoch()`, `cci()`, `macd()`, `mfi()`, etc.
|
|
120
|
+
- **Volatility**: `bb()`, `atr()`, `stdev()`, `variance()`, etc.
|
|
121
|
+
- **Momentum**: `mom()`, `roc()`, `percentrank()`, etc.
|
|
122
|
+
- **Regression**: `linreg()`, `correlation()`, etc.
|
|
123
|
+
- **Crossovers**: `crossover()`, `crossunder()`, `cross()`
|
|
124
|
+
|
|
125
|
+
### Math (`math`)
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
math.abs(x), math.ceil(x), math.floor(x), math.round(x)
|
|
129
|
+
math.min(...values), math.max(...values), math.avg(...values)
|
|
130
|
+
math.sqrt(x), math.pow(x, y), math.exp(x), math.log(x)
|
|
131
|
+
math.sin(x), math.cos(x), math.tan(x)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Array (`array`)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
array.new_float(size, initial)
|
|
138
|
+
array.push(arr, value)
|
|
139
|
+
array.get(arr, index)
|
|
140
|
+
array.sum(arr), array.avg(arr), array.sort(arr)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Series Class
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
class Series {
|
|
147
|
+
// Constructor
|
|
148
|
+
constructor(data: Bar[] | BarData, extractor: SeriesExtractor)
|
|
149
|
+
|
|
150
|
+
// Properties
|
|
151
|
+
get bars(): Bar[]
|
|
152
|
+
get barData(): BarData
|
|
153
|
+
|
|
154
|
+
// Arithmetic
|
|
155
|
+
add(other: Series | number): Series
|
|
156
|
+
sub(other: Series | number): Series
|
|
157
|
+
mul(other: Series | number): Series
|
|
158
|
+
div(other: Series | number): Series
|
|
159
|
+
|
|
160
|
+
// Comparison
|
|
161
|
+
gt(other: Series | number): Series
|
|
162
|
+
lt(other: Series | number): Series
|
|
163
|
+
|
|
164
|
+
// Logical
|
|
165
|
+
and(other: Series | number): Series
|
|
166
|
+
or(other: Series | number): Series
|
|
167
|
+
|
|
168
|
+
// Access
|
|
169
|
+
toArray(): number[]
|
|
170
|
+
last(): number
|
|
171
|
+
offset(n: number): Series // Like close[1]
|
|
172
|
+
|
|
173
|
+
// Memory management
|
|
174
|
+
materialize(): Series // Break closure chains
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### BarData Class
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
class BarData {
|
|
182
|
+
constructor(bars: Bar[])
|
|
183
|
+
|
|
184
|
+
get version(): number
|
|
185
|
+
get bars(): Bar[]
|
|
186
|
+
get length(): number
|
|
187
|
+
|
|
188
|
+
push(bar: Bar): void
|
|
189
|
+
pop(): Bar | undefined
|
|
190
|
+
set(index: number, bar: Bar): void
|
|
191
|
+
updateLast(bar: Bar): void
|
|
192
|
+
setAll(bars: Bar[]): void
|
|
193
|
+
invalidate(): void
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Drawing Objects
|
|
198
|
+
|
|
199
|
+
- **Line (`line`)**: `new()`, `get_price()`, getters/setters
|
|
200
|
+
- **Box (`box`)**: `new()`, getters/setters for gap detection
|
|
201
|
+
- **Label (`label`)**: `new()`, getters/setters
|
|
202
|
+
- **Linefill (`linefill`)**: `new()`, `set_color()`
|
|
203
|
+
|
|
204
|
+
## Examples
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Example 1: Simple Moving Average
|
|
208
|
+
import {Series, ta, type IndicatorResult} from 'oakscriptjs';
|
|
209
|
+
|
|
210
|
+
export function smaIndicator(bars: any[]): IndicatorResult {
|
|
211
|
+
const close = new Series(bars, (bar) => bar.close);
|
|
212
|
+
const sma20 = ta.sma(close, 20);
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
metadata: { title: "SMA 20", overlay: true },
|
|
216
|
+
plots: [{
|
|
217
|
+
data: sma20.toArray().map((v, i) => ({ time: bars[i].time, value: v })),
|
|
218
|
+
options: { color: '#2196F3', linewidth: 2 }
|
|
219
|
+
}]
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Example 2: RSI
|
|
224
|
+
export function rsiIndicator(bars: any[]): IndicatorResult {
|
|
225
|
+
const close = new Series(bars, (bar) => bar.close);
|
|
226
|
+
const rsi = ta.rsi(close, 14);
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
metadata: { title: "RSI", overlay: false },
|
|
230
|
+
plots: [{
|
|
231
|
+
data: rsi.toArray().map((v, i) => ({ time: bars[i].time, value: v })),
|
|
232
|
+
options: { color: '#FF5722', linewidth: 2 }
|
|
233
|
+
}],
|
|
234
|
+
hlines: [
|
|
235
|
+
{ value: 70, options: { color: '#FF0000' } },
|
|
236
|
+
{ value: 30, options: { color: '#00FF00' } }
|
|
237
|
+
]
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Development
|
|
243
|
+
|
|
244
|
+
### Setup
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
npm install
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Build
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm run build
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Test
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
npm test
|
|
260
|
+
npm run test:watch
|
|
261
|
+
npm run test:coverage
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Documentation
|
|
265
|
+
|
|
266
|
+
- **[Complete Guide](../../docs/guide.md)** - User guide and examples
|
|
267
|
+
- **[Function Inventory](../../docs/inventory.md)** - Complete function list with status
|
|
268
|
+
|
|
269
|
+
## Acknowledgments
|
|
270
|
+
|
|
271
|
+
This library is inspired by TradingView's PineScript language. It is not affiliated with or endorsed by TradingView.
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oakscriptjs",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "PineScript v6 compatible technical analysis library for JavaScript/TypeScript",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./runtime": {
|
|
16
|
+
"types": "./dist/runtime/index.d.ts",
|
|
17
|
+
"import": "./dist/runtime/index.mjs",
|
|
18
|
+
"require": "./dist/runtime/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"pinescript",
|
|
28
|
+
"trading",
|
|
29
|
+
"technical-analysis",
|
|
30
|
+
"indicators",
|
|
31
|
+
"charting",
|
|
32
|
+
"oakscript",
|
|
33
|
+
"ta",
|
|
34
|
+
"finance",
|
|
35
|
+
"stocks",
|
|
36
|
+
"crypto"
|
|
37
|
+
],
|
|
38
|
+
"author": "Odyssée",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/deepentropy/oakscriptJS.git",
|
|
43
|
+
"directory": "packages/oakscriptjs"
|
|
44
|
+
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/deepentropy/oakscriptJS/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/deepentropy/oakscriptJS#readme",
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"lightweight-charts": "^5.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/jest": "^29.5.11",
|
|
54
|
+
"@types/node": "^20.10.6",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
|
56
|
+
"@typescript-eslint/parser": "^6.16.0",
|
|
57
|
+
"esbuild": "^0.19.11",
|
|
58
|
+
"eslint": "^8.56.0",
|
|
59
|
+
"jest": "^29.7.0",
|
|
60
|
+
"lightweight-charts": "^5.0.0",
|
|
61
|
+
"prettier": "^3.1.1",
|
|
62
|
+
"rimraf": "^6.1.0",
|
|
63
|
+
"ts-jest": "^29.1.1",
|
|
64
|
+
"typescript": "^5.3.3"
|
|
65
|
+
},
|
|
66
|
+
"engines": {
|
|
67
|
+
"node": ">=16.0.0"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:runtime:esm && npm run build:runtime:cjs && npm run build:types",
|
|
71
|
+
"build:esm": "esbuild src/index.ts --bundle --format=esm --outfile=dist/index.mjs --platform=neutral --external:@types/* --external:lightweight-charts",
|
|
72
|
+
"build:cjs": "esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.js --platform=neutral --external:@types/* --external:lightweight-charts",
|
|
73
|
+
"build:runtime:esm": "esbuild src/runtime/index.ts --bundle --format=esm --outfile=dist/runtime/index.mjs --platform=neutral --external:@types/* --external:lightweight-charts",
|
|
74
|
+
"build:runtime:cjs": "esbuild src/runtime/index.ts --bundle --format=cjs --outfile=dist/runtime/index.js --platform=neutral --external:@types/* --external:lightweight-charts",
|
|
75
|
+
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
76
|
+
"clean": "rimraf dist",
|
|
77
|
+
"dev": "tsc --watch",
|
|
78
|
+
"test": "jest",
|
|
79
|
+
"test:watch": "jest --watch",
|
|
80
|
+
"test:coverage": "jest --coverage",
|
|
81
|
+
"lint": "eslint src --ext .ts",
|
|
82
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
83
|
+
"typecheck": "tsc --noEmit",
|
|
84
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
85
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
86
|
+
}
|
|
87
|
+
}
|