@helloxiaohu/plugin-stock-portfolio-constructor 0.0.1
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 +3 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/portfolio-constructor.d.ts +20 -0
- package/dist/lib/portfolio-constructor.d.ts.map +1 -0
- package/dist/lib/portfolio-constructor.js +191 -0
- package/dist/lib/portfolio-constructor.js.map +1 -0
- package/dist/lib/stock-portfolio-constructor.plugin.d.ts +3 -0
- package/dist/lib/stock-portfolio-constructor.plugin.d.ts.map +1 -0
- package/dist/lib/stock-portfolio-constructor.plugin.js +15 -0
- package/dist/lib/stock-portfolio-constructor.plugin.js.map +1 -0
- package/dist/lib/stock-portfolio-constructor.strategy.d.ts +245 -0
- package/dist/lib/stock-portfolio-constructor.strategy.d.ts.map +1 -0
- package/dist/lib/stock-portfolio-constructor.strategy.js +67 -0
- package/dist/lib/stock-portfolio-constructor.strategy.js.map +1 -0
- package/dist/lib/tools/portfolio-build-target.tool.d.ts +87 -0
- package/dist/lib/tools/portfolio-build-target.tool.d.ts.map +1 -0
- package/dist/lib/tools/portfolio-build-target.tool.js +48 -0
- package/dist/lib/tools/portfolio-build-target.tool.js.map +1 -0
- package/dist/lib/tools/portfolio-rebalance-plan.tool.d.ts +110 -0
- package/dist/lib/tools/portfolio-rebalance-plan.tool.d.ts.map +1 -0
- package/dist/lib/tools/portfolio-rebalance-plan.tool.js +54 -0
- package/dist/lib/tools/portfolio-rebalance-plan.tool.js.map +1 -0
- package/dist/lib/toolset.d.ts +7 -0
- package/dist/lib/toolset.d.ts.map +1 -0
- package/dist/lib/toolset.js +19 -0
- package/dist/lib/toolset.js.map +1 -0
- package/dist/lib/types.d.ts +31 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { XpertPlugin } from '@xpert-ai/plugin-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
4
|
+
maxSingleWeight: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
5
|
+
maxIndustryWeight: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
6
|
+
maxPositions: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
maxPositions?: number;
|
|
9
|
+
maxSingleWeight?: number;
|
|
10
|
+
maxIndustryWeight?: number;
|
|
11
|
+
}, {
|
|
12
|
+
maxPositions?: number;
|
|
13
|
+
maxSingleWeight?: number;
|
|
14
|
+
maxIndustryWeight?: number;
|
|
15
|
+
}>;
|
|
16
|
+
declare const plugin: XpertPlugin<z.infer<typeof ConfigSchema>>;
|
|
17
|
+
export default plugin;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAIvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAYvB,QAAA,MAAM,YAAY;;;;;;;;;;;;EAIhB,CAAA;AAEF,QAAA,MAAM,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CA2BrD,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { StockPortfolioConstructorPlugin } from './lib/stock-portfolio-constructor.plugin.js';
|
|
6
|
+
import { icon } from './lib/types.js';
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
10
|
+
const ConfigSchema = z.object({
|
|
11
|
+
maxSingleWeight: z.number().min(0.01).max(1).optional().default(0.2),
|
|
12
|
+
maxIndustryWeight: z.number().min(0.01).max(1).optional().default(0.35),
|
|
13
|
+
maxPositions: z.number().int().min(1).max(100).optional().default(10)
|
|
14
|
+
});
|
|
15
|
+
const plugin = {
|
|
16
|
+
meta: {
|
|
17
|
+
name: packageJson.name,
|
|
18
|
+
version: packageJson.version,
|
|
19
|
+
category: 'tools',
|
|
20
|
+
icon: {
|
|
21
|
+
type: 'image',
|
|
22
|
+
value: icon
|
|
23
|
+
},
|
|
24
|
+
displayName: 'Stock Portfolio Constructor',
|
|
25
|
+
description: 'Build target portfolio weights from research signals and produce rebalance plans',
|
|
26
|
+
keywords: ['portfolio', 'rebalance', 'weights', 'allocation', '组合构建', '调仓'],
|
|
27
|
+
author: 'XpertAI Team',
|
|
28
|
+
},
|
|
29
|
+
config: {
|
|
30
|
+
schema: ConfigSchema,
|
|
31
|
+
},
|
|
32
|
+
register(ctx) {
|
|
33
|
+
ctx.logger.log('register stock-portfolio-constructor plugin');
|
|
34
|
+
return { module: StockPortfolioConstructorPlugin, global: true };
|
|
35
|
+
},
|
|
36
|
+
async onStart(ctx) {
|
|
37
|
+
ctx.logger.log('stock-portfolio-constructor plugin started');
|
|
38
|
+
},
|
|
39
|
+
async onStop(ctx) {
|
|
40
|
+
ctx.logger.log('stock-portfolio-constructor plugin stopped');
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export default plugin;
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,+BAA+B,EAAE,MAAM,6CAA6C,CAAA;AAC7F,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AAErC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAGtF,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IACpE,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACvE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACtE,CAAC,CAAA;AAEF,MAAM,MAAM,GAA8C;IACxD,IAAI,EAAE;QACJ,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,IAAI;SACZ;QACD,WAAW,EAAE,6BAA6B;QAC1C,WAAW,EAAE,kFAAkF;QAC/F,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC;QAC3E,MAAM,EAAE,cAAc;KACvB;IACD,MAAM,EAAE;QACN,MAAM,EAAE,YAAY;KACrB;IACD,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAA;QAC7D,OAAO,EAAE,MAAM,EAAE,+BAA+B,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IAClE,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,GAAG;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;IAC9D,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;IAC9D,CAAC;CACF,CAAA;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CandidateSignal, Position, RebalanceOrder, TargetWeight } from './types.js';
|
|
2
|
+
interface BuildOptions {
|
|
3
|
+
maxPositions?: number;
|
|
4
|
+
longOnly?: boolean;
|
|
5
|
+
maxSingleWeight?: number;
|
|
6
|
+
maxIndustryWeight?: number;
|
|
7
|
+
minWeight?: number;
|
|
8
|
+
}
|
|
9
|
+
interface BuildResult {
|
|
10
|
+
targetWeights: TargetWeight[];
|
|
11
|
+
dropped: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function buildTargetWeights(candidates: CandidateSignal[], options?: BuildOptions): BuildResult;
|
|
14
|
+
export declare function buildRebalanceOrders(totalCapital: number, currentPositions: Position[], targetWeights: TargetWeight[], priceMap: Record<string, number>, lotSize?: number): {
|
|
15
|
+
orders: RebalanceOrder[];
|
|
16
|
+
estimatedTurnover: number;
|
|
17
|
+
netCashDelta: number;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=portfolio-constructor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-constructor.d.ts","sourceRoot":"","sources":["../../src/lib/portfolio-constructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEpF,UAAU,YAAY;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,WAAW;IACnB,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AA+FD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAoDzG;AAMD,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,QAAQ,EAAE,EAC5B,aAAa,EAAE,YAAY,EAAE,EAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,OAAO,SAAI,GACV;IAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA2D/E"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
function scoreToAlpha(candidate) {
|
|
2
|
+
const expected = Number.isFinite(candidate.expectedReturn)
|
|
3
|
+
? Number(candidate.expectedReturn)
|
|
4
|
+
: Math.max(0.01, Math.abs(candidate.score) * 0.1);
|
|
5
|
+
const risk = Number.isFinite(candidate.risk)
|
|
6
|
+
? Math.max(0.01, Number(candidate.risk))
|
|
7
|
+
: 0.2;
|
|
8
|
+
return Math.max(0, candidate.score) * (expected / risk);
|
|
9
|
+
}
|
|
10
|
+
function normalize(weights) {
|
|
11
|
+
const total = weights.reduce((sum, item) => sum + item.weight, 0);
|
|
12
|
+
if (total <= 0)
|
|
13
|
+
return weights;
|
|
14
|
+
return weights.map((item) => ({ ...item, weight: item.weight / total }));
|
|
15
|
+
}
|
|
16
|
+
function capSingle(weights, cap) {
|
|
17
|
+
let output = [...weights];
|
|
18
|
+
for (let round = 0; round < 4; round++) {
|
|
19
|
+
let overflow = 0;
|
|
20
|
+
const bounded = output.map((item) => {
|
|
21
|
+
if (item.weight > cap) {
|
|
22
|
+
overflow += item.weight - cap;
|
|
23
|
+
return { ...item, weight: cap };
|
|
24
|
+
}
|
|
25
|
+
return item;
|
|
26
|
+
});
|
|
27
|
+
if (overflow <= 1e-10) {
|
|
28
|
+
output = bounded;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
const receivers = bounded.filter((item) => item.weight < cap - 1e-10);
|
|
32
|
+
if (receivers.length === 0) {
|
|
33
|
+
output = bounded;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
const receiverWeight = receivers.reduce((sum, item) => sum + item.weight, 0);
|
|
37
|
+
output = bounded.map((item) => {
|
|
38
|
+
if (item.weight >= cap - 1e-10)
|
|
39
|
+
return item;
|
|
40
|
+
const ratio = receiverWeight > 0 ? item.weight / receiverWeight : 1 / receivers.length;
|
|
41
|
+
return { ...item, weight: item.weight + overflow * ratio };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return output;
|
|
45
|
+
}
|
|
46
|
+
function capIndustry(weights, cap) {
|
|
47
|
+
let output = [...weights];
|
|
48
|
+
for (let round = 0; round < 4; round++) {
|
|
49
|
+
const industryTotals = new Map();
|
|
50
|
+
for (const item of output) {
|
|
51
|
+
industryTotals.set(item.industry, (industryTotals.get(item.industry) || 0) + item.weight);
|
|
52
|
+
}
|
|
53
|
+
let overflow = 0;
|
|
54
|
+
const bounded = output.map((item) => {
|
|
55
|
+
const industryTotal = industryTotals.get(item.industry) || 0;
|
|
56
|
+
if (industryTotal <= cap + 1e-10)
|
|
57
|
+
return item;
|
|
58
|
+
const nextWeight = industryTotal > 0 ? item.weight * (cap / industryTotal) : item.weight;
|
|
59
|
+
overflow += item.weight - nextWeight;
|
|
60
|
+
return { ...item, weight: nextWeight };
|
|
61
|
+
});
|
|
62
|
+
if (overflow <= 1e-10) {
|
|
63
|
+
output = bounded;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
const industryAfter = new Map();
|
|
67
|
+
for (const item of bounded) {
|
|
68
|
+
industryAfter.set(item.industry, (industryAfter.get(item.industry) || 0) + item.weight);
|
|
69
|
+
}
|
|
70
|
+
const receivers = bounded.filter((item) => (industryAfter.get(item.industry) || 0) < cap - 1e-10);
|
|
71
|
+
if (receivers.length === 0) {
|
|
72
|
+
output = bounded;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const receiverSum = receivers.reduce((sum, item) => sum + item.weight, 0);
|
|
76
|
+
output = bounded.map((item) => {
|
|
77
|
+
if ((industryAfter.get(item.industry) || 0) >= cap - 1e-10)
|
|
78
|
+
return item;
|
|
79
|
+
const ratio = receiverSum > 0 ? item.weight / receiverSum : 1 / receivers.length;
|
|
80
|
+
return { ...item, weight: item.weight + overflow * ratio };
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return output;
|
|
84
|
+
}
|
|
85
|
+
export function buildTargetWeights(candidates, options = {}) {
|
|
86
|
+
const maxPositions = options.maxPositions ?? 10;
|
|
87
|
+
const longOnly = options.longOnly ?? true;
|
|
88
|
+
const maxSingleWeight = options.maxSingleWeight ?? 0.2;
|
|
89
|
+
const maxIndustryWeight = options.maxIndustryWeight ?? 0.35;
|
|
90
|
+
const minWeight = options.minWeight ?? 0.01;
|
|
91
|
+
let pool = candidates
|
|
92
|
+
.map((item) => ({ ...item, code: item.code.toUpperCase(), industry: (item.industry || 'UNKNOWN').toUpperCase() }))
|
|
93
|
+
.filter((item) => Number.isFinite(item.score));
|
|
94
|
+
if (longOnly) {
|
|
95
|
+
pool = pool.filter((item) => item.score > 0);
|
|
96
|
+
}
|
|
97
|
+
pool.sort((a, b) => b.score - a.score);
|
|
98
|
+
const selected = pool.slice(0, maxPositions);
|
|
99
|
+
const dropped = pool.slice(maxPositions).map((item) => item.code);
|
|
100
|
+
if (selected.length === 0) {
|
|
101
|
+
return { targetWeights: [], dropped };
|
|
102
|
+
}
|
|
103
|
+
const withAlpha = selected.map((item) => ({
|
|
104
|
+
code: item.code,
|
|
105
|
+
score: item.score,
|
|
106
|
+
industry: item.industry,
|
|
107
|
+
expectedReturn: item.expectedReturn,
|
|
108
|
+
price: item.price,
|
|
109
|
+
weight: scoreToAlpha(item)
|
|
110
|
+
}));
|
|
111
|
+
let weights = normalize(withAlpha);
|
|
112
|
+
weights = capSingle(weights, maxSingleWeight);
|
|
113
|
+
weights = normalize(weights);
|
|
114
|
+
weights = capIndustry(weights, maxIndustryWeight);
|
|
115
|
+
weights = normalize(weights);
|
|
116
|
+
weights = weights.filter((item) => item.weight >= minWeight);
|
|
117
|
+
weights = normalize(weights);
|
|
118
|
+
return {
|
|
119
|
+
targetWeights: weights.map((item) => ({
|
|
120
|
+
code: item.code,
|
|
121
|
+
weight: item.weight,
|
|
122
|
+
industry: item.industry,
|
|
123
|
+
expectedReturn: item.expectedReturn,
|
|
124
|
+
price: item.price,
|
|
125
|
+
score: item.score
|
|
126
|
+
})),
|
|
127
|
+
dropped
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function positionValue(position) {
|
|
131
|
+
return Math.max(0, position.quantity * position.price);
|
|
132
|
+
}
|
|
133
|
+
export function buildRebalanceOrders(totalCapital, currentPositions, targetWeights, priceMap, lotSize = 1) {
|
|
134
|
+
const safeLotSize = Math.max(1, Math.floor(lotSize));
|
|
135
|
+
const currentMap = new Map(currentPositions.map((item) => [item.code.toUpperCase(), item]));
|
|
136
|
+
const orders = [];
|
|
137
|
+
let turnover = 0;
|
|
138
|
+
let netCashDelta = 0;
|
|
139
|
+
for (const target of targetWeights) {
|
|
140
|
+
const code = target.code.toUpperCase();
|
|
141
|
+
const current = currentMap.get(code);
|
|
142
|
+
const refPrice = Number.isFinite(priceMap[code]) ? priceMap[code] : (current?.price || target.price || 0);
|
|
143
|
+
if (refPrice <= 0)
|
|
144
|
+
continue;
|
|
145
|
+
const targetValue = totalCapital * target.weight;
|
|
146
|
+
const currentValue = current ? positionValue(current) : 0;
|
|
147
|
+
const deltaValue = targetValue - currentValue;
|
|
148
|
+
const quantityRaw = Math.floor(Math.abs(deltaValue) / refPrice);
|
|
149
|
+
const quantity = Math.floor(quantityRaw / safeLotSize) * safeLotSize;
|
|
150
|
+
if (quantity <= 0)
|
|
151
|
+
continue;
|
|
152
|
+
const side = deltaValue >= 0 ? 'buy' : 'sell';
|
|
153
|
+
const amount = quantity * refPrice;
|
|
154
|
+
orders.push({
|
|
155
|
+
code,
|
|
156
|
+
side,
|
|
157
|
+
quantity,
|
|
158
|
+
price: refPrice,
|
|
159
|
+
estimatedAmount: amount
|
|
160
|
+
});
|
|
161
|
+
turnover += amount;
|
|
162
|
+
netCashDelta += side === 'buy' ? -amount : amount;
|
|
163
|
+
}
|
|
164
|
+
for (const current of currentPositions) {
|
|
165
|
+
const code = current.code.toUpperCase();
|
|
166
|
+
if (targetWeights.some((item) => item.code.toUpperCase() === code))
|
|
167
|
+
continue;
|
|
168
|
+
const quantity = Math.floor(Math.max(0, current.quantity) / safeLotSize) * safeLotSize;
|
|
169
|
+
if (quantity <= 0)
|
|
170
|
+
continue;
|
|
171
|
+
const refPrice = Number.isFinite(priceMap[code]) ? priceMap[code] : current.price;
|
|
172
|
+
if (refPrice <= 0)
|
|
173
|
+
continue;
|
|
174
|
+
const amount = quantity * refPrice;
|
|
175
|
+
orders.push({
|
|
176
|
+
code,
|
|
177
|
+
side: 'sell',
|
|
178
|
+
quantity,
|
|
179
|
+
price: refPrice,
|
|
180
|
+
estimatedAmount: amount
|
|
181
|
+
});
|
|
182
|
+
turnover += amount;
|
|
183
|
+
netCashDelta += amount;
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
orders,
|
|
187
|
+
estimatedTurnover: turnover,
|
|
188
|
+
netCashDelta
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=portfolio-constructor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-constructor.js","sourceRoot":"","sources":["../../src/lib/portfolio-constructor.ts"],"names":[],"mappings":"AAeA,SAAS,YAAY,CAAC,SAA0B;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAwB,CAAC;QAClE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC;QAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAc,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC,CAAC,GAAG,CAAA;IACP,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,SAAS,CAAC,OAA0H;IAC3I,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACjE,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,OAAO,CAAA;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;AAC1E,CAAC;AAED,SAAS,SAAS,CAAC,OAA0H,EAAE,GAAW;IACxJ,IAAI,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAA;IACzB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvC,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAClC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACtB,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,CAAA;gBAC7B,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;YACjC,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,OAAO,CAAA;YAChB,MAAK;QACP,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,CAAA;QACrE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,OAAO,CAAA;YAChB,MAAK;QACP,CAAC;QAED,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC5E,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAC5B,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,GAAG,KAAK;gBAAE,OAAO,IAAI,CAAA;YAC3C,MAAM,KAAK,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAA;YACtF,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAE,CAAA;QAC5D,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,WAAW,CAAC,OAA0H,EAAE,GAAW;IAC1J,IAAI,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAA;IACzB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;QAChD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3F,CAAC;QAED,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAClC,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YAC5D,IAAI,aAAa,IAAI,GAAG,GAAG,KAAK;gBAAE,OAAO,IAAI,CAAA;YAC7C,MAAM,UAAU,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAA;YACxF,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;YACpC,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAA;QACxC,CAAC,CAAC,CAAA;QAEF,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,OAAO,CAAA;YAChB,MAAK;QACP,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC/C,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QACzF,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAA;QACjG,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,OAAO,CAAA;YAChB,MAAK;QACP,CAAC;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QACzE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAC5B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG,KAAK;gBAAE,OAAO,IAAI,CAAA;YACvE,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAA;YAChF,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAE,CAAA;QAC5D,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAA6B,EAAE,UAAwB,EAAE;IAC1F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAA;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAA;IACzC,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,GAAG,CAAA;IACtD,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAA;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAA;IAE3C,IAAI,IAAI,GAAG,UAAU;SAClB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;SACjH,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAEhD,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;IAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,CAAA;IACvC,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC,CAAA;IAEH,IAAI,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IAClC,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;IAC7C,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;IACjD,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAE5B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAA;IAC5D,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAE5B,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO;KACR,CAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAkB;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,gBAA4B,EAC5B,aAA6B,EAC7B,QAAgC,EAChC,OAAO,GAAG,CAAC;IAEX,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACpD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAE3F,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,YAAY,GAAG,CAAC,CAAA;IAEpB,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAA;QACtC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAA;QACzG,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAQ;QAE3B,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC,MAAM,CAAA;QAChD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACzD,MAAM,UAAU,GAAG,WAAW,GAAG,YAAY,CAAA;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,WAAW,CAAA;QACpE,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAQ;QAE3B,MAAM,IAAI,GAAmB,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAA;QAC7D,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;QAClC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,IAAI;YACJ,QAAQ;YACR,KAAK,EAAE,QAAQ;YACf,eAAe,EAAE,MAAM;SACxB,CAAC,CAAA;QAEF,QAAQ,IAAI,MAAM,CAAA;QAClB,YAAY,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAA;IACnD,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAA;QACvC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC;YAAE,SAAQ;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,WAAW,CAAA;QACtF,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAQ;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAA;QACjF,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAQ;QAC3B,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;QAClC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,IAAI,EAAE,MAAM;YACZ,QAAQ;YACR,KAAK,EAAE,QAAQ;YACf,eAAe,EAAE,MAAM;SACxB,CAAC,CAAA;QACF,QAAQ,IAAI,MAAM,CAAA;QAClB,YAAY,IAAI,MAAM,CAAA;IACxB,CAAC;IAED,OAAO;QACL,MAAM;QACN,iBAAiB,EAAE,QAAQ;QAC3B,YAAY;KACb,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock-portfolio-constructor.plugin.d.ts","sourceRoot":"","sources":["../../src/lib/stock-portfolio-constructor.plugin.ts"],"names":[],"mappings":"AAGA,qBAMa,+BAA+B;CAAG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { XpertServerPlugin } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
import { StockPortfolioConstructorStrategy } from './stock-portfolio-constructor.strategy.js';
|
|
4
|
+
let StockPortfolioConstructorPlugin = class StockPortfolioConstructorPlugin {
|
|
5
|
+
};
|
|
6
|
+
StockPortfolioConstructorPlugin = __decorate([
|
|
7
|
+
XpertServerPlugin({
|
|
8
|
+
imports: [],
|
|
9
|
+
providers: [StockPortfolioConstructorStrategy],
|
|
10
|
+
controllers: [],
|
|
11
|
+
entities: []
|
|
12
|
+
})
|
|
13
|
+
], StockPortfolioConstructorPlugin);
|
|
14
|
+
export { StockPortfolioConstructorPlugin };
|
|
15
|
+
//# sourceMappingURL=stock-portfolio-constructor.plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock-portfolio-constructor.plugin.js","sourceRoot":"","sources":["../../src/lib/stock-portfolio-constructor.plugin.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,iCAAiC,EAAE,MAAM,2CAA2C,CAAA;AAQtF,IAAM,+BAA+B,GAArC,MAAM,+BAA+B;CAAG,CAAA;AAAlC,+BAA+B;IAN3C,iBAAiB,CAAC;QACjB,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,CAAC,iCAAiC,CAAC;QAC9C,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,EAAE;KACb,CAAC;GACW,+BAA+B,CAAG"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { BuiltinToolset, IToolsetStrategy } from '@xpert-ai/plugin-sdk';
|
|
2
|
+
export declare class StockPortfolioConstructorStrategy implements IToolsetStrategy<any> {
|
|
3
|
+
meta: {
|
|
4
|
+
author: string;
|
|
5
|
+
tags: string[];
|
|
6
|
+
name: string;
|
|
7
|
+
label: {
|
|
8
|
+
en_US: string;
|
|
9
|
+
zh_Hans: string;
|
|
10
|
+
};
|
|
11
|
+
description: {
|
|
12
|
+
en_US: string;
|
|
13
|
+
zh_Hans: string;
|
|
14
|
+
};
|
|
15
|
+
icon: {
|
|
16
|
+
type: "svg";
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
configSchema: {
|
|
20
|
+
type: string;
|
|
21
|
+
properties: {
|
|
22
|
+
maxSingleWeight: {
|
|
23
|
+
type: string;
|
|
24
|
+
default: number;
|
|
25
|
+
'x-ui': {
|
|
26
|
+
component: string;
|
|
27
|
+
label: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
maxIndustryWeight: {
|
|
31
|
+
type: string;
|
|
32
|
+
default: number;
|
|
33
|
+
'x-ui': {
|
|
34
|
+
component: string;
|
|
35
|
+
label: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
maxPositions: {
|
|
39
|
+
type: string;
|
|
40
|
+
default: number;
|
|
41
|
+
'x-ui': {
|
|
42
|
+
component: string;
|
|
43
|
+
label: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
required: any[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
validateConfig(config: any): Promise<void>;
|
|
51
|
+
create(config: any): Promise<BuiltinToolset>;
|
|
52
|
+
createTools(): (import("@langchain/core/tools").DynamicStructuredTool<import("zod").ZodObject<{
|
|
53
|
+
candidates: import("zod").ZodArray<import("zod").ZodObject<{
|
|
54
|
+
code: import("zod").ZodString;
|
|
55
|
+
score: import("zod").ZodNumber;
|
|
56
|
+
expectedReturn: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
57
|
+
risk: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
58
|
+
industry: import("zod").ZodOptional<import("zod").ZodString>;
|
|
59
|
+
price: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
60
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
61
|
+
code?: string;
|
|
62
|
+
score?: number;
|
|
63
|
+
expectedReturn?: number;
|
|
64
|
+
risk?: number;
|
|
65
|
+
industry?: string;
|
|
66
|
+
price?: number;
|
|
67
|
+
}, {
|
|
68
|
+
code?: string;
|
|
69
|
+
score?: number;
|
|
70
|
+
expectedReturn?: number;
|
|
71
|
+
risk?: number;
|
|
72
|
+
industry?: string;
|
|
73
|
+
price?: number;
|
|
74
|
+
}>, "many">;
|
|
75
|
+
maxPositions: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
76
|
+
longOnly: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodBoolean>>;
|
|
77
|
+
maxSingleWeight: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
78
|
+
maxIndustryWeight: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
79
|
+
minWeight: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
80
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
81
|
+
candidates?: {
|
|
82
|
+
code?: string;
|
|
83
|
+
score?: number;
|
|
84
|
+
expectedReturn?: number;
|
|
85
|
+
risk?: number;
|
|
86
|
+
industry?: string;
|
|
87
|
+
price?: number;
|
|
88
|
+
}[];
|
|
89
|
+
maxPositions?: number;
|
|
90
|
+
longOnly?: boolean;
|
|
91
|
+
maxSingleWeight?: number;
|
|
92
|
+
maxIndustryWeight?: number;
|
|
93
|
+
minWeight?: number;
|
|
94
|
+
}, {
|
|
95
|
+
candidates?: {
|
|
96
|
+
code?: string;
|
|
97
|
+
score?: number;
|
|
98
|
+
expectedReturn?: number;
|
|
99
|
+
risk?: number;
|
|
100
|
+
industry?: string;
|
|
101
|
+
price?: number;
|
|
102
|
+
}[];
|
|
103
|
+
maxPositions?: number;
|
|
104
|
+
longOnly?: boolean;
|
|
105
|
+
maxSingleWeight?: number;
|
|
106
|
+
maxIndustryWeight?: number;
|
|
107
|
+
minWeight?: number;
|
|
108
|
+
}>, {
|
|
109
|
+
candidates?: {
|
|
110
|
+
code?: string;
|
|
111
|
+
score?: number;
|
|
112
|
+
expectedReturn?: number;
|
|
113
|
+
risk?: number;
|
|
114
|
+
industry?: string;
|
|
115
|
+
price?: number;
|
|
116
|
+
}[];
|
|
117
|
+
maxPositions?: number;
|
|
118
|
+
longOnly?: boolean;
|
|
119
|
+
maxSingleWeight?: number;
|
|
120
|
+
maxIndustryWeight?: number;
|
|
121
|
+
minWeight?: number;
|
|
122
|
+
}, {
|
|
123
|
+
candidates?: {
|
|
124
|
+
code?: string;
|
|
125
|
+
score?: number;
|
|
126
|
+
expectedReturn?: number;
|
|
127
|
+
risk?: number;
|
|
128
|
+
industry?: string;
|
|
129
|
+
price?: number;
|
|
130
|
+
}[];
|
|
131
|
+
maxPositions?: number;
|
|
132
|
+
longOnly?: boolean;
|
|
133
|
+
maxSingleWeight?: number;
|
|
134
|
+
maxIndustryWeight?: number;
|
|
135
|
+
minWeight?: number;
|
|
136
|
+
}, string> | import("@langchain/core/tools").DynamicStructuredTool<import("zod").ZodObject<{
|
|
137
|
+
totalCapital: import("zod").ZodNumber;
|
|
138
|
+
currentPositions: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
|
|
139
|
+
code: import("zod").ZodString;
|
|
140
|
+
quantity: import("zod").ZodNumber;
|
|
141
|
+
price: import("zod").ZodNumber;
|
|
142
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
143
|
+
code?: string;
|
|
144
|
+
price?: number;
|
|
145
|
+
quantity?: number;
|
|
146
|
+
}, {
|
|
147
|
+
code?: string;
|
|
148
|
+
price?: number;
|
|
149
|
+
quantity?: number;
|
|
150
|
+
}>, "many">>;
|
|
151
|
+
targetWeights: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
|
|
152
|
+
code: import("zod").ZodString;
|
|
153
|
+
weight: import("zod").ZodNumber;
|
|
154
|
+
industry: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodString>>;
|
|
155
|
+
score: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
156
|
+
price: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
157
|
+
expectedReturn: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
158
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
159
|
+
code?: string;
|
|
160
|
+
score?: number;
|
|
161
|
+
expectedReturn?: number;
|
|
162
|
+
industry?: string;
|
|
163
|
+
price?: number;
|
|
164
|
+
weight?: number;
|
|
165
|
+
}, {
|
|
166
|
+
code?: string;
|
|
167
|
+
score?: number;
|
|
168
|
+
expectedReturn?: number;
|
|
169
|
+
industry?: string;
|
|
170
|
+
price?: number;
|
|
171
|
+
weight?: number;
|
|
172
|
+
}>, "many">>;
|
|
173
|
+
priceMap: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNumber>>;
|
|
174
|
+
lotSize: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
175
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
176
|
+
totalCapital?: number;
|
|
177
|
+
currentPositions?: {
|
|
178
|
+
code?: string;
|
|
179
|
+
price?: number;
|
|
180
|
+
quantity?: number;
|
|
181
|
+
}[];
|
|
182
|
+
targetWeights?: {
|
|
183
|
+
code?: string;
|
|
184
|
+
score?: number;
|
|
185
|
+
expectedReturn?: number;
|
|
186
|
+
industry?: string;
|
|
187
|
+
price?: number;
|
|
188
|
+
weight?: number;
|
|
189
|
+
}[];
|
|
190
|
+
priceMap?: Record<string, number>;
|
|
191
|
+
lotSize?: number;
|
|
192
|
+
}, {
|
|
193
|
+
totalCapital?: number;
|
|
194
|
+
currentPositions?: {
|
|
195
|
+
code?: string;
|
|
196
|
+
price?: number;
|
|
197
|
+
quantity?: number;
|
|
198
|
+
}[];
|
|
199
|
+
targetWeights?: {
|
|
200
|
+
code?: string;
|
|
201
|
+
score?: number;
|
|
202
|
+
expectedReturn?: number;
|
|
203
|
+
industry?: string;
|
|
204
|
+
price?: number;
|
|
205
|
+
weight?: number;
|
|
206
|
+
}[];
|
|
207
|
+
priceMap?: Record<string, number>;
|
|
208
|
+
lotSize?: number;
|
|
209
|
+
}>, {
|
|
210
|
+
totalCapital?: number;
|
|
211
|
+
currentPositions?: {
|
|
212
|
+
code?: string;
|
|
213
|
+
price?: number;
|
|
214
|
+
quantity?: number;
|
|
215
|
+
}[];
|
|
216
|
+
targetWeights?: {
|
|
217
|
+
code?: string;
|
|
218
|
+
score?: number;
|
|
219
|
+
expectedReturn?: number;
|
|
220
|
+
industry?: string;
|
|
221
|
+
price?: number;
|
|
222
|
+
weight?: number;
|
|
223
|
+
}[];
|
|
224
|
+
priceMap?: Record<string, number>;
|
|
225
|
+
lotSize?: number;
|
|
226
|
+
}, {
|
|
227
|
+
totalCapital?: number;
|
|
228
|
+
currentPositions?: {
|
|
229
|
+
code?: string;
|
|
230
|
+
price?: number;
|
|
231
|
+
quantity?: number;
|
|
232
|
+
}[];
|
|
233
|
+
targetWeights?: {
|
|
234
|
+
code?: string;
|
|
235
|
+
score?: number;
|
|
236
|
+
expectedReturn?: number;
|
|
237
|
+
industry?: string;
|
|
238
|
+
price?: number;
|
|
239
|
+
weight?: number;
|
|
240
|
+
}[];
|
|
241
|
+
priceMap?: Record<string, number>;
|
|
242
|
+
lotSize?: number;
|
|
243
|
+
}, string>)[];
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=stock-portfolio-constructor.strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock-portfolio-constructor.strategy.d.ts","sourceRoot":"","sources":["../../src/lib/stock-portfolio-constructor.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAmB,MAAM,sBAAsB,CAAA;AAMxF,qBAEa,iCAAkC,YAAW,gBAAgB,CAAC,GAAG,CAAC;IAC7E,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqCH;IAED,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;IAIlD,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMZ"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { Injectable } from '@nestjs/common';
|
|
3
|
+
import { ToolsetStrategy } from '@xpert-ai/plugin-sdk';
|
|
4
|
+
import { StockPortfolioConstructorProvider, icon } from './types.js';
|
|
5
|
+
import { StockPortfolioConstructorToolset } from './toolset.js';
|
|
6
|
+
import { buildPortfolioBuildTargetTool } from './tools/portfolio-build-target.tool.js';
|
|
7
|
+
import { buildPortfolioRebalancePlanTool } from './tools/portfolio-rebalance-plan.tool.js';
|
|
8
|
+
let StockPortfolioConstructorStrategy = class StockPortfolioConstructorStrategy {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.meta = {
|
|
11
|
+
author: 'Xpert AI',
|
|
12
|
+
tags: ['portfolio', 'rebalance', 'allocation', '组合构建', '调仓'],
|
|
13
|
+
name: StockPortfolioConstructorProvider,
|
|
14
|
+
label: {
|
|
15
|
+
en_US: 'Stock Portfolio Constructor',
|
|
16
|
+
zh_Hans: '股票组合构建'
|
|
17
|
+
},
|
|
18
|
+
description: {
|
|
19
|
+
en_US: 'Build target portfolio weights from research signals and generate rebalance plans.',
|
|
20
|
+
zh_Hans: '根据研究信号构建目标组合权重并生成调仓计划。'
|
|
21
|
+
},
|
|
22
|
+
icon: {
|
|
23
|
+
type: 'svg',
|
|
24
|
+
value: icon
|
|
25
|
+
},
|
|
26
|
+
configSchema: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
maxSingleWeight: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
default: 0.2,
|
|
32
|
+
'x-ui': { component: 'input', label: 'Max Single Weight' }
|
|
33
|
+
},
|
|
34
|
+
maxIndustryWeight: {
|
|
35
|
+
type: 'number',
|
|
36
|
+
default: 0.35,
|
|
37
|
+
'x-ui': { component: 'input', label: 'Max Industry Weight' }
|
|
38
|
+
},
|
|
39
|
+
maxPositions: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
default: 10,
|
|
42
|
+
'x-ui': { component: 'input', label: 'Max Positions' }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
required: []
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
validateConfig(config) {
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
async create(config) {
|
|
53
|
+
return new StockPortfolioConstructorToolset(config);
|
|
54
|
+
}
|
|
55
|
+
createTools() {
|
|
56
|
+
return [
|
|
57
|
+
buildPortfolioBuildTargetTool(),
|
|
58
|
+
buildPortfolioRebalancePlanTool()
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
StockPortfolioConstructorStrategy = __decorate([
|
|
63
|
+
Injectable(),
|
|
64
|
+
ToolsetStrategy(StockPortfolioConstructorProvider)
|
|
65
|
+
], StockPortfolioConstructorStrategy);
|
|
66
|
+
export { StockPortfolioConstructorStrategy };
|
|
67
|
+
//# sourceMappingURL=stock-portfolio-constructor.strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stock-portfolio-constructor.strategy.js","sourceRoot":"","sources":["../../src/lib/stock-portfolio-constructor.strategy.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAoC,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxF,OAAO,EAAE,iCAAiC,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAA;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAA;AAInF,IAAM,iCAAiC,GAAvC,MAAM,iCAAiC;IAAvC;QACL,SAAI,GAAG;YACL,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC;YAC5D,IAAI,EAAE,iCAAiC;YACvC,KAAK,EAAE;gBACL,KAAK,EAAE,6BAA6B;gBACpC,OAAO,EAAE,QAAQ;aAClB;YACD,WAAW,EAAE;gBACX,KAAK,EAAE,oFAAoF;gBAC3F,OAAO,EAAE,wBAAwB;aAClC;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAc;gBACpB,KAAK,EAAE,IAAI;aACZ;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,eAAe,EAAE;wBACf,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG;wBACZ,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE;qBAC3D;oBACD,iBAAiB,EAAE;wBACjB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE;qBAC7D;oBACD,YAAY,EAAE;wBACZ,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,EAAE;wBACX,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;qBACvD;iBACF;gBACD,QAAQ,EAAE,EAAE;aACb;SACF,CAAA;IAgBH,CAAC;IAdC,cAAc,CAAC,MAAW;QACxB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAW;QACtB,OAAO,IAAI,gCAAgC,CAAC,MAAM,CAAC,CAAA;IACrD,CAAC;IAED,WAAW;QACT,OAAO;YACL,6BAA6B,EAAE;YAC/B,+BAA+B,EAAE;SAClC,CAAA;IACH,CAAC;CACF,CAAA;AAtDY,iCAAiC;IAF7C,UAAU,EAAE;IACZ,eAAe,CAAC,iCAAiC,CAAC;GACtC,iCAAiC,CAsD7C"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare function buildPortfolioBuildTargetTool(): import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
3
|
+
candidates: z.ZodArray<z.ZodObject<{
|
|
4
|
+
code: z.ZodString;
|
|
5
|
+
score: z.ZodNumber;
|
|
6
|
+
expectedReturn: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
risk: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
industry: z.ZodOptional<z.ZodString>;
|
|
9
|
+
price: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
code?: string;
|
|
12
|
+
score?: number;
|
|
13
|
+
expectedReturn?: number;
|
|
14
|
+
risk?: number;
|
|
15
|
+
industry?: string;
|
|
16
|
+
price?: number;
|
|
17
|
+
}, {
|
|
18
|
+
code?: string;
|
|
19
|
+
score?: number;
|
|
20
|
+
expectedReturn?: number;
|
|
21
|
+
risk?: number;
|
|
22
|
+
industry?: string;
|
|
23
|
+
price?: number;
|
|
24
|
+
}>, "many">;
|
|
25
|
+
maxPositions: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
26
|
+
longOnly: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
27
|
+
maxSingleWeight: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
28
|
+
maxIndustryWeight: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
29
|
+
minWeight: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
30
|
+
}, "strip", z.ZodTypeAny, {
|
|
31
|
+
candidates?: {
|
|
32
|
+
code?: string;
|
|
33
|
+
score?: number;
|
|
34
|
+
expectedReturn?: number;
|
|
35
|
+
risk?: number;
|
|
36
|
+
industry?: string;
|
|
37
|
+
price?: number;
|
|
38
|
+
}[];
|
|
39
|
+
maxPositions?: number;
|
|
40
|
+
longOnly?: boolean;
|
|
41
|
+
maxSingleWeight?: number;
|
|
42
|
+
maxIndustryWeight?: number;
|
|
43
|
+
minWeight?: number;
|
|
44
|
+
}, {
|
|
45
|
+
candidates?: {
|
|
46
|
+
code?: string;
|
|
47
|
+
score?: number;
|
|
48
|
+
expectedReturn?: number;
|
|
49
|
+
risk?: number;
|
|
50
|
+
industry?: string;
|
|
51
|
+
price?: number;
|
|
52
|
+
}[];
|
|
53
|
+
maxPositions?: number;
|
|
54
|
+
longOnly?: boolean;
|
|
55
|
+
maxSingleWeight?: number;
|
|
56
|
+
maxIndustryWeight?: number;
|
|
57
|
+
minWeight?: number;
|
|
58
|
+
}>, {
|
|
59
|
+
candidates?: {
|
|
60
|
+
code?: string;
|
|
61
|
+
score?: number;
|
|
62
|
+
expectedReturn?: number;
|
|
63
|
+
risk?: number;
|
|
64
|
+
industry?: string;
|
|
65
|
+
price?: number;
|
|
66
|
+
}[];
|
|
67
|
+
maxPositions?: number;
|
|
68
|
+
longOnly?: boolean;
|
|
69
|
+
maxSingleWeight?: number;
|
|
70
|
+
maxIndustryWeight?: number;
|
|
71
|
+
minWeight?: number;
|
|
72
|
+
}, {
|
|
73
|
+
candidates?: {
|
|
74
|
+
code?: string;
|
|
75
|
+
score?: number;
|
|
76
|
+
expectedReturn?: number;
|
|
77
|
+
risk?: number;
|
|
78
|
+
industry?: string;
|
|
79
|
+
price?: number;
|
|
80
|
+
}[];
|
|
81
|
+
maxPositions?: number;
|
|
82
|
+
longOnly?: boolean;
|
|
83
|
+
maxSingleWeight?: number;
|
|
84
|
+
maxIndustryWeight?: number;
|
|
85
|
+
minWeight?: number;
|
|
86
|
+
}, string>;
|
|
87
|
+
//# sourceMappingURL=portfolio-build-target.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-build-target.tool.d.ts","sourceRoot":"","sources":["../../../src/lib/tools/portfolio-build-target.tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,wBAAgB,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA6C5C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { tool } from '@langchain/core/tools';
|
|
2
|
+
import { getErrorMessage } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { buildTargetWeights } from '../portfolio-constructor.js';
|
|
5
|
+
export function buildPortfolioBuildTargetTool() {
|
|
6
|
+
return tool(async (input) => {
|
|
7
|
+
try {
|
|
8
|
+
const candidates = (input.candidates || []).map((item) => ({
|
|
9
|
+
code: String(item.code || ''),
|
|
10
|
+
score: Number(item.score || 0),
|
|
11
|
+
expectedReturn: item.expectedReturn === undefined ? undefined : Number(item.expectedReturn),
|
|
12
|
+
risk: item.risk === undefined ? undefined : Number(item.risk),
|
|
13
|
+
industry: item.industry ? String(item.industry) : undefined,
|
|
14
|
+
price: item.price === undefined ? undefined : Number(item.price)
|
|
15
|
+
}));
|
|
16
|
+
const result = buildTargetWeights(candidates, {
|
|
17
|
+
maxPositions: input.maxPositions,
|
|
18
|
+
longOnly: input.longOnly,
|
|
19
|
+
maxSingleWeight: input.maxSingleWeight,
|
|
20
|
+
maxIndustryWeight: input.maxIndustryWeight,
|
|
21
|
+
minWeight: input.minWeight
|
|
22
|
+
});
|
|
23
|
+
return JSON.stringify(result, null, 2);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw new Error(`构建目标组合失败: ${getErrorMessage(error)}`);
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
name: 'portfolio_build_target',
|
|
30
|
+
description: '基于候选标的和打分构建目标权重组合,支持单票和行业权重约束',
|
|
31
|
+
schema: z.object({
|
|
32
|
+
candidates: z.array(z.object({
|
|
33
|
+
code: z.string(),
|
|
34
|
+
score: z.number(),
|
|
35
|
+
expectedReturn: z.number().optional(),
|
|
36
|
+
risk: z.number().positive().optional(),
|
|
37
|
+
industry: z.string().optional(),
|
|
38
|
+
price: z.number().positive().optional()
|
|
39
|
+
})).min(1),
|
|
40
|
+
maxPositions: z.number().int().min(1).max(100).optional().default(10),
|
|
41
|
+
longOnly: z.boolean().optional().default(true),
|
|
42
|
+
maxSingleWeight: z.number().min(0.01).max(1).optional().default(0.2),
|
|
43
|
+
maxIndustryWeight: z.number().min(0.01).max(1).optional().default(0.35),
|
|
44
|
+
minWeight: z.number().min(0).max(1).optional().default(0.01)
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=portfolio-build-target.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-build-target.tool.js","sourceRoot":"","sources":["../../../src/lib/tools/portfolio-build-target.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare function buildPortfolioRebalancePlanTool(): import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
3
|
+
totalCapital: z.ZodNumber;
|
|
4
|
+
currentPositions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
5
|
+
code: z.ZodString;
|
|
6
|
+
quantity: z.ZodNumber;
|
|
7
|
+
price: z.ZodNumber;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
code?: string;
|
|
10
|
+
price?: number;
|
|
11
|
+
quantity?: number;
|
|
12
|
+
}, {
|
|
13
|
+
code?: string;
|
|
14
|
+
price?: number;
|
|
15
|
+
quantity?: number;
|
|
16
|
+
}>, "many">>;
|
|
17
|
+
targetWeights: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
18
|
+
code: z.ZodString;
|
|
19
|
+
weight: z.ZodNumber;
|
|
20
|
+
industry: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
21
|
+
score: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
22
|
+
price: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
expectedReturn: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
code?: string;
|
|
26
|
+
score?: number;
|
|
27
|
+
expectedReturn?: number;
|
|
28
|
+
industry?: string;
|
|
29
|
+
price?: number;
|
|
30
|
+
weight?: number;
|
|
31
|
+
}, {
|
|
32
|
+
code?: string;
|
|
33
|
+
score?: number;
|
|
34
|
+
expectedReturn?: number;
|
|
35
|
+
industry?: string;
|
|
36
|
+
price?: number;
|
|
37
|
+
weight?: number;
|
|
38
|
+
}>, "many">>;
|
|
39
|
+
priceMap: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
40
|
+
lotSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
totalCapital?: number;
|
|
43
|
+
currentPositions?: {
|
|
44
|
+
code?: string;
|
|
45
|
+
price?: number;
|
|
46
|
+
quantity?: number;
|
|
47
|
+
}[];
|
|
48
|
+
targetWeights?: {
|
|
49
|
+
code?: string;
|
|
50
|
+
score?: number;
|
|
51
|
+
expectedReturn?: number;
|
|
52
|
+
industry?: string;
|
|
53
|
+
price?: number;
|
|
54
|
+
weight?: number;
|
|
55
|
+
}[];
|
|
56
|
+
priceMap?: Record<string, number>;
|
|
57
|
+
lotSize?: number;
|
|
58
|
+
}, {
|
|
59
|
+
totalCapital?: number;
|
|
60
|
+
currentPositions?: {
|
|
61
|
+
code?: string;
|
|
62
|
+
price?: number;
|
|
63
|
+
quantity?: number;
|
|
64
|
+
}[];
|
|
65
|
+
targetWeights?: {
|
|
66
|
+
code?: string;
|
|
67
|
+
score?: number;
|
|
68
|
+
expectedReturn?: number;
|
|
69
|
+
industry?: string;
|
|
70
|
+
price?: number;
|
|
71
|
+
weight?: number;
|
|
72
|
+
}[];
|
|
73
|
+
priceMap?: Record<string, number>;
|
|
74
|
+
lotSize?: number;
|
|
75
|
+
}>, {
|
|
76
|
+
totalCapital?: number;
|
|
77
|
+
currentPositions?: {
|
|
78
|
+
code?: string;
|
|
79
|
+
price?: number;
|
|
80
|
+
quantity?: number;
|
|
81
|
+
}[];
|
|
82
|
+
targetWeights?: {
|
|
83
|
+
code?: string;
|
|
84
|
+
score?: number;
|
|
85
|
+
expectedReturn?: number;
|
|
86
|
+
industry?: string;
|
|
87
|
+
price?: number;
|
|
88
|
+
weight?: number;
|
|
89
|
+
}[];
|
|
90
|
+
priceMap?: Record<string, number>;
|
|
91
|
+
lotSize?: number;
|
|
92
|
+
}, {
|
|
93
|
+
totalCapital?: number;
|
|
94
|
+
currentPositions?: {
|
|
95
|
+
code?: string;
|
|
96
|
+
price?: number;
|
|
97
|
+
quantity?: number;
|
|
98
|
+
}[];
|
|
99
|
+
targetWeights?: {
|
|
100
|
+
code?: string;
|
|
101
|
+
score?: number;
|
|
102
|
+
expectedReturn?: number;
|
|
103
|
+
industry?: string;
|
|
104
|
+
price?: number;
|
|
105
|
+
weight?: number;
|
|
106
|
+
}[];
|
|
107
|
+
priceMap?: Record<string, number>;
|
|
108
|
+
lotSize?: number;
|
|
109
|
+
}, string>;
|
|
110
|
+
//# sourceMappingURL=portfolio-rebalance-plan.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-rebalance-plan.tool.d.ts","sourceRoot":"","sources":["../../../src/lib/tools/portfolio-rebalance-plan.tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,wBAAgB,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA0D9C"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { tool } from '@langchain/core/tools';
|
|
2
|
+
import { getErrorMessage } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { buildRebalanceOrders } from '../portfolio-constructor.js';
|
|
5
|
+
export function buildPortfolioRebalancePlanTool() {
|
|
6
|
+
return tool(async (input) => {
|
|
7
|
+
try {
|
|
8
|
+
const normalizedPriceMap = {};
|
|
9
|
+
for (const [code, price] of Object.entries(input.priceMap || {})) {
|
|
10
|
+
normalizedPriceMap[code.toUpperCase()] = price;
|
|
11
|
+
}
|
|
12
|
+
const currentPositions = (input.currentPositions || []).map((item) => ({
|
|
13
|
+
code: String(item.code || ''),
|
|
14
|
+
quantity: Number(item.quantity || 0),
|
|
15
|
+
price: Number(item.price || 0)
|
|
16
|
+
}));
|
|
17
|
+
const targetWeights = (input.targetWeights || []).map((item) => ({
|
|
18
|
+
code: String(item.code || ''),
|
|
19
|
+
weight: Number(item.weight || 0),
|
|
20
|
+
industry: String(item.industry || 'UNKNOWN'),
|
|
21
|
+
score: Number(item.score || 0),
|
|
22
|
+
price: item.price === undefined ? undefined : Number(item.price),
|
|
23
|
+
expectedReturn: item.expectedReturn === undefined ? undefined : Number(item.expectedReturn)
|
|
24
|
+
}));
|
|
25
|
+
const result = buildRebalanceOrders(Number(input.totalCapital), currentPositions, targetWeights, normalizedPriceMap, input.lotSize);
|
|
26
|
+
return JSON.stringify(result, null, 2);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
throw new Error(`生成调仓计划失败: ${getErrorMessage(error)}`);
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
name: 'portfolio_rebalance_plan',
|
|
33
|
+
description: '根据当前持仓和目标权重生成调仓买卖指令',
|
|
34
|
+
schema: z.object({
|
|
35
|
+
totalCapital: z.number().positive(),
|
|
36
|
+
currentPositions: z.array(z.object({
|
|
37
|
+
code: z.string(),
|
|
38
|
+
quantity: z.number().nonnegative(),
|
|
39
|
+
price: z.number().positive()
|
|
40
|
+
})).default([]),
|
|
41
|
+
targetWeights: z.array(z.object({
|
|
42
|
+
code: z.string(),
|
|
43
|
+
weight: z.number().min(0).max(1),
|
|
44
|
+
industry: z.string().optional().default('UNKNOWN'),
|
|
45
|
+
score: z.number().optional().default(0),
|
|
46
|
+
price: z.number().positive().optional(),
|
|
47
|
+
expectedReturn: z.number().optional()
|
|
48
|
+
})).default([]),
|
|
49
|
+
priceMap: z.record(z.string(), z.number().positive()).default({}),
|
|
50
|
+
lotSize: z.number().int().min(1).max(1000).optional().default(1)
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=portfolio-rebalance-plan.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio-rebalance-plan.tool.js","sourceRoot":"","sources":["../../../src/lib/tools/portfolio-rebalance-plan.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BuiltinToolset } from '@xpert-ai/plugin-sdk';
|
|
2
|
+
export declare class StockPortfolioConstructorToolset extends BuiltinToolset {
|
|
3
|
+
validateCredentials(credentials: Record<string, never>): Promise<void>;
|
|
4
|
+
_validateCredentials(credentials: Record<string, never>): Promise<void>;
|
|
5
|
+
initTools(): Promise<any[]>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=toolset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolset.d.ts","sourceRoot":"","sources":["../../src/lib/toolset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAIrD,qBAAa,gCAAiC,SAAQ,cAAc;IACnD,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;CAO3C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BuiltinToolset } from '@xpert-ai/plugin-sdk';
|
|
2
|
+
import { buildPortfolioBuildTargetTool } from './tools/portfolio-build-target.tool.js';
|
|
3
|
+
import { buildPortfolioRebalancePlanTool } from './tools/portfolio-rebalance-plan.tool.js';
|
|
4
|
+
export class StockPortfolioConstructorToolset extends BuiltinToolset {
|
|
5
|
+
async validateCredentials(credentials) {
|
|
6
|
+
await this._validateCredentials(credentials);
|
|
7
|
+
}
|
|
8
|
+
async _validateCredentials(credentials) {
|
|
9
|
+
// Portfolio constructor runs deterministic local calculations.
|
|
10
|
+
}
|
|
11
|
+
async initTools() {
|
|
12
|
+
this.tools = [
|
|
13
|
+
buildPortfolioBuildTargetTool(),
|
|
14
|
+
buildPortfolioRebalancePlanTool()
|
|
15
|
+
];
|
|
16
|
+
return this.tools;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=toolset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolset.js","sourceRoot":"","sources":["../../src/lib/toolset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAA;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAA;AAE1F,MAAM,OAAO,gCAAiC,SAAQ,cAAc;IACzD,KAAK,CAAC,mBAAmB,CAAC,WAAkC;QACnE,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAA;IAC9C,CAAC;IAEQ,KAAK,CAAC,oBAAoB,CAAC,WAAkC;QACpE,+DAA+D;IACjE,CAAC;IAEQ,KAAK,CAAC,SAAS;QACtB,IAAI,CAAC,KAAK,GAAG;YACX,6BAA6B,EAAE;YAC/B,+BAA+B,EAAE;SAClC,CAAA;QACD,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const StockPortfolioConstructorProvider = "stock-portfolio-constructor";
|
|
2
|
+
export interface CandidateSignal {
|
|
3
|
+
code: string;
|
|
4
|
+
score: number;
|
|
5
|
+
expectedReturn?: number;
|
|
6
|
+
risk?: number;
|
|
7
|
+
industry?: string;
|
|
8
|
+
price?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface TargetWeight {
|
|
11
|
+
code: string;
|
|
12
|
+
weight: number;
|
|
13
|
+
industry: string;
|
|
14
|
+
price?: number;
|
|
15
|
+
expectedReturn?: number;
|
|
16
|
+
score: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Position {
|
|
19
|
+
code: string;
|
|
20
|
+
quantity: number;
|
|
21
|
+
price: number;
|
|
22
|
+
}
|
|
23
|
+
export interface RebalanceOrder {
|
|
24
|
+
code: string;
|
|
25
|
+
side: 'buy' | 'sell';
|
|
26
|
+
quantity: number;
|
|
27
|
+
price: number;
|
|
28
|
+
estimatedAmount: number;
|
|
29
|
+
}
|
|
30
|
+
export declare const icon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMGVhNWU5IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHJlY3QgeD0iMyIgeT0iMyIgd2lkdGg9IjE4IiBoZWlnaHQ9IjE4IiByeD0iMiIvPjxwYXRoIGQ9Ik03IDE0bDMgM2w3LTciLz48L3N2Zz4=";
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,gCAAgC,CAAA;AAE9E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,eAAO,MAAM,IAAI,uVAAuV,CAAA"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export const StockPortfolioConstructorProvider = 'stock-portfolio-constructor';
|
|
2
|
+
export const icon = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMGVhNWU5IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHJlY3QgeD0iMyIgeT0iMyIgd2lkdGg9IjE4IiBoZWlnaHQ9IjE4IiByeD0iMiIvPjxwYXRoIGQ9Ik03IDE0bDMgM2w3LTciLz48L3N2Zz4=`;
|
|
3
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iCAAiC,GAAG,6BAA6B,CAAA;AAkC9E,MAAM,CAAC,MAAM,IAAI,GAAG,oVAAoV,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@helloxiaohu/plugin-stock-portfolio-constructor",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/xpert-ai/xpert-plugins"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"@xpert-plugins-starter/source": "./src/index.ts",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"!**/*.tsbuildinfo"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"tslib": "^2.3.0"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"@xpert-ai/plugin-sdk": "^3.6.2",
|
|
30
|
+
"zod": "3.25.67",
|
|
31
|
+
"chalk": "4.1.2",
|
|
32
|
+
"@nestjs/config": "^4.0.2",
|
|
33
|
+
"@nestjs/common": "^11.1.6",
|
|
34
|
+
"@langchain/core": "0.3.72"
|
|
35
|
+
}
|
|
36
|
+
}
|