@backtest-kit/graph 6.10.0 → 6.12.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 CHANGED
@@ -99,7 +99,7 @@ npm install @backtest-kit/graph backtest-kit
99
99
  - 🔒 **Type-safe values**: TypeScript infers the return type of every node through the graph via generics
100
100
  - 🧱 **Two APIs**: Low-level `INode` for runtime/storage, high-level `TypedNode` + builders for authoring
101
101
  - 💾 **DB-ready serialization**: `serialize` / `deserialize` convert the graph to a flat `IFlatNode[]` list with `id` / `nodeIds`
102
- - 🔌 **Context-aware fetch**: `SourceNode.fetch` receives `(symbol, when, exchangeName)` from the execution context automatically
102
+ - 🔌 **Context-aware fetch**: `SourceNode.fetch` receives `(symbol, when, currentPrice, exchangeName)` from the execution context automatically
103
103
 
104
104
  ## 📖 Usage
105
105
 
@@ -110,14 +110,14 @@ Use `sourceNode` and `outputNode` to define a typed computation graph. TypeScrip
110
110
  ```typescript
111
111
  import { sourceNode, outputNode, resolve } from '@backtest-kit/graph';
112
112
 
113
- // SourceNode<number> — fetch receives symbol, when, exchangeName from context
114
- const closePrice = sourceNode(async (symbol, when, exchangeName) => {
113
+ // SourceNode<number> — fetch receives symbol, when, currentPrice, exchangeName from context
114
+ const closePrice = sourceNode(async (symbol, when, currentPrice, exchangeName) => {
115
115
  const candles = await getCandles(symbol, '1h', 1, exchangeName);
116
116
  return candles[0].close; // number
117
117
  });
118
118
 
119
119
  // SourceNode<number>
120
- const volume = sourceNode(async (symbol, when, exchangeName) => {
120
+ const volume = sourceNode(async (symbol, when, currentPrice, exchangeName) => {
121
121
  const candles = await getCandles(symbol, '1h', 1, exchangeName);
122
122
  return candles[0].volume; // number
123
123
  });
@@ -147,14 +147,14 @@ const signal: TypedNode = {
147
147
  nodes: [
148
148
  {
149
149
  type: NodeType.SourceNode,
150
- fetch: async (symbol, when, exchangeName) => {
150
+ fetch: async (symbol, when, currentPrice, exchangeName) => {
151
151
  const plots = await run(File.fromPath('timeframe_4h.pine'), { symbol, timeframe: '4h', limit: 100 });
152
152
  return extract(plots, { allowLong: 'AllowLong', allowShort: 'AllowShort', noTrades: 'NoTrades' });
153
153
  },
154
154
  },
155
155
  {
156
156
  type: NodeType.SourceNode,
157
- fetch: async (symbol, when, exchangeName) => {
157
+ fetch: async (symbol, when, currentPrice, exchangeName) => {
158
158
  const plots = await run(File.fromPath('timeframe_15m.pine'), { symbol, timeframe: '15m', limit: 100 });
159
159
  return extract(plots, { position: 'Signal', priceOpen: 'Close', priceTakeProfit: 'TakeProfit', priceStopLoss: 'StopLoss' });
160
160
  },
@@ -195,7 +195,7 @@ const result = outputNode(
195
195
  import { addStrategy } from 'backtest-kit';
196
196
  import { sourceNode, outputNode, resolve } from '@backtest-kit/graph';
197
197
 
198
- const rsi = sourceNode(async (symbol, when, exchangeName) => {
198
+ const rsi = sourceNode(async (symbol, when, currentPrice, exchangeName) => {
199
199
  // ... compute RSI
200
200
  return 55.2;
201
201
  });
@@ -229,7 +229,7 @@ import NodeType from '@backtest-kit/graph/enum/NodeType';
229
229
  const priceNode: INode = {
230
230
  type: NodeType.SourceNode,
231
231
  description: 'Close price',
232
- fetch: async (symbol, when, exchangeName) => 42,
232
+ fetch: async (symbol, when, currentPrice, exchangeName) => 42,
233
233
  };
234
234
 
235
235
  const outputNode: INode = {
package/build/index.cjs CHANGED
@@ -50,10 +50,11 @@ async function resolve(node) {
50
50
  if (node.type === NodeType$1.SourceNode) {
51
51
  const { symbol, when } = backtestKit.lib.executionContextService.context;
52
52
  const { exchangeName } = backtestKit.lib.methodContextService.context;
53
- return node.fetch(symbol, when, exchangeName);
53
+ const currentPrice = await backtestKit.getAveragePrice(symbol);
54
+ return await node.fetch(symbol, when, currentPrice, exchangeName);
54
55
  }
55
56
  const values = await Promise.all(node.nodes.map(resolve));
56
- return node.compute(values);
57
+ return await node.compute(values);
57
58
  }
58
59
 
59
60
  /**
package/build/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { ExecutionContextService, MethodContextService, lib } from 'backtest-kit';
1
+ import { ExecutionContextService, MethodContextService, lib, getAveragePrice } from 'backtest-kit';
2
2
  import { randomString } from 'functools-kit';
3
3
 
4
4
  var NodeType;
@@ -48,10 +48,11 @@ async function resolve(node) {
48
48
  if (node.type === NodeType$1.SourceNode) {
49
49
  const { symbol, when } = lib.executionContextService.context;
50
50
  const { exchangeName } = lib.methodContextService.context;
51
- return node.fetch(symbol, when, exchangeName);
51
+ const currentPrice = await getAveragePrice(symbol);
52
+ return await node.fetch(symbol, when, currentPrice, exchangeName);
52
53
  }
53
54
  const values = await Promise.all(node.nodes.map(resolve));
54
- return node.compute(values);
55
+ return await node.compute(values);
55
56
  }
56
57
 
57
58
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtest-kit/graph",
3
- "version": "6.10.0",
3
+ "version": "6.12.0",
4
4
  "description": "Compose backtest-kit computations as a typed directed acyclic graph. Define source nodes that fetch market data and output nodes that compute derived values — then resolve the whole graph in topological order.",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
@@ -67,17 +67,17 @@
67
67
  "ts-morph": "27.0.2",
68
68
  "tslib": "2.7.0",
69
69
  "typedoc": "0.27.9",
70
- "backtest-kit": "6.10.0",
70
+ "backtest-kit": "6.12.0",
71
71
  "worker-testbed": "2.0.0"
72
72
  },
73
73
  "peerDependencies": {
74
- "backtest-kit": "^6.10.0",
74
+ "backtest-kit": "^6.12.0",
75
75
  "typescript": "^5.0.0"
76
76
  },
77
77
  "dependencies": {
78
78
  "di-kit": "^1.1.1",
79
79
  "di-scoped": "^1.0.21",
80
- "functools-kit": "^2.0.1",
80
+ "functools-kit": "^2.0.2",
81
81
  "get-moment-stamp": "^1.1.2"
82
82
  },
83
83
  "publishConfig": {
package/types.d.ts CHANGED
@@ -27,7 +27,7 @@ interface INode {
27
27
  * Источник данных для SourceNode.
28
28
  * Вызывается при вычислении узла без входящих зависимостей.
29
29
  */
30
- fetch?: (symbol: string, when: Date, exchangeName: ExchangeName) => Promise<Value> | Value;
30
+ fetch?: (symbol: string, when: Date, currentPrice: number, exchangeName: ExchangeName) => Promise<Value> | Value;
31
31
  /**
32
32
  * Функция вычисления для OutputNode.
33
33
  * Получает на вход массив значений, возвращённых fetch/compute
@@ -60,7 +60,7 @@ type InferNodeValue<T extends TypedNode> = T extends SourceNode<infer V> ? V : T
60
60
  type SourceNode<T extends Value = Value> = {
61
61
  type: NodeType.SourceNode;
62
62
  description?: string;
63
- fetch: (symbol: string, when: Date, exchangeName: ExchangeName) => Promise<T> | T;
63
+ fetch: (symbol: string, when: Date, currentPrice: number, exchangeName: ExchangeName) => Promise<T> | T;
64
64
  };
65
65
  /**
66
66
  * Узел вычисления. TNodes — tuple входящих зависимостей,
@@ -79,7 +79,7 @@ type OutputNode<TNodes extends TypedNode[] = TypedNode[], TResult extends Value
79
79
  */
80
80
  type TypedNode = SourceNode<Value> | OutputNode<TypedNode[], Value>;
81
81
 
82
- declare const sourceNode: <T extends Value>(fetch: (symbol: string, when: Date, exchangeName: ExchangeName) => Promise<T> | T) => SourceNode<T>;
82
+ declare const sourceNode: <T extends Value>(fetch: (symbol: string, when: Date, currentPrice: number, exchangeName: ExchangeName) => Promise<T> | T) => SourceNode<T>;
83
83
  declare const outputNode: <TNodes extends TypedNode[], TResult extends Value = Value>(compute: (values: InferValues<TNodes>) => Promise<TResult> | TResult, ...nodes: TNodes) => OutputNode<TNodes, TResult>;
84
84
 
85
85
  /**
@@ -124,7 +124,7 @@ interface IFlatNode {
124
124
  * Источник данных для SourceNode — не сериализуется в БД,
125
125
  * восстанавливается на стороне приложения.
126
126
  */
127
- fetch?: (symbol: string, when: Date, exchangeName: ExchangeName) => Promise<Value> | Value;
127
+ fetch?: (symbol: string, when: Date, currentPrice: number, exchangeName: ExchangeName) => Promise<Value> | Value;
128
128
  /**
129
129
  * Функция вычисления для OutputNode — не сериализуется в БД,
130
130
  * восстанавливается на стороне приложения.