From 477d7580a870cf0d705a7dbf08a2fc945b918e68 Mon Sep 17 00:00:00 2001 From: alaa-eddine Date: Sun, 15 Mar 2026 15:05:35 +0100 Subject: [PATCH] update precision updated documentation --- docs/api-coverage.md | 54 +-- docs/architecture/index.md | 42 +-- docs/data-providers.md | 461 ++++++++++++++++++++++++ docs/getting-started.md | 12 + docs/indicators/cross-signal/index.html | 2 +- docs/indicators/sqzmom/index.html | 2 +- docs/indicators/willvixfix/index.html | 2 +- docs/initialization-and-usage.md | 24 +- docs/js/chart-script.js | 2 +- docs/js/indicators/WillVixFix.js | 2 +- docs/js/indicators/instit-bias.js | 2 +- docs/js/indicators/macd.js | 2 +- docs/js/indicators/sqzmom.js | 2 +- docs/lang-coverage.md | 6 +- docs/syntax-guide.md | 2 +- src/namespaces/math/methods/__eq.ts | 2 +- src/namespaces/math/methods/__neq.ts | 2 +- tests/compatibility/lib/serializer.ts | 6 +- tests/core/functions.test.ts | 4 +- 19 files changed, 548 insertions(+), 83 deletions(-) create mode 100644 docs/data-providers.md diff --git a/docs/api-coverage.md b/docs/api-coverage.md index d446685..ccdd6c1 100644 --- a/docs/api-coverage.md +++ b/docs/api-coverage.md @@ -1,7 +1,7 @@ --- layout: default title: API Coverage -nav_order: 6 +nav_order: 9 permalink: /api-coverage/ has_children: true --- @@ -12,32 +12,32 @@ This is a list of all the functions in the Pine Script API and their implementat ## Key -- ✅ Implemented and Tested -- ✔️ Implemented but needs testing -- ❌ Not implemented -- ⏳ In progress +- ✅ Implemented and Tested +- ✔️ Implemented but needs testing +- ❌ Not implemented +- ⏳ In progress --- -- [Input](./api-coverage/input.md) -- [Math](./api-coverage/math.md) -- [Technical Analysis](./api-coverage/ta.md) -- [Array](./api-coverage/array.md) -- [Box](./api-coverage/box.md) -- [Chart](./api-coverage/chart.md) -- [Color](./api-coverage/color.md) -- [Label](./api-coverage/label.md) -- [Line](./api-coverage/line.md) -- [Linefill](./api-coverage/linefill.md) -- [Log](./api-coverage/log.md) -- [Map](./api-coverage/map.md) -- [Matrix](./api-coverage/matrix.md) -- [Plot](./api-coverage/plot.md) -- [Request](./api-coverage/request.md) -- [String](./api-coverage/string.md) -- [Strategy](./api-coverage/strategy.md) -- [Table](./api-coverage/table.md) -- [Syminfo](./api-coverage/syminfo.md) -- [Runtime](./api-coverage/runtime.md) -- [Polyline](./api-coverage/polyline.md) -- [Others](./api-coverage/others.md) +- [Input](./api-coverage/input.md) +- [Math](./api-coverage/math.md) +- [Technical Analysis](./api-coverage/ta.md) +- [Array](./api-coverage/array.md) +- [Box](./api-coverage/box.md) +- [Chart](./api-coverage/chart.md) +- [Color](./api-coverage/color.md) +- [Label](./api-coverage/label.md) +- [Line](./api-coverage/line.md) +- [Linefill](./api-coverage/linefill.md) +- [Log](./api-coverage/log.md) +- [Map](./api-coverage/map.md) +- [Matrix](./api-coverage/matrix.md) +- [Plot](./api-coverage/plot.md) +- [Request](./api-coverage/request.md) +- [String](./api-coverage/string.md) +- [Strategy](./api-coverage/strategy.md) +- [Table](./api-coverage/table.md) +- [Syminfo](./api-coverage/syminfo.md) +- [Runtime](./api-coverage/runtime.md) +- [Polyline](./api-coverage/polyline.md) +- [Others](./api-coverage/others.md) diff --git a/docs/architecture/index.md b/docs/architecture/index.md index 8fa33d1..50ef76a 100644 --- a/docs/architecture/index.md +++ b/docs/architecture/index.md @@ -1,7 +1,7 @@ --- layout: default title: Architecture -nav_order: 4 +nav_order: 7 has_children: true permalink: /architecture/ --- @@ -50,29 +50,29 @@ PineTS bridges the gap between Pine Script's unique time-series semantics and st ### Core Architecture -- [Transpiler Architecture](./transpiler/index.md): Details on AST parsing, scope analysis, and code transformation. - - [Scope Manager](./transpiler/scope-manager.md): Variable renaming and unique ID generation - - [Transformers](./transpiler/transformers.md): AST transformation logic - - [Real Examples](./transpiler/examples.md): Actual transpilation output examples -- [Runtime Engine](./runtime/index.md): How the `Context`, `Series`, and execution loop work. - - [Context Class](./runtime/context.md): The global state object - - [Series Class](./runtime/series.md): Forward storage with reverse access - - [Execution Flow](./runtime/execution-flow.md): Run loop and pagination -- [Namespaces](./namespaces/index.md): Implementation of `ta`, `math`, `request`, etc. - - [Technical Analysis (ta)](./namespaces/ta.md): TA functions implementation - - [Math (math)](./namespaces/math.md): Mathematical operations - - [Array (array)](./namespaces/array.md): Array operations - - [Request (request)](./namespaces/request.md): Multi-timeframe analysis - - [Input (input)](./namespaces/input.md): User input handling -- [Critical Implementation Details](./specifics/index.md): Deep dives into tuple handling, `request.security`, and other complex features. - - [Tuple Handling](./specifics/tuples.md): Double bracket convention - - [Request Security](./specifics/request-security.md): Secondary context architecture +- [Transpiler Architecture](./transpiler/index.md): Details on AST parsing, scope analysis, and code transformation. + - [Scope Manager](./transpiler/scope-manager.md): Variable renaming and unique ID generation + - [Transformers](./transpiler/transformers.md): AST transformation logic + - [Real Examples](./transpiler/examples.md): Actual transpilation output examples +- [Runtime Engine](./runtime/index.md): How the `Context`, `Series`, and execution loop work. + - [Context Class](./runtime/context.md): The global state object + - [Series Class](./runtime/series.md): Forward storage with reverse access + - [Execution Flow](./runtime/execution-flow.md): Run loop and pagination +- [Namespaces](./namespaces/index.md): Implementation of `ta`, `math`, `request`, etc. + - [Technical Analysis (ta)](./namespaces/ta.md): TA functions implementation + - [Math (math)](./namespaces/math.md): Mathematical operations + - [Array (array)](./namespaces/array.md): Array operations + - [Request (request)](./namespaces/request.md): Multi-timeframe analysis + - [Input (input)](./namespaces/input.md): User input handling +- [Critical Implementation Details](./specifics/index.md): Deep dives into tuple handling, `request.security`, and other complex features. + - [Tuple Handling](./specifics/tuples.md): Double bracket convention + - [Request Security](./specifics/request-security.md): Secondary context architecture ### Developer Resources -- [Debugging Guide](./debugging.md): Practical debugging techniques and common issues -- [Best Practices](./best-practices.md): Common pitfalls and recommended patterns -- [Syntax Evolution](./syntax-evolution.md): Migration from old to new syntax +- [Debugging Guide](./debugging.md): Practical debugging techniques and common issues +- [Best Practices](./best-practices.md): Common pitfalls and recommended patterns +- [Syntax Evolution](./syntax-evolution.md): Migration from old to new syntax ## Key Design Principles diff --git a/docs/data-providers.md b/docs/data-providers.md new file mode 100644 index 0000000..0711554 --- /dev/null +++ b/docs/data-providers.md @@ -0,0 +1,461 @@ +--- +layout: default +title: Data Providers +nav_order: 5 +permalink: /data-providers/ +--- + +# Data Providers + +PineTS supports multiple market data providers out of the box. Each provider fetches OHLCV candle data and symbol metadata, which PineTS uses to run your indicators. + +--- + +## Overview + +There are two ways to use a provider: + +**1. Singleton** (from the `Provider` registry): + +```typescript +import { PineTS, Provider } from 'pinets'; + +const pine = new PineTS(Provider.Binance, 'BTCUSDT', 'D', 100); +``` + +**2. Direct instantiation** (for provider-specific config): + +```typescript +import { PineTS, BinanceProvider } from 'pinets'; + +const binance = new BinanceProvider(); +const pine = new PineTS(binance, 'BTCUSDT', 'D', 100); +``` + +Providers that require API keys must be configured before use, either via `.configure()` on the singleton or by passing config to the constructor. + +### Timeframe Aggregation + +If a provider doesn't natively support a requested timeframe, PineTS automatically selects the best sub-timeframe and aggregates candles. For example, requesting `'45'` (45 min) from Binance will fetch `'15'` minute candles and aggregate 3:1. This is handled transparently by the `BaseProvider` class. + +--- + +## Binance + +The Binance provider fetches cryptocurrency market data. **No API key required.** + +### Quick Start + +```typescript +import { PineTS, Provider } from 'pinets'; + +// Fetch 100 daily BTC candles and compute SMA +const pine = new PineTS(Provider.Binance, 'BTCUSDT', 'D', 100); + +const { result, plots } = await pine.run(` +//@version=6 +indicator("BTC SMA Cross") +sma20 = ta.sma(close, 20) +sma50 = ta.sma(close, 50) +plot(sma20, "SMA 20", color.blue) +plot(sma50, "SMA 50", color.red) +`); +``` + +### Symbols + +| Format | Example | Market | +| -------- | -------------------- | ------ | +| `SYMBOL` | `BTCUSDT`, `ETHUSDC` | Spot | + +### Supported Timeframes + +`'1'`, `'3'`, `'5'`, `'15'`, `'30'`, `'60'`, `'120'`, `'240'`, `'D'`, `'W'`, `'M'` + +Timeframes not in this list (e.g., `'45'`, `'180'`) are automatically aggregated from smaller candles. + +### Features + +- **No API key** required +- **Auto-pagination** for fetching >1000 candles +- **5-minute cache** for repeated identical requests +- **Dual endpoint fallback**: tries `api.binance.com`, falls back to `api.binance.us` + +### Examples + +```typescript +import { PineTS, Provider, BinanceProvider } from 'pinets'; + +// Using the singleton +const pine1 = new PineTS(Provider.Binance, 'BTCUSDT', 'D', 100); + +// Direct instantiation (equivalent) +const binance = new BinanceProvider(); +const pine2 = new PineTS(binance, 'ETHUSDT', '1W', 50); + +// With date range +const sDate = new Date('2024-01-01').getTime(); +const eDate = new Date('2024-06-30').getTime(); +const pine3 = new PineTS(Provider.Binance, 'BTCUSDT', 'D', undefined, sDate, eDate); +``` + +--- + +## FMP (Financial Modeling Prep) + +The FMP provider fetches stock, forex, and crypto data from [Financial Modeling Prep](https://financialmodelingprep.com/). **Requires an API key.** + +### Quick Start + +```typescript +import { PineTS, Provider } from 'pinets'; + +// Configure with your API key +Provider.FMP.configure({ apiKey: 'your-api-key' }); + +// Fetch 200 daily AAPL candles +const pine = new PineTS(Provider.FMP, 'AAPL', 'D', 200); + +const { result } = await pine.run(` +//@version=6 +indicator("AAPL RSI") +rsi = ta.rsi(close, 14) +plot(rsi, "RSI") +hline(70, "Overbought") +hline(30, "Oversold") +`); +``` + +### Configuration + +```typescript +// Option 1: Configure the singleton +Provider.FMP.configure({ apiKey: 'your-api-key' }); + +// Option 2: Direct instantiation with config +import { FMPProvider } from 'pinets'; +const fmp = new FMPProvider({ apiKey: 'your-api-key' }); +const pine = new PineTS(fmp, 'AAPL', 'D', 200); +``` + +| Option | Type | Required | Description | +| --------- | -------- | -------- | ------------------------- | +| `apiKey` | `string` | Yes | Your FMP API key | +| `baseUrl` | `string` | No | Override the API base URL | + +### Symbols + +| Format | Example | Market | +| ------ | --------------------- | -------------- | +| Ticker | `AAPL`, `MSFT`, `SPY` | US Stocks | +| Crypto | `BTCUSD`, `ETHUSD` | Cryptocurrency | +| Forex | `EURUSD` | Currency pairs | + +### Supported Timeframes + +| Tier | Timeframes | +| -------- | --------------------------------------------- | +| **Free** | `'D'` (daily only) | +| **Paid** | `'1'`, `'5'`, `'15'`, `'30'`, `'60'`, `'240'` | + +### Features + +- **Exchange-aware session times**: maps exchanges to IANA timezones (e.g., NYSE = `America/New_York`, `0930-1600`) +- **Session-aware closeTime**: correctly computes bar close times including early-close days +- **Profile caching**: symbol metadata is fetched once and cached + +### Examples + +```typescript +import { PineTS, Provider, FMPProvider } from 'pinets'; + +// Configure singleton +Provider.FMP.configure({ apiKey: 'your-api-key' }); + +// US Stock +const pine1 = new PineTS(Provider.FMP, 'AAPL', 'D', 200); + +// Crypto via FMP +const pine2 = new PineTS(Provider.FMP, 'BTCUSD', 'D', 100); + +// Forex +const pine3 = new PineTS(Provider.FMP, 'EURUSD', 'D', 100); + +// Direct instantiation (separate instance with its own config) +const fmp = new FMPProvider({ apiKey: 'different-api-key' }); +const pine4 = new PineTS(fmp, 'MSFT', 'D', 100); +``` + +--- + +## Alpaca + +The Alpaca provider fetches US stock and crypto data from [Alpaca Markets](https://alpaca.markets/). **Requires an API key and secret.** + +### Quick Start + +```typescript +import { PineTS, Provider } from 'pinets'; + +// Configure with your credentials +Provider.Alpaca.configure({ + apiKey: 'PK...', + apiSecret: '...', + paper: true, + feed: 'iex', +}); + +// Fetch 200 daily AAPL candles +const pine = new PineTS(Provider.Alpaca, 'AAPL', 'D', 200); + +const { result } = await pine.run(` +//@version=6 +indicator("AAPL Bollinger Bands") +[middle, upper, lower] = ta.bb(close, 20, 2) +plot(middle, "Middle", color.blue) +plot(upper, "Upper", color.green) +plot(lower, "Lower", color.red) +`); +``` + +### Configuration + +```typescript +// Option 1: Configure the singleton +Provider.Alpaca.configure({ + apiKey: 'PK...', + apiSecret: '...', + paper: true, + feed: 'sip', +}); + +// Option 2: Direct instantiation +import { AlpacaProvider } from 'pinets'; +const alpaca = new AlpacaProvider({ + apiKey: 'PK...', + apiSecret: '...', + paper: true, + feed: 'iex', +}); +const pine = new PineTS(alpaca, 'AAPL', 'D', 200); +``` + +| Option | Type | Required | Default | Description | +| ------------ | ---------------- | -------- | ------- | ---------------------------------------------------------------- | +| `apiKey` | `string` | Yes | - | Alpaca API key ID (`PK...`) | +| `apiSecret` | `string` | Yes | - | Alpaca secret key | +| `paper` | `boolean` | No | `true` | `true` for paper trading, `false` for live | +| `feed` | `'sip' \| 'iex'` | No | `'sip'` | `'sip'` = full market data (paid), `'iex'` = IEX exchange (free) | +| `dataUrl` | `string` | No | - | Override the market data API URL | +| `tradingUrl` | `string` | No | - | Override the trading/asset API URL | + +### Symbols + +| Format | Example | Market | +| ------ | --------------------- | ------------------------------- | +| Ticker | `AAPL`, `MSFT`, `SPY` | US Stocks | +| Crypto | `BTC/USD`, `ETH/USD` | Cryptocurrency (note the slash) | + +> **Note:** Crypto symbols use slash notation (`BTC/USD`), not concatenated (`BTCUSD`). + +### Supported Timeframes + +`'1'`, `'3'`, `'5'`, `'15'`, `'30'`, `'45'`, `'60'`, `'120'`, `'180'`, `'240'`, `'D'`, `'W'`, `'M'` + +Alpaca natively supports all common timeframes including `'45'` and `'180'` which other providers aggregate. + +### Features + +- **Calendar-aware closeTime** for stocks: uses Alpaca's trading calendar API for exact session times (handles early closes and DST) +- **Fixed-duration closeTime** for crypto: 24/7 markets use computed period boundaries +- **Auto-pagination**: handles large requests (10,000+ candles) via page tokens +- **Asset and calendar caching**: symbol info and trading calendar fetched once per session + +### Data Feed Options + +| Feed | Cost | Coverage | +| ------- | --------------- | --------------------------------------------------- | +| `'sip'` | Paid ($9/month) | Full consolidated market data from all US exchanges | +| `'iex'` | Free | IEX exchange data only (may have gaps or lag) | + +### Examples + +```typescript +import { PineTS, Provider, AlpacaProvider } from 'pinets'; + +// Configure singleton +Provider.Alpaca.configure({ + apiKey: 'PK...', + apiSecret: '...', + paper: true, + feed: 'iex', +}); + +// US Stock +const pine1 = new PineTS(Provider.Alpaca, 'AAPL', 'D', 200); + +// Crypto (note the slash notation) +const pine2 = new PineTS(Provider.Alpaca, 'BTC/USD', 'D', 100); + +// Direct instantiation +const alpaca = new AlpacaProvider({ + apiKey: 'PK...', + apiSecret: '...', + feed: 'sip', +}); +const pine3 = new PineTS(alpaca, 'MSFT', '60', 500); +``` + +--- + +## Custom Data + +You can bypass providers entirely by passing your own OHLCV data array: + +```typescript +import { PineTS } from 'pinets'; + +const customData = [ + { + openTime: new Date('2024-01-01').getTime(), + open: 42000, + high: 43000, + low: 41500, + close: 42500, + volume: 1234.56, + closeTime: new Date('2024-01-02').getTime(), + }, + { + openTime: new Date('2024-01-02').getTime(), + open: 42500, + high: 44000, + low: 42000, + close: 43800, + volume: 2345.67, + closeTime: new Date('2024-01-03').getTime(), + }, + // ... more candles +]; + +const pine = new PineTS(customData); +const { result } = await pine.run(` +//@version=6 +indicator("Custom Data SMA") +plot(ta.sma(close, 10)) +`); +``` + +### Data Format + +Each candle object must include: + +| Field | Type | Required | Description | +| ----------- | -------- | -------- | ----------------------------- | +| `open` | `number` | Yes | Opening price | +| `high` | `number` | Yes | Highest price | +| `low` | `number` | Yes | Lowest price | +| `close` | `number` | Yes | Closing price | +| `volume` | `number` | Yes | Trading volume | +| `openTime` | `number` | No | Bar open time (ms timestamp) | +| `closeTime` | `number` | No | Bar close time (ms timestamp) | + +If `openTime` / `closeTime` are omitted, time-dependent functions (`time`, `hour`, `dayofmonth`, etc.) will not work correctly. + +--- + +## Custom Providers + +You can create your own provider by implementing the `IProvider` interface or extending `BaseProvider`: + +```typescript +import { BaseProvider, PineTS } from 'pinets'; +import type { ISymbolInfo, Kline } from 'pinets'; + +class MyProvider extends BaseProvider { + constructor() { + super({ requiresApiKey: false, providerName: 'MyProvider' }); + } + + protected getSupportedTimeframes() { + return new Set(['1', '5', '15', '60', 'D']); + } + + protected async _getMarketDataNative(tickerId: string, timeframe: string, limit?: number, sDate?: number, eDate?: number): Promise { + // Fetch data from your API + const response = await fetch(`https://my-api.com/candles?symbol=${tickerId}&tf=${timeframe}`); + const data = await response.json(); + + return data.map((candle) => ({ + openTime: candle.time, + open: candle.o, + high: candle.h, + low: candle.l, + close: candle.c, + volume: candle.v, + closeTime: candle.time + 86400000, // next bar open + })); + } + + async getSymbolInfo(tickerId: string): Promise { + // Return symbol metadata + return { ticker: tickerId /* ... */ } as ISymbolInfo; + } +} + +// Use it +const provider = new MyProvider(); +const pine = new PineTS(provider, 'AAPL', 'D', 100); +``` + +By extending `BaseProvider`, you get automatic timeframe aggregation for free. If you request a timeframe not in `getSupportedTimeframes()`, the base class will automatically fetch a supported sub-timeframe and aggregate. + +You can also add your provider to the global registry for convenience: + +```typescript +import { Provider } from 'pinets'; + +Provider['MyProvider'] = new MyProvider(); +// Now available as Provider.MyProvider +``` + +--- + +## Timeframe Reference + +Standard timeframe strings used across all providers: + +| String | Description | Period | +| ----------------- | ----------- | -------- | +| `'1'` | 1 minute | Intraday | +| `'3'` | 3 minutes | Intraday | +| `'5'` | 5 minutes | Intraday | +| `'15'` | 15 minutes | Intraday | +| `'30'` | 30 minutes | Intraday | +| `'45'` | 45 minutes | Intraday | +| `'60'` | 1 hour | Intraday | +| `'120'` | 2 hours | Intraday | +| `'180'` | 3 hours | Intraday | +| `'240'` or `'4H'` | 4 hours | Intraday | +| `'D'` or `'1D'` | 1 day | Daily | +| `'W'` or `'1W'` | 1 week | Weekly | +| `'M'` or `'1M'` | 1 month | Monthly | + +### Provider Support Matrix + +| Timeframe | Binance | FMP (Free) | FMP (Paid) | Alpaca | +| --------- | ---------- | ---------- | ---------- | ------ | +| `'1'` | Native | - | Native | Native | +| `'3'` | Native | - | - | Native | +| `'5'` | Native | - | Native | Native | +| `'15'` | Native | - | Native | Native | +| `'30'` | Native | - | Native | Native | +| `'45'` | Aggregated | - | - | Native | +| `'60'` | Native | - | Native | Native | +| `'120'` | Native | - | - | Native | +| `'180'` | Aggregated | - | - | Native | +| `'240'` | Native | - | Native | Native | +| `'D'` | Native | Native | Native | Native | +| `'W'` | Native | - | - | Native | +| `'M'` | Native | - | - | Native | + +**Native** = provider fetches directly. **Aggregated** = PineTS fetches smaller candles and combines them. **-** = not available. diff --git a/docs/getting-started.md b/docs/getting-started.md index 20cba23..ba131bb 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -210,6 +210,18 @@ When using **PineTS syntax** (Option 2), note these differences from native Pine When using **Native Pine Script** (Option 1), write code exactly as you would in TradingView - no conversion needed! +## Data Providers + +PineTS includes built-in providers for multiple data sources: + +| Provider | Market | API Key | +| --- | --- | --- | +| `Provider.Binance` | Crypto | Not required | +| `Provider.FMP` | Stocks, forex, crypto | Required | +| `Provider.Alpaca` | US stocks, crypto | Required | + +You can also pass your own OHLCV data array instead of using a provider. See the **[Data Providers](../data-providers/)** page for configuration details and examples. + ## Core Components ### PineTS Class diff --git a/docs/indicators/cross-signal/index.html b/docs/indicators/cross-signal/index.html index 6132cff..17cfa8c 100644 --- a/docs/indicators/cross-signal/index.html +++ b/docs/indicators/cross-signal/index.html @@ -40,7 +40,7 @@

PineScript Demo