@pear-protocol/market-sdk 0.0.13 → 0.1.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/README.md +27 -0
- package/dist/chart/cache/index.d.ts +1 -1
- package/dist/chart/cache/index.js +15 -3
- package/dist/chart/chart.d.ts +1 -1
- package/dist/chart/chart.js +14 -23
- package/dist/chart/collector/binance.d.ts +1 -1
- package/dist/chart/collector/binance.js +4 -0
- package/dist/chart/collector/bybit.d.ts +1 -1
- package/dist/chart/collector/bybit.js +12 -1
- package/dist/chart/collector/helpers.d.ts +2 -2
- package/dist/chart/collector/helpers.js +5 -2
- package/dist/chart/collector/hyperliquid.d.ts +1 -1
- package/dist/chart/collector/hyperliquid.js +12 -2
- package/dist/chart/collector/index.d.ts +1 -1
- package/dist/chart/collector/index.js +28 -12
- package/dist/chart/collector/lighter.d.ts +2 -2
- package/dist/chart/collector/lighter.js +10 -4
- package/dist/chart/collector/okx.d.ts +1 -1
- package/dist/chart/collector/okx.js +12 -1
- package/dist/chart/compute/asset.d.ts +1 -1
- package/dist/chart/compute/asset.js +4 -0
- package/dist/chart/compute/index.d.ts +1 -1
- package/dist/chart/compute/performance.d.ts +1 -1
- package/dist/chart/compute/performance.js +20 -4
- package/dist/chart/compute/price-ratio.d.ts +1 -1
- package/dist/chart/compute/price-ratio.js +8 -1
- package/dist/chart/compute/weighted-ratio.d.ts +1 -1
- package/dist/chart/compute/weighted-ratio.js +9 -1
- package/dist/chart/types.d.ts +1 -1
- package/dist/chart/utils.d.ts +1 -1
- package/dist/chart/utils.js +19 -11
- package/dist/chart/ws/base-candle.d.ts +11 -5
- package/dist/chart/ws/base-candle.js +6 -2
- package/dist/chart/ws/binance.d.ts +4 -6
- package/dist/chart/ws/binance.js +33 -19
- package/dist/chart/ws/bybit.d.ts +4 -6
- package/dist/chart/ws/bybit.js +40 -24
- package/dist/chart/ws/hyperliquid.d.ts +4 -6
- package/dist/chart/ws/hyperliquid.js +37 -19
- package/dist/chart/ws/index.js +3 -0
- package/dist/chart/ws/lighter.d.ts +20 -20
- package/dist/chart/ws/lighter.js +83 -196
- package/dist/chart/ws/okx.d.ts +4 -6
- package/dist/chart/ws/okx.js +47 -23
- package/dist/funding-rate/fetcher/binance.d.ts +1 -1
- package/dist/funding-rate/fetcher/binance.js +7 -1
- package/dist/funding-rate/fetcher/bybit.d.ts +1 -1
- package/dist/funding-rate/fetcher/bybit.js +15 -13
- package/dist/funding-rate/fetcher/http-client.d.ts +1 -1
- package/dist/funding-rate/fetcher/http-client.js +15 -10
- package/dist/funding-rate/fetcher/hyperliquid.d.ts +1 -1
- package/dist/funding-rate/fetcher/hyperliquid.js +7 -1
- package/dist/funding-rate/fetcher/index.d.ts +2 -2
- package/dist/funding-rate/fetcher/index.js +5 -2
- package/dist/funding-rate/fetcher/lighter.d.ts +2 -2
- package/dist/funding-rate/fetcher/lighter.js +11 -3
- package/dist/funding-rate/fetcher/okx.d.ts +1 -1
- package/dist/funding-rate/fetcher/okx.js +14 -12
- package/dist/funding-rate/funding-rate.d.ts +1 -1
- package/dist/funding-rate/funding-rate.js +30 -21
- package/dist/funding-rate/types.d.ts +1 -1
- package/dist/funding-rate/utils.d.ts +1 -1
- package/dist/funding-rate/utils.js +26 -5
- package/dist/index.d.ts +2 -2
- package/dist/orderbook/book/aggregate.d.ts +1 -1
- package/dist/orderbook/book/aggregate.js +16 -3
- package/dist/orderbook/book/local-book.d.ts +1 -1
- package/dist/orderbook/book/local-book.js +16 -5
- package/dist/orderbook/orderbook.d.ts +1 -1
- package/dist/orderbook/orderbook.js +29 -13
- package/dist/orderbook/types.d.ts +1 -1
- package/dist/orderbook/types.js +7 -1
- package/dist/orderbook/utils.d.ts +1 -1
- package/dist/orderbook/utils.js +5 -0
- package/dist/orderbook/ws/base-depth.js +10 -1
- package/dist/orderbook/ws/binance.js +28 -7
- package/dist/orderbook/ws/bybit.js +20 -5
- package/dist/orderbook/ws/hyperliquid.js +31 -11
- package/dist/orderbook/ws/index.js +3 -0
- package/dist/orderbook/ws/lighter.js +30 -7
- package/dist/orderbook/ws/okx.js +23 -2
- package/dist/shared/types.d.ts +6 -1
- package/dist/transport/base-transport.d.ts +4 -0
- package/dist/transport/base-transport.js +13 -0
- package/dist/transport/binance.js +5 -0
- package/dist/transport/bybit.js +8 -1
- package/dist/transport/hyperliquid.js +8 -1
- package/dist/transport/index.d.ts +11 -3
- package/dist/transport/index.js +5 -2
- package/dist/transport/lighter.d.ts +31 -1
- package/dist/transport/lighter.js +86 -1
- package/dist/transport/okx.js +5 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -70,6 +70,33 @@ orderbook.destroy();
|
|
|
70
70
|
transport.destroy();
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
## Transport
|
|
74
|
+
|
|
75
|
+
`CreateTransport(connector)` builds the connection every feature shares. Pass it to `Chart`,
|
|
76
|
+
`Orderbook`, and `FundingRate`, then `destroy()` it once when you are done.
|
|
77
|
+
|
|
78
|
+
### Lighter rate limits
|
|
79
|
+
|
|
80
|
+
Lighter grants a wider rate limit to requests it can attribute to an account, on public market data
|
|
81
|
+
as well as private endpoints. Supply a token provider and this SDK sends it on Lighter's candle and
|
|
82
|
+
funding reads (`authorization` header) and on its candle and order-book subscriptions (`auth` field):
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { CreateTransport } from '@pear-protocol/market-sdk';
|
|
86
|
+
import { retrieveLighterAuthToken } from '@pear-protocol/exchanges-sdk';
|
|
87
|
+
|
|
88
|
+
const transport = CreateTransport('lighter', {
|
|
89
|
+
authToken: () => retrieveLighterAuthToken(sdk, credentials, false),
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This SDK never holds Lighter credentials — the caller mints the token and owns its cache.
|
|
94
|
+
`retrieveLighterAuthToken` is the same cache the account trackers use, so both SDKs share one token.
|
|
95
|
+
|
|
96
|
+
Everything is optional. Omit `authToken`, or resolve `undefined` for a visitor with no connected
|
|
97
|
+
account, and every request goes out anonymously. A failed mint logs a warning and falls back to
|
|
98
|
+
anonymous rather than breaking the market data.
|
|
99
|
+
|
|
73
100
|
## Chart
|
|
74
101
|
|
|
75
102
|
### Initialization
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleInterval, CandleData, HistoricalRange } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare class CandleCache {
|
|
9
9
|
private historicalPriceData;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { createKey, mergeRanges, getIntervalSeconds } from '../utils';
|
|
2
2
|
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
5
|
class CandleCache {
|
|
6
|
+
static {
|
|
7
|
+
__name(this, "CandleCache");
|
|
8
|
+
}
|
|
4
9
|
historicalPriceData = {};
|
|
5
10
|
loadingTokens = /* @__PURE__ */ new Set();
|
|
6
11
|
addLoadingToken(symbol) {
|
|
@@ -13,7 +18,9 @@ class CandleCache {
|
|
|
13
18
|
const key = createKey(symbol, interval);
|
|
14
19
|
const existing = this.historicalPriceData[key];
|
|
15
20
|
if (!existing) {
|
|
16
|
-
const sortedCandles = [
|
|
21
|
+
const sortedCandles = [
|
|
22
|
+
...candles
|
|
23
|
+
].sort((a, b) => a.t - b.t);
|
|
17
24
|
const noDataBefore2 = sortedCandles.length === 0 ? range.end : null;
|
|
18
25
|
this.historicalPriceData[key] = {
|
|
19
26
|
symbol,
|
|
@@ -21,14 +28,19 @@ class CandleCache {
|
|
|
21
28
|
candles: sortedCandles,
|
|
22
29
|
oldestTime: sortedCandles.length > 0 ? sortedCandles[0]?.t ?? null : null,
|
|
23
30
|
latestTime: sortedCandles.length > 0 ? sortedCandles[sortedCandles.length - 1]?.t ?? null : null,
|
|
24
|
-
requestedRanges: [
|
|
31
|
+
requestedRanges: [
|
|
32
|
+
range
|
|
33
|
+
],
|
|
25
34
|
noDataBefore: noDataBefore2
|
|
26
35
|
};
|
|
27
36
|
return;
|
|
28
37
|
}
|
|
29
38
|
const existingTimes = new Set(existing.candles.map((c) => c.t));
|
|
30
39
|
const newCandles = candles.filter((c) => !existingTimes.has(c.t));
|
|
31
|
-
const mergedCandles = [
|
|
40
|
+
const mergedCandles = [
|
|
41
|
+
...existing.candles,
|
|
42
|
+
...newCandles
|
|
43
|
+
].sort((a, b) => a.t - b.t);
|
|
32
44
|
const oldestTime = mergedCandles.length > 0 ? mergedCandles[0]?.t ?? null : null;
|
|
33
45
|
const latestTime = mergedCandles.length > 0 ? mergedCandles[mergedCandles.length - 1]?.t ?? null : null;
|
|
34
46
|
const mergedRanges = mergeRanges(existing.requestedRanges, range);
|
package/dist/chart/chart.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ChartConfig, TokenSelection, CandleInterval, ChartType, Bar, RealtimeBarCallback } from './types.js';
|
|
2
2
|
import '../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../shared/types.js';
|
|
4
5
|
import '../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare class Chart {
|
|
9
9
|
private collector;
|
package/dist/chart/chart.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { DataCollector } from './collector';
|
|
2
2
|
import { computePerformanceCandles, computePriceRatioCandles, computeWeightedRatioCandles, computeAssetBars, computeRealtimePerformanceBar, computeRealtimePriceRatioBar, computeRealtimeWeightedRatioBar, computeRealtimeAssetBar } from './compute/index';
|
|
3
3
|
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
6
|
class Chart {
|
|
7
|
+
static {
|
|
8
|
+
__name(this, "Chart");
|
|
9
|
+
}
|
|
5
10
|
collector;
|
|
6
11
|
baselinePrices = {};
|
|
7
12
|
constructor(config) {
|
|
@@ -20,21 +25,13 @@ class Chart {
|
|
|
20
25
|
const tokenCandles = await this.collector.fetchHistoricalPriceData(startTime, endTime, interval);
|
|
21
26
|
switch (chartType) {
|
|
22
27
|
case "weighted-ratio": {
|
|
23
|
-
return computeWeightedRatioCandles(
|
|
24
|
-
this.collector.getLongTokens(),
|
|
25
|
-
this.collector.getShortTokens(),
|
|
26
|
-
tokenCandles
|
|
27
|
-
);
|
|
28
|
+
return computeWeightedRatioCandles(this.collector.getLongTokens(), this.collector.getShortTokens(), tokenCandles);
|
|
28
29
|
}
|
|
29
30
|
case "price-ratio": {
|
|
30
31
|
return computePriceRatioCandles(this.collector.getLongTokens(), this.collector.getShortTokens(), tokenCandles);
|
|
31
32
|
}
|
|
32
33
|
case "performance": {
|
|
33
|
-
const result = computePerformanceCandles(
|
|
34
|
-
this.collector.getLongTokens(),
|
|
35
|
-
this.collector.getShortTokens(),
|
|
36
|
-
tokenCandles
|
|
37
|
-
);
|
|
34
|
+
const result = computePerformanceCandles(this.collector.getLongTokens(), this.collector.getShortTokens(), tokenCandles);
|
|
38
35
|
if (result.bars.length > 0) {
|
|
39
36
|
this.baselinePrices = result.baselinePrices;
|
|
40
37
|
}
|
|
@@ -57,7 +54,7 @@ class Chart {
|
|
|
57
54
|
if (!this.collector.isWsAttached) {
|
|
58
55
|
this.collector.attachCandleWs();
|
|
59
56
|
}
|
|
60
|
-
const formatTokens = (tokens) => tokens.map((t) => `${t.symbol}:${t.weight}`).join(",");
|
|
57
|
+
const formatTokens = /* @__PURE__ */ __name((tokens) => tokens.map((t) => `${t.symbol}:${t.weight}`).join(","), "formatTokens");
|
|
61
58
|
const id = `${chartType}-${formatTokens(this.collector.getLongTokens())}-${formatTokens(this.collector.getShortTokens())}`;
|
|
62
59
|
this.collector.addRealtimeListener(id, () => {
|
|
63
60
|
const snapshot = this.collector.getLatestCandles();
|
|
@@ -65,23 +62,14 @@ class Chart {
|
|
|
65
62
|
let bar = null;
|
|
66
63
|
switch (chartType) {
|
|
67
64
|
case "weighted-ratio":
|
|
68
|
-
bar = computeRealtimeWeightedRatioBar(
|
|
69
|
-
this.collector.getLongTokens(),
|
|
70
|
-
this.collector.getShortTokens(),
|
|
71
|
-
snapshot
|
|
72
|
-
);
|
|
65
|
+
bar = computeRealtimeWeightedRatioBar(this.collector.getLongTokens(), this.collector.getShortTokens(), snapshot);
|
|
73
66
|
break;
|
|
74
67
|
case "price-ratio":
|
|
75
68
|
bar = computeRealtimePriceRatioBar(this.collector.getLongTokens(), this.collector.getShortTokens(), snapshot);
|
|
76
69
|
break;
|
|
77
70
|
case "performance":
|
|
78
71
|
if (Object.keys(this.baselinePrices).length === 0) break;
|
|
79
|
-
bar = computeRealtimePerformanceBar(
|
|
80
|
-
this.collector.getLongTokens(),
|
|
81
|
-
this.collector.getShortTokens(),
|
|
82
|
-
snapshot,
|
|
83
|
-
this.baselinePrices
|
|
84
|
-
);
|
|
72
|
+
bar = computeRealtimePerformanceBar(this.collector.getLongTokens(), this.collector.getShortTokens(), snapshot, this.baselinePrices);
|
|
85
73
|
break;
|
|
86
74
|
}
|
|
87
75
|
if (bar) {
|
|
@@ -124,7 +112,10 @@ class Chart {
|
|
|
124
112
|
this.collector.removeRealtimeListener(id);
|
|
125
113
|
}
|
|
126
114
|
assertTokenExists(symbol) {
|
|
127
|
-
const allTokens = [
|
|
115
|
+
const allTokens = [
|
|
116
|
+
...this.collector.getLongTokens(),
|
|
117
|
+
...this.collector.getShortTokens()
|
|
118
|
+
];
|
|
128
119
|
if (!allTokens.some((t) => t.symbol === symbol)) {
|
|
129
120
|
throw new Error(`Symbol "${symbol}" is not part of the configured long or short tokens`);
|
|
130
121
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function fetchHistoricalCandles(symbol: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
9
9
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
const BINANCE_FUTURES_URL = "https://fapi.binance.com/fapi/v1/klines";
|
|
2
4
|
const MAX_LIMIT = 1e3;
|
|
3
5
|
function toCandleData(kline) {
|
|
@@ -10,6 +12,7 @@ function toCandleData(kline) {
|
|
|
10
12
|
c: Number(kline[4])
|
|
11
13
|
};
|
|
12
14
|
}
|
|
15
|
+
__name(toCandleData, "toCandleData");
|
|
13
16
|
async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
14
17
|
const params = new URLSearchParams({
|
|
15
18
|
symbol,
|
|
@@ -23,5 +26,6 @@ async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
|
23
26
|
const data = await response.json();
|
|
24
27
|
return data.map(toCandleData);
|
|
25
28
|
}
|
|
29
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
26
30
|
|
|
27
31
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function fetchHistoricalCandles(symbol: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
9
9
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
const BYBIT_URL = "https://api.bybit.com/v5/market/kline";
|
|
2
4
|
const MAX_LIMIT = 1e3;
|
|
3
5
|
const intervalMap = {
|
|
@@ -18,8 +20,16 @@ const intervalMap = {
|
|
|
18
20
|
};
|
|
19
21
|
function toCandleData(item) {
|
|
20
22
|
const startMs = Number(item[0]);
|
|
21
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
t: startMs,
|
|
25
|
+
T: startMs,
|
|
26
|
+
o: Number(item[1]),
|
|
27
|
+
h: Number(item[2]),
|
|
28
|
+
l: Number(item[3]),
|
|
29
|
+
c: Number(item[4])
|
|
30
|
+
};
|
|
22
31
|
}
|
|
32
|
+
__name(toCandleData, "toCandleData");
|
|
23
33
|
async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
24
34
|
const params = new URLSearchParams({
|
|
25
35
|
category: "linear",
|
|
@@ -35,5 +45,6 @@ async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
|
35
45
|
if (data.retCode !== 0) throw new Error(`Bybit API error: ${data.retMsg}`);
|
|
36
46
|
return data.result.list.reverse().map((item) => toCandleData(item));
|
|
37
47
|
}
|
|
48
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
38
49
|
|
|
39
50
|
export { fetchHistoricalCandles };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Connector } from '@pear-protocol/types';
|
|
2
2
|
import { CandleInterval, CandleData } from '../types.js';
|
|
3
3
|
import '../../transport/index.js';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
|
-
declare function fetchHistoricalCandles(connector: Connector, symbol: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
8
|
+
declare function fetchHistoricalCandles(connector: Connector, symbol: string, startTime: number, endTime: number, interval: CandleInterval, authToken?: string): Promise<CandleData[]>;
|
|
9
9
|
|
|
10
10
|
export { fetchHistoricalCandles };
|
|
@@ -4,7 +4,9 @@ import { fetchHistoricalCandles as fetchHistoricalCandles$5 } from './hyperliqui
|
|
|
4
4
|
import { fetchHistoricalCandles as fetchHistoricalCandles$1 } from './lighter';
|
|
5
5
|
import { fetchHistoricalCandles as fetchHistoricalCandles$2 } from './okx';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
async function fetchHistoricalCandles(connector, symbol, startTime, endTime, interval, authToken) {
|
|
8
10
|
switch (connector) {
|
|
9
11
|
case "hyperliquid":
|
|
10
12
|
return fetchHistoricalCandles$5(symbol, startTime, endTime, interval);
|
|
@@ -15,10 +17,11 @@ async function fetchHistoricalCandles(connector, symbol, startTime, endTime, int
|
|
|
15
17
|
case "okx":
|
|
16
18
|
return fetchHistoricalCandles$2(symbol, startTime, endTime, interval);
|
|
17
19
|
case "lighter":
|
|
18
|
-
return fetchHistoricalCandles$1(symbol, startTime, endTime, interval);
|
|
20
|
+
return fetchHistoricalCandles$1(symbol, startTime, endTime, interval, authToken);
|
|
19
21
|
default:
|
|
20
22
|
throw new Error(`Unsupported connector: ${connector}`);
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
23
26
|
|
|
24
27
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function fetchHistoricalCandles(symbol: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
9
9
|
|
|
@@ -1,15 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
2
4
|
const request = {
|
|
3
|
-
req: {
|
|
5
|
+
req: {
|
|
6
|
+
coin: symbol,
|
|
7
|
+
startTime,
|
|
8
|
+
endTime,
|
|
9
|
+
interval
|
|
10
|
+
},
|
|
4
11
|
type: "candleSnapshot"
|
|
5
12
|
};
|
|
6
13
|
const response = await fetch("https://api.hyperliquid.xyz/info", {
|
|
7
14
|
method: "POST",
|
|
8
|
-
headers: {
|
|
15
|
+
headers: {
|
|
16
|
+
"Content-Type": "application/json"
|
|
17
|
+
},
|
|
9
18
|
body: JSON.stringify(request)
|
|
10
19
|
});
|
|
11
20
|
if (!response.ok) throw new Error(`Hyperliquid API error: ${response.status} ${response.statusText}`);
|
|
12
21
|
return response.json();
|
|
13
22
|
}
|
|
23
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
14
24
|
|
|
15
25
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ChartConfig, TokenSelection, CandleInterval, RealtimeCandleCallback, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare class DataCollector {
|
|
9
9
|
private transport;
|
|
@@ -2,7 +2,12 @@ import { CandleCache } from '../cache';
|
|
|
2
2
|
import { createCandleWs } from '../ws';
|
|
3
3
|
import { fetchHistoricalCandles } from './helpers';
|
|
4
4
|
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
7
|
class DataCollector {
|
|
8
|
+
static {
|
|
9
|
+
__name(this, "DataCollector");
|
|
10
|
+
}
|
|
6
11
|
transport;
|
|
7
12
|
longTokens;
|
|
8
13
|
shortTokens;
|
|
@@ -56,7 +61,9 @@ class DataCollector {
|
|
|
56
61
|
for (const token of this.getAllTokens()) {
|
|
57
62
|
const latestCandle = this.cache.getLatestCandle(token.symbol, this.candleInterval);
|
|
58
63
|
if (latestCandle) {
|
|
59
|
-
this.candleWs.onHistoricalDataFetched(token.symbol, this.candleInterval, [
|
|
64
|
+
this.candleWs.onHistoricalDataFetched(token.symbol, this.candleInterval, [
|
|
65
|
+
latestCandle
|
|
66
|
+
]);
|
|
60
67
|
}
|
|
61
68
|
this.candleWs.subscribe(token.symbol, this.candleInterval);
|
|
62
69
|
}
|
|
@@ -120,22 +127,28 @@ class DataCollector {
|
|
|
120
127
|
for (const token of tokensToFetch) {
|
|
121
128
|
this.cache.addLoadingToken(token.symbol);
|
|
122
129
|
}
|
|
130
|
+
const authToken = await this.transport.retrieveAuthToken();
|
|
123
131
|
try {
|
|
124
132
|
const fetchPromises = tokensToFetch.map(async (token) => {
|
|
125
133
|
try {
|
|
126
|
-
const candles = await fetchHistoricalCandles(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
interval
|
|
132
|
-
);
|
|
133
|
-
this.cache.addHistoricalPriceData(token.symbol, interval, candles, { start: startTime, end: endTime });
|
|
134
|
+
const candles = await fetchHistoricalCandles(this.transport.connector, token.symbol, startTime, endTime, interval, authToken);
|
|
135
|
+
this.cache.addHistoricalPriceData(token.symbol, interval, candles, {
|
|
136
|
+
start: startTime,
|
|
137
|
+
end: endTime
|
|
138
|
+
});
|
|
134
139
|
this.candleWs?.onHistoricalDataFetched(token.symbol, interval, candles);
|
|
135
|
-
return {
|
|
140
|
+
return {
|
|
141
|
+
symbol: token.symbol,
|
|
142
|
+
candles,
|
|
143
|
+
success: true
|
|
144
|
+
};
|
|
136
145
|
} catch (error) {
|
|
137
146
|
console.warn(`Failed to fetch historical data for ${token.symbol}:`, error);
|
|
138
|
-
return {
|
|
147
|
+
return {
|
|
148
|
+
symbol: token.symbol,
|
|
149
|
+
candles: [],
|
|
150
|
+
success: false
|
|
151
|
+
};
|
|
139
152
|
}
|
|
140
153
|
});
|
|
141
154
|
await Promise.all(fetchPromises);
|
|
@@ -158,7 +171,10 @@ class DataCollector {
|
|
|
158
171
|
this.cache.clear();
|
|
159
172
|
}
|
|
160
173
|
getAllTokens() {
|
|
161
|
-
return [
|
|
174
|
+
return [
|
|
175
|
+
...this.longTokens,
|
|
176
|
+
...this.shortTokens
|
|
177
|
+
];
|
|
162
178
|
}
|
|
163
179
|
syncTokenChanges() {
|
|
164
180
|
const currentSymbols = new Set(this.getAllTokens().map((t) => t.symbol));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
|
-
declare function fetchHistoricalCandles(symbol: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
8
|
+
declare function fetchHistoricalCandles(symbol: string, startTime: number, endTime: number, interval: CandleInterval, authToken?: string): Promise<CandleData[]>;
|
|
9
9
|
|
|
10
10
|
export { fetchHistoricalCandles };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getIntervalSeconds } from '../utils';
|
|
2
2
|
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
5
|
const BASE_URL = "https://mainnet.zklighter.elliot.ai";
|
|
4
6
|
const MAX_LIMIT = 500;
|
|
5
7
|
const RESOLUTION_MAP = {
|
|
@@ -10,10 +12,9 @@ const RESOLUTION_MAP = {
|
|
|
10
12
|
"1h": "1h",
|
|
11
13
|
"4h": "4h",
|
|
12
14
|
"12h": "12h",
|
|
13
|
-
"1d": "1d"
|
|
14
|
-
"1w": "1w"
|
|
15
|
+
"1d": "1d"
|
|
15
16
|
};
|
|
16
|
-
async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
17
|
+
async function fetchHistoricalCandles(symbol, startTime, endTime, interval, authToken) {
|
|
17
18
|
const resolution = RESOLUTION_MAP[interval];
|
|
18
19
|
if (!resolution) throw new Error(`Lighter does not support the '${interval}' interval`);
|
|
19
20
|
const intervalMs = getIntervalSeconds(interval) * 1e3;
|
|
@@ -25,7 +26,11 @@ async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
|
25
26
|
end_timestamp: String(endTime),
|
|
26
27
|
count_back: String(countBack)
|
|
27
28
|
});
|
|
28
|
-
const response = await fetch(`${BASE_URL}/api/v1/candles?${params}
|
|
29
|
+
const response = await fetch(`${BASE_URL}/api/v1/candles?${params}`, authToken ? {
|
|
30
|
+
headers: {
|
|
31
|
+
authorization: authToken
|
|
32
|
+
}
|
|
33
|
+
} : void 0);
|
|
29
34
|
if (!response.ok) throw new Error(`Lighter API error: ${response.status} ${response.statusText}`);
|
|
30
35
|
const data = await response.json();
|
|
31
36
|
if (data.code !== 200) throw new Error(`Lighter API error: ${data.message ?? String(data.code)}`);
|
|
@@ -38,5 +43,6 @@ async function fetchHistoricalCandles(symbol, startTime, endTime, interval) {
|
|
|
38
43
|
c: candle.c ?? 0
|
|
39
44
|
}));
|
|
40
45
|
}
|
|
46
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
41
47
|
|
|
42
48
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function fetchHistoricalCandles(instId: string, startTime: number, endTime: number, interval: CandleInterval): Promise<CandleData[]>;
|
|
9
9
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
const OKX_URL = "https://www.okx.com/api/v5/market/candles";
|
|
2
4
|
const MAX_LIMIT = 300;
|
|
3
5
|
const intervalMap = {
|
|
@@ -18,8 +20,16 @@ const intervalMap = {
|
|
|
18
20
|
};
|
|
19
21
|
function toCandleData(item) {
|
|
20
22
|
const startMs = Number(item[0]);
|
|
21
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
t: startMs,
|
|
25
|
+
T: startMs,
|
|
26
|
+
o: Number(item[1]),
|
|
27
|
+
h: Number(item[2]),
|
|
28
|
+
l: Number(item[3]),
|
|
29
|
+
c: Number(item[4])
|
|
30
|
+
};
|
|
22
31
|
}
|
|
32
|
+
__name(toCandleData, "toCandleData");
|
|
23
33
|
async function fetchHistoricalCandles(instId, startTime, endTime, interval) {
|
|
24
34
|
const params = new URLSearchParams({
|
|
25
35
|
instId,
|
|
@@ -34,5 +44,6 @@ async function fetchHistoricalCandles(instId, startTime, endTime, interval) {
|
|
|
34
44
|
if (data.code !== "0") throw new Error(`OKX API error: ${data.msg}`);
|
|
35
45
|
return data.data.reverse().map(toCandleData);
|
|
36
46
|
}
|
|
47
|
+
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
37
48
|
|
|
38
49
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CandleData, Bar } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function computeAssetBars(tokenCandles: Record<string, CandleData[]>, symbol: string): Bar[];
|
|
9
9
|
declare function computeRealtimeAssetBar(snapshot: Record<string, CandleData>, symbol: string): Bar | null;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
function computeAssetBars(tokenCandles, symbol) {
|
|
2
4
|
const candles = tokenCandles[symbol];
|
|
3
5
|
if (!candles) return [];
|
|
@@ -9,6 +11,7 @@ function computeAssetBars(tokenCandles, symbol) {
|
|
|
9
11
|
close: c.c
|
|
10
12
|
}));
|
|
11
13
|
}
|
|
14
|
+
__name(computeAssetBars, "computeAssetBars");
|
|
12
15
|
function computeRealtimeAssetBar(snapshot, symbol) {
|
|
13
16
|
const candle = snapshot[symbol];
|
|
14
17
|
if (!candle) return null;
|
|
@@ -20,5 +23,6 @@ function computeRealtimeAssetBar(snapshot, symbol) {
|
|
|
20
23
|
close: candle.c
|
|
21
24
|
};
|
|
22
25
|
}
|
|
26
|
+
__name(computeRealtimeAssetBar, "computeRealtimeAssetBar");
|
|
23
27
|
|
|
24
28
|
export { computeAssetBars, computeRealtimeAssetBar };
|
|
@@ -5,6 +5,6 @@ export { computeRealtimeWeightedRatioBar, computeWeightedRatioCandles } from './
|
|
|
5
5
|
import '../types.js';
|
|
6
6
|
import '../../transport/index.js';
|
|
7
7
|
import '@pear-protocol/types';
|
|
8
|
+
import '../../shared/types.js';
|
|
8
9
|
import '../../transport/base-transport.js';
|
|
9
10
|
import 'partysocket';
|
|
10
|
-
import '../../shared/types.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { TokenSelection, CandleData, PerformanceResult, Bar } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function computePerformanceCandles(longTokens: TokenSelection[], shortTokens: TokenSelection[], tokenCandles: Record<string, CandleData[]>): PerformanceResult;
|
|
9
9
|
declare function computeRealtimePerformanceBar(longTokens: TokenSelection[], shortTokens: TokenSelection[], snapshot: Record<string, CandleData>, baselinePrices: Record<string, number>): Bar | null;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { createCandleLookups, getCompleteTimestamps } from '../utils';
|
|
2
2
|
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
5
|
function computePerformanceCandles(longTokens, shortTokens, tokenCandles) {
|
|
4
|
-
const empty = {
|
|
5
|
-
|
|
6
|
+
const empty = {
|
|
7
|
+
bars: [],
|
|
8
|
+
baselinePrices: {}
|
|
9
|
+
};
|
|
10
|
+
const allTokens = [
|
|
11
|
+
...longTokens,
|
|
12
|
+
...shortTokens
|
|
13
|
+
];
|
|
6
14
|
if (allTokens.length === 0) return empty;
|
|
7
15
|
const candleLookups = createCandleLookups(tokenCandles);
|
|
8
16
|
const allSymbols = allTokens.map((t) => t.symbol);
|
|
@@ -45,10 +53,17 @@ function computePerformanceCandles(longTokens, shortTokens, tokenCandles) {
|
|
|
45
53
|
close: portfolioValue
|
|
46
54
|
});
|
|
47
55
|
}
|
|
48
|
-
return {
|
|
56
|
+
return {
|
|
57
|
+
bars,
|
|
58
|
+
baselinePrices
|
|
59
|
+
};
|
|
49
60
|
}
|
|
61
|
+
__name(computePerformanceCandles, "computePerformanceCandles");
|
|
50
62
|
function computeRealtimePerformanceBar(longTokens, shortTokens, snapshot, baselinePrices) {
|
|
51
|
-
const allTokens = [
|
|
63
|
+
const allTokens = [
|
|
64
|
+
...longTokens,
|
|
65
|
+
...shortTokens
|
|
66
|
+
];
|
|
52
67
|
if (allTokens.length === 0) return null;
|
|
53
68
|
const initialPortfolioValue = 1e3;
|
|
54
69
|
const longSet = new Set(longTokens.map((t) => t.symbol));
|
|
@@ -77,5 +92,6 @@ function computeRealtimePerformanceBar(longTokens, shortTokens, snapshot, baseli
|
|
|
77
92
|
close: portfolioValue
|
|
78
93
|
};
|
|
79
94
|
}
|
|
95
|
+
__name(computeRealtimePerformanceBar, "computeRealtimePerformanceBar");
|
|
80
96
|
|
|
81
97
|
export { computePerformanceCandles, computeRealtimePerformanceBar };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { TokenSelection, CandleData, Bar } from '../types.js';
|
|
2
2
|
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../shared/types.js';
|
|
4
5
|
import '../../transport/base-transport.js';
|
|
5
6
|
import 'partysocket';
|
|
6
|
-
import '../../shared/types.js';
|
|
7
7
|
|
|
8
8
|
declare function computePriceRatioCandles(longTokens: TokenSelection[], shortTokens: TokenSelection[], tokenCandles: Record<string, CandleData[]>): Bar[];
|
|
9
9
|
declare function computeRealtimePriceRatioBar(longTokens: TokenSelection[], shortTokens: TokenSelection[], snapshot: Record<string, CandleData>): Bar | null;
|