Skip to content

Commit f25f6eb

Browse files
committed
Add : PineTS.stream() method, an event driven wrapper of PineTS.run to simplify handling live data
Critical fix : live data processing was producing wrong values in ta.* functions due to wrong handling of current vs committed candles
1 parent 8e4fd50 commit f25f6eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2403
-1132
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,33 @@ npm install pinets
7171

7272
## Usage Examples
7373

74+
### Streaming Data
75+
76+
PineTS provides a convenient event-based interface for streaming live data:
77+
78+
```javascript
79+
import { PineTS, Provider } from 'pinets';
80+
81+
const pineTS = new PineTS(Provider.Binance, 'BTCUSDT', '1m');
82+
83+
// Start streaming with 1 second interval
84+
const evt = pineTS.stream(
85+
indicator,
86+
//assuming that indicator is a pine source code or pineTS function
87+
{
88+
pageSize: 10,
89+
live: true,
90+
interval: 1000,
91+
}
92+
);
93+
94+
evt.on('data', (ctx) => {
95+
console.log('Update:', ctx.result.close);
96+
});
97+
98+
// See documentation for full details
99+
```
100+
74101
### Option 1: Run Native Pine Script Directly _(Experimental)_
75102

76103
Starting with v0.7.0, you can run original Pine Script code directly:

docs/getting-started.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,44 +127,50 @@ const { result } = await pineTS.run((context) => {
127127
});
128128
```
129129

130-
## Using Pagination for Large Datasets
130+
## Streaming Data and Pagination
131131

132-
For processing large datasets efficiently or streaming live market data, use pagination:
132+
For processing large datasets efficiently or handling live data streams, use the `stream()` method:
133133

134134
```javascript
135135
import { PineTS, Provider } from 'pinets';
136136

137-
// Initialize with a provider for live streaming capability
138-
const pineTS = new PineTS(Provider.Binance, 'BTCUSDT', '1h');
137+
// Initialize with a provider
138+
const pineTS = new PineTS(Provider.Binance, 'BTCUSDT', '1m', 100);
139139

140-
// Process 200 candles in pages of 50
141-
const iterator = pineTS.run(
140+
// Start streaming
141+
const evt = pineTS.stream(
142142
(context) => {
143-
const ta = context.ta;
144143
const { close } = context.data;
145-
146-
const sma = ta.sma(close, 20);
147-
return { sma };
144+
const sma = context.ta.sma(close, 14);
145+
return { close, sma };
148146
},
149-
200,
150-
50
147+
{
148+
pageSize: 50, // Process in chunks of 50
149+
live: true, // Continue with live data
150+
interval: 2000, // Poll every 2 seconds
151+
}
151152
);
152153

153-
// Process each page as it becomes available
154-
for await (const page of iterator) {
155-
console.log(`Received ${page.result.sma.length} results`);
156-
// With a provider and no end date, automatically continues with live data
157-
}
154+
// Listen for updates
155+
evt.on('data', (ctx) => {
156+
const { close, sma } = ctx.result;
157+
console.log(`Update: Close=${close[close.length - 1]}, SMA=${sma[sma.length - 1]}`);
158+
});
159+
160+
evt.on('error', (err) => console.error(err));
161+
162+
// To stop streaming later
163+
// evt.stop();
158164
```
159165

160166
**Benefits:**
161167

162168
- Memory efficient for large datasets
163-
- Shows progress during processing
164-
- Automatically streams live market data when using a provider
169+
- Event-based interface is easier to integrate
170+
- Automatically streams live market data
165171
- Perfect for real-time trading bots and dashboards
166172

167-
📖 **For complete pagination documentation and advanced examples, see [Pagination & Live Streaming](../pagination/).**
173+
📖 **For complete pagination and streaming documentation, see [Pagination & Live Streaming](../pagination/).**
168174

169175
## Key Differences: PineTS Syntax vs Native Pine Script
170176

docs/initialization-and-usage.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This guide explains how to initialize PineTS and run indicators or strategies wi
1515
- [PineTS Constructor](#pinets-constructor)
1616
- [Initialization Options](#initialization-options)
1717
- [The run() Method](#the-run-method)
18+
- [The stream() Method](#the-stream-method)
1819
- [Context Object](#context-object)
1920
- [Return Values](#return-values)
2021
- [Complete Examples](#complete-examples)
@@ -281,6 +282,56 @@ Returns a `Promise<Context>` object containing:
281282

282283
---
283284

285+
## The stream() Method
286+
287+
The `stream()` method provides an event-based interface for handling live data streams, making it easy to integrate with real-time applications.
288+
289+
### Syntax
290+
291+
```typescript
292+
const evt = pineTS.stream(
293+
pineTSCode: Function | String,
294+
options?: {
295+
pageSize?: number,
296+
live?: boolean,
297+
interval?: number
298+
}
299+
);
300+
```
301+
302+
### Options
303+
304+
| Option | Type | Default | Description |
305+
| ---------- | --------- | ----------------- | ---------------------------------------------------------------------------------------------- |
306+
| `pageSize` | `number` | `undefined` (all) | Number of bars per chunk. If not specified, processes all available historical data in one go. |
307+
| `live` | `boolean` | `true` | Whether to continue fetching live data after processing historical data. |
308+
| `interval` | `number` | `1000` | Polling interval in milliseconds for live data. |
309+
310+
### Usage
311+
312+
The method returns an object with `on()` and `stop()` methods:
313+
314+
```typescript
315+
// Start streaming
316+
const evt = pineTS.stream(indicator, { pageSize: 1, live: true, interval: 2000 });
317+
318+
// Handle data updates
319+
evt.on('data', (context) => {
320+
// Process new data
321+
console.log('New data:', context.result);
322+
});
323+
324+
// Handle errors
325+
evt.on('error', (error) => {
326+
console.error('Stream error:', error);
327+
});
328+
329+
// Stop streaming
330+
// evt.stop();
331+
```
332+
333+
---
334+
284335
## Context Object
285336

286337
The context object is passed to your indicator function and contains all the data and utilities needed for calculations.

0 commit comments

Comments
 (0)