Feature/custom strategy (#1172)

* feat: add Strategy Studio with multi-timeframe support
- Add Strategy Studio page with three-column layout for strategy management
- Support multi-timeframe K-line data selection (5m, 15m, 1h, 4h, etc.)
- Add GetWithTimeframes() function in market package for fetching multiple timeframes
- Add TimeframeSeriesData struct for storing per-timeframe technical indicators
- Update formatMarketData() to display all selected timeframes in AI prompt
- Add strategy API endpoints for CRUD operations and test run
- Integrate real AI test runs with configured AI models
- Support custom AI500 and OI Top API URLs from strategy config
* docs: add Strategy Studio screenshot to README files
* fix: correct strategy-studio.png filename case in README
* refactor: remove legacy signal source config and simplify trader creation
- Remove signal source configuration from traders page (now handled by strategy)
- Remove advanced options (legacy config) from TraderConfigModal
- Rename default strategy to "默认山寨策略" with AI500 coin pool URL
- Delete SignalSourceModal and SignalSourceWarning components
- Clean up related stores, hooks, and page components
This commit is contained in:
tinkle-community
2025-12-06 07:20:11 +08:00
committed by GitHub
parent afb2d158ac
commit 5cff32e4f2
37 changed files with 4965 additions and 1051 deletions

View File

@@ -19,6 +19,8 @@ import type {
BacktestTradeEvent,
BacktestMetrics,
BacktestRunMetadata,
Strategy,
StrategyConfig,
} from '../types'
import { CryptoService } from './crypto'
import { httpClient } from './httpClient'
@@ -553,4 +555,69 @@ export const api = {
}
return res.blob()
},
// Strategy APIs
async getStrategies(): Promise<Strategy[]> {
const result = await httpClient.get<Strategy[]>(`${API_BASE}/strategies`)
if (!result.success) throw new Error('获取策略列表失败')
return result.data!
},
async getStrategy(strategyId: string): Promise<Strategy> {
const result = await httpClient.get<Strategy>(`${API_BASE}/strategies/${strategyId}`)
if (!result.success) throw new Error('获取策略失败')
return result.data!
},
async getActiveStrategy(): Promise<Strategy> {
const result = await httpClient.get<Strategy>(`${API_BASE}/strategies/active`)
if (!result.success) throw new Error('获取激活策略失败')
return result.data!
},
async getDefaultStrategyConfig(): Promise<StrategyConfig> {
const result = await httpClient.get<StrategyConfig>(`${API_BASE}/strategies/default-config`)
if (!result.success) throw new Error('获取默认策略配置失败')
return result.data!
},
async createStrategy(data: {
name: string
description: string
config: StrategyConfig
}): Promise<Strategy> {
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies`, data)
if (!result.success) throw new Error('创建策略失败')
return result.data!
},
async updateStrategy(
strategyId: string,
data: {
name?: string
description?: string
config?: StrategyConfig
}
): Promise<Strategy> {
const result = await httpClient.put<Strategy>(`${API_BASE}/strategies/${strategyId}`, data)
if (!result.success) throw new Error('更新策略失败')
return result.data!
},
async deleteStrategy(strategyId: string): Promise<void> {
const result = await httpClient.delete(`${API_BASE}/strategies/${strategyId}`)
if (!result.success) throw new Error('删除策略失败')
},
async activateStrategy(strategyId: string): Promise<Strategy> {
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies/${strategyId}/activate`)
if (!result.success) throw new Error('激活策略失败')
return result.data!
},
async duplicateStrategy(strategyId: string): Promise<Strategy> {
const result = await httpClient.post<Strategy>(`${API_BASE}/strategies/${strategyId}/duplicate`)
if (!result.success) throw new Error('复制策略失败')
return result.data!
},
}