@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.
Files changed (34) hide show
  1. package/README.md +3 -0
  2. package/dist/index.d.ts +18 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +44 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/portfolio-constructor.d.ts +20 -0
  7. package/dist/lib/portfolio-constructor.d.ts.map +1 -0
  8. package/dist/lib/portfolio-constructor.js +191 -0
  9. package/dist/lib/portfolio-constructor.js.map +1 -0
  10. package/dist/lib/stock-portfolio-constructor.plugin.d.ts +3 -0
  11. package/dist/lib/stock-portfolio-constructor.plugin.d.ts.map +1 -0
  12. package/dist/lib/stock-portfolio-constructor.plugin.js +15 -0
  13. package/dist/lib/stock-portfolio-constructor.plugin.js.map +1 -0
  14. package/dist/lib/stock-portfolio-constructor.strategy.d.ts +245 -0
  15. package/dist/lib/stock-portfolio-constructor.strategy.d.ts.map +1 -0
  16. package/dist/lib/stock-portfolio-constructor.strategy.js +67 -0
  17. package/dist/lib/stock-portfolio-constructor.strategy.js.map +1 -0
  18. package/dist/lib/tools/portfolio-build-target.tool.d.ts +87 -0
  19. package/dist/lib/tools/portfolio-build-target.tool.d.ts.map +1 -0
  20. package/dist/lib/tools/portfolio-build-target.tool.js +48 -0
  21. package/dist/lib/tools/portfolio-build-target.tool.js.map +1 -0
  22. package/dist/lib/tools/portfolio-rebalance-plan.tool.d.ts +110 -0
  23. package/dist/lib/tools/portfolio-rebalance-plan.tool.d.ts.map +1 -0
  24. package/dist/lib/tools/portfolio-rebalance-plan.tool.js +54 -0
  25. package/dist/lib/tools/portfolio-rebalance-plan.tool.js.map +1 -0
  26. package/dist/lib/toolset.d.ts +7 -0
  27. package/dist/lib/toolset.d.ts.map +1 -0
  28. package/dist/lib/toolset.js +19 -0
  29. package/dist/lib/toolset.js.map +1 -0
  30. package/dist/lib/types.d.ts +31 -0
  31. package/dist/lib/types.d.ts.map +1 -0
  32. package/dist/lib/types.js +3 -0
  33. package/dist/lib/types.js.map +1 -0
  34. package/package.json +36 -0
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Stock Portfolio Constructor Plugin
2
+
3
+ Build target weights from research signals and generate rebalance orders.
@@ -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":"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"}
@@ -0,0 +1,3 @@
1
+ export declare class StockPortfolioConstructorPlugin {
2
+ }
3
+ //# sourceMappingURL=stock-portfolio-constructor.plugin.d.ts.map
@@ -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
+ }