Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,251 changes: 1,149 additions & 1,102 deletions bun.lock

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions modules/tool/packages/allTick/children/depthTick/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { defineTool } from '@tool/type';
import { FlowNodeInputTypeEnum, WorkflowIOValueTypeEnum } from '@tool/type/fastgpt';

export default defineTool({
name: {
'zh-CN': '深度行情查询',
en: 'Depth Tick Query'
},
description: {
'zh-CN': '获取AllTick的最新盘口深度行情数据(Order Book)',
en: 'Get AllTick latest depth tick data (Order Book)'
},
toolDescription:
'Query real-time market depth data including bid/ask prices and volumes for stocks, forex, cryptocurrencies and other financial instruments from AllTick API',
versionList: [
{
value: '0.1.0',
description: 'Default version',
inputs: [
{
key: 'symbol',
label: '产品代码',
description: '支持股票、外汇、贵金属、加密货币等,如:"857.HK","UNH.US"',
renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'is_stock',
label: '是否为股票类产品',
description: '是否为股票类产品,决定使用哪个API端点。股票类包括:A股、港股、美股等',
renderTypeList: [FlowNodeInputTypeEnum.switch, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.boolean
}
],
outputs: [
{
valueType: WorkflowIOValueTypeEnum.object,
key: 'data',
label: '深度行情数据',
description: '包含产品代码、报价序号、时间戳、买卖盘深度等完整的盘口信息'
}
]
}
]
});
10 changes: 10 additions & 0 deletions modules/tool/packages/allTick/children/depthTick/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import config from './config';
import { InputType, OutputType, tool as toolCb } from './src';
import { exportTool } from '@tool/utils/tool';

export default exportTool({
toolCb,
InputType,
OutputType,
config
});
143 changes: 143 additions & 0 deletions modules/tool/packages/allTick/children/depthTick/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { z } from 'zod';

// Input parameter schema
export const InputType = z.object({
token: z.string().min(1, 'Please provide a valid API token'),
symbol: z.string().min(1, 'Please provide product code, e.g.: 857.HK, UNH.US'),
is_stock: z
.boolean()
.optional()
.default(true)
.describe('Whether it is a stock product, determines which API endpoint to use')
});

// Depth quote data item schema
const DepthItemType = z.object({
price: z.string().describe('Price'),
volume: z.string().describe('Volume')
});

// Single product depth quote schema
const TickItemType = z.object({
code: z.string().describe('Product code'),
seq: z.string().describe('Quote sequence number'),
tick_time: z.string().describe('Quote timestamp'),
bids: z.array(DepthItemType).describe('Bid depth list'),
asks: z.array(DepthItemType).describe('Ask depth list')
});

// API response schema
const ApiResponseType = z.object({
ret: z.number(),
msg: z.string(),
trace: z.string(),
data: z
.object({
tick_list: z.array(TickItemType)
})
.optional()
});

// Output parameter schema
export const OutputType = z.object({
data: z.object({
tick_list: z.array(TickItemType),
total_count: z.number()
})
});

// Generate unique trace code
function generateTrace(): string {
const uuid = crypto.randomUUID();
const timestamp = Date.now();
return `${uuid}-${timestamp}`;
}

// Build query parameters
function buildQueryData(params: z.infer<typeof InputType>) {
return {
trace: generateTrace(),
data: {
symbol_list: [{ code: params.symbol }]
}
};
}

// Get API endpoint URL
function getApiEndpoint(isStock: boolean): string {
if (isStock) {
return 'https://quote.alltick.io/quote-stock-b-api/depth-tick';
} else {
return 'https://quote.alltick.io/quote-b-api/depth-tick';
}
}

export async function tool(params: z.infer<typeof InputType>): Promise<z.infer<typeof OutputType>> {
try {
// Validate input parameters
const validatedParams = InputType.parse(params);

// Build request data
const queryData = buildQueryData(validatedParams);
const apiUrl = getApiEndpoint(validatedParams.is_stock);

// Build complete request URL
const requestUrl = `${apiUrl}?token=${encodeURIComponent(validatedParams.token)}&query=${encodeURIComponent(JSON.stringify(queryData))}`;

// Send API request
const response = await fetch(requestUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'User-Agent': 'FastGPT-AllTick-Plugin/1.0'
}
});

if (!response.ok) {
return Promise.reject(new Error(`HTTP error: ${response.status} ${response.statusText}`));
}

const responseData = await response.json();

// Validate API response format
const validatedResponse = ApiResponseType.parse(responseData);

// Check API return status
if (validatedResponse.ret !== 200) {
return Promise.reject(
new Error(`API error: ${validatedResponse.msg} (error code: ${validatedResponse.ret})`)
);
}

// Check if data exists
if (!validatedResponse.data || !validatedResponse.data.tick_list) {
return Promise.reject(
new Error(
'Failed to retrieve depth quote data, please check if the product code is correct'
)
);
}

// Return success result
return {
data: {
tick_list: validatedResponse.data.tick_list,
total_count: validatedResponse.data.tick_list.length
}
};
} catch (error) {
// Error handling - use Promise.reject
if (error instanceof z.ZodError) {
const errorMessages = error.errors
.map((err) => `${err.path.join('.')}: ${err.message}`)
.join('; ');
return Promise.reject(new Error(`Parameter validation failed: ${errorMessages}`));
}

if (error instanceof Error) {
return Promise.reject(new Error(`Request failed: ${error.message}`));
}

return Promise.reject(new Error('Unknown error, please try again later'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { expect, test } from 'vitest';
import tool from '..';

test(async () => {
expect(tool.name).toBeDefined();
expect(tool.description).toBeDefined();
expect(tool.cb).toBeDefined();
});
146 changes: 146 additions & 0 deletions modules/tool/packages/allTick/children/kline/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { defineTool } from '@tool/type';
import { FlowNodeInputTypeEnum, WorkflowIOValueTypeEnum } from '@tool/type/fastgpt';

export default defineTool({
name: {
'zh-CN': 'K线数据查询',
en: 'AllTick K-Line Data Query'
},
description: {
'zh-CN': '获取AllTick平台的K线图表数据,支持股票、外汇、贵金属、加密货币等多种金融产品',
en: 'Retrieve K-line chart data from AllTick platform, supporting stocks, forex, precious metals, cryptocurrencies and other financial products'
},
toolDescription:
'Query K-line (candlestick) chart data from AllTick API for various financial instruments including stocks, forex, precious metals, and cryptocurrencies',
versionList: [
{
value: '0.1.0',
description: 'Default version',
inputs: [
{
key: 'code',
label: '产品代码',
description: '金融产品的唯一标识符,支持股票代码、外汇对、贵金属代码、加密货币代码等',
renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'kline_type',
label: 'K线周期类型',
description:
'K线时间周期设置:\n' +
'• 1: 1分钟线\n' +
'• 2: 5分钟线\n' +
'• 3: 15分钟线\n' +
'• 4: 30分钟线\n' +
'• 5: 1小时线\n' +
'• 6: 2小时线(股票不支持)\n' +
'• 7: 4小时线(股票不支持)\n' +
'• 8: 日K线\n' +
'• 9: 周K线\n' +
'• 10: 月K线\n' +
'注:查询昨日收盘价请使用日K线(8)',
renderTypeList: [FlowNodeInputTypeEnum.select, FlowNodeInputTypeEnum.reference],
list: [
{
label: '1分钟线',
value: '1'
},
{
label: '5分钟线',
value: '2'
},
{
label: '15分钟线',
value: '3'
},
{
label: '30分钟线',
value: '4'
},
{
label: '1小时线',
value: '5'
},
{
label: '2小时线',
value: '6'
},
{
label: '4小时线',
value: '7'
},
{
label: '日K线',
value: '8'
},
{
label: '周K线',
value: '9'
},
{
label: '月K线',
value: '10'
}
],
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'kline_timestamp_end',
label: 'K线查询截止时间',
description:
'K线数据查询的时间基准点:\n' +
'• 传入 0:从当前最新交易日开始向前查询\n' +
'• 传入时间戳:从指定时间戳开始向前查询\n' +
'注:时间戳查询仅支持外汇、贵金属、加密货币,股票类产品无效',
renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'query_kline_num',
label: 'K线数据条数',
description:
'指定查询的K线数据条数,单次请求最多500条。\n' +
'可通过时间戳分批循环查询更多历史数据。\n' +
'提示:查询昨日收盘价时,设置K线周期为8(日K),数据条数为2,返回结果中时间戳较小的即为昨日收盘价',
renderTypeList: [FlowNodeInputTypeEnum.input, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'adjust_type',
label: '复权类型',
description:
'股票数据的复权处理方式(仅对股票类产品有效):\n• 0: 不复权(除权)\n• 1: 前复权\n注:目前仅支持不复权模式(0)',
renderTypeList: [FlowNodeInputTypeEnum.select, FlowNodeInputTypeEnum.reference],
list: [
{
label: '不复权(除权)',
value: '0'
},
{
label: '前复权',
value: '1'
}
],
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'is_stock',
label: '股票类产品开关',
description: '标识当前查询的产品是否为股票类型,用于系统选择合适的API接口进行数据查询',
renderTypeList: [FlowNodeInputTypeEnum.switch, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.boolean
}
],
outputs: [
{
valueType: WorkflowIOValueTypeEnum.object,
key: 'data',
label: 'K线数据结果',
description:
'返回完整的K线数据对象,包含产品代码、K线周期类型、K线数据列表以及数据总条数等详细信息'
}
]
}
]
});
10 changes: 10 additions & 0 deletions modules/tool/packages/allTick/children/kline/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import config from './config';
import { InputType, OutputType, tool as toolCb } from './src';
import { exportTool } from '@tool/utils/tool';

export default exportTool({
toolCb,
InputType,
OutputType,
config
});
Loading
Loading