Spaces:
Running
Running
| import axios from 'axios'; | |
| const API_BASE = import.meta.env.DEV ? 'http://localhost:8000/api' : '/api'; | |
| const api = axios.create({ | |
| baseURL: API_BASE, | |
| headers: { 'Content-Type': 'application/json' }, | |
| }); | |
| // Attach JWT token to all requests | |
| api.interceptors.request.use((config) => { | |
| const token = localStorage.getItem('qh_token'); | |
| if (token) { | |
| config.headers.Authorization = `Bearer ${token}`; | |
| } | |
| return config; | |
| }); | |
| // Handle 401 responses | |
| api.interceptors.response.use( | |
| (response) => response, | |
| (error) => { | |
| if (error.response?.status === 401) { | |
| localStorage.removeItem('qh_token'); | |
| localStorage.removeItem('qh_user'); | |
| if (window.location.pathname !== '/login') { | |
| window.location.href = '/login'; | |
| } | |
| } | |
| return Promise.reject(error); | |
| } | |
| ); | |
| // ββ Auth βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const authAPI = { | |
| register: (data: { email: string; username: string; password: string; full_name?: string }) => | |
| api.post('/auth/register', data), | |
| login: (data: { email: string; password: string }) => | |
| api.post('/auth/login', data), | |
| getProfile: () => api.get('/auth/me'), | |
| updateProfile: (data: { full_name?: string; bio?: string }) => | |
| api.put('/auth/me', data), | |
| }; | |
| // ββ Market Data ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const dataAPI = { | |
| getExchanges: () => api.get('/data/exchanges'), | |
| getMarkets: () => api.get('/data/markets'), | |
| getSectors: () => api.get('/data/sectors'), | |
| getPopularTickers: (market: string = 'US') => | |
| api.get(`/data/popular-tickers?market=${market}`), | |
| getPrices: (ticker: string, period: string = '1y', interval: string = '1d') => | |
| api.get(`/data/prices/${ticker}?period=${period}&interval=${interval}`), | |
| getCompanyInfo: (ticker: string) => api.get(`/data/company/${ticker}`), | |
| computeFeatures: (data: { ticker: string; features?: string[]; period?: string }) => | |
| api.post('/data/features', data), | |
| searchNews: (data: { query: string; page_size?: number }) => | |
| api.post('/data/news', data), | |
| searchTickers: (query: string, limit: number = 15) => | |
| api.get(`/data/search-tickers?q=${encodeURIComponent(query)}&limit=${limit}`), | |
| }; | |
| // ββ Quantitative βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const quantAPI = { | |
| analyzeFactors: (data: { tickers: string[]; factors?: string[]; period?: string }) => | |
| api.post('/quant/factors/analyze', data), | |
| getFactorDefinitions: () => api.get('/quant/factors/definitions'), | |
| generateSignals: (data: { tickers: string[]; signal_types?: string[]; period?: string }) => | |
| api.post('/quant/signals/generate', data), | |
| }; | |
| // ββ Strategies βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const strategyAPI = { | |
| create: (data: any) => api.post('/strategies/', data), | |
| list: () => api.get('/strategies/'), | |
| get: (id: number) => api.get(`/strategies/${id}`), | |
| update: (id: number, data: any) => api.put(`/strategies/${id}`, data), | |
| delete: (id: number) => api.delete(`/strategies/${id}`), | |
| evaluate: (id: number) => api.post(`/strategies/${id}/evaluate`), | |
| convertGraph: (graph: any) => api.post('/strategies/convert-visual-graph', graph), | |
| }; | |
| // ββ Portfolios βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const portfolioAPI = { | |
| create: (data: any) => api.post('/portfolios/', data), | |
| list: () => api.get('/portfolios/'), | |
| get: (id: number) => api.get(`/portfolios/${id}`), | |
| optimize: (data: { tickers: string[]; method?: string; period?: string }) => | |
| api.post('/portfolios/optimize', data), | |
| }; | |
| // ββ Risk βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const riskAPI = { | |
| analyze: (data: { tickers: string[]; period?: string; benchmark_ticker?: string }) => | |
| api.post('/risk/analyze', data), | |
| correlation: (tickers: string[], period: string = '1y') => | |
| api.post(`/risk/correlation?period=${period}`, tickers), | |
| }; | |
| // ββ Backtests ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const backtestAPI = { | |
| run: (data: any) => api.post('/backtests/run', data), | |
| list: () => api.get('/backtests/'), | |
| get: (id: number) => api.get(`/backtests/${id}`), | |
| compare: (strategyIds: number[]) => api.post('/analytics/compare', strategyIds), | |
| }; | |
| // ββ Marketplace ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const marketplaceAPI = { | |
| publish: (data: any) => api.post('/marketplace/publish', data), | |
| browse: (params?: { category?: string; sort_by?: string; page?: number; search?: string }) => | |
| api.get('/marketplace/browse', { params }), | |
| leaderboard: (sort_by: string = 'sharpe_ratio', limit: number = 25) => | |
| api.get(`/marketplace/leaderboard?sort_by=${sort_by}&limit=${limit}`), | |
| }; | |
| // ββ AI Research ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const researchAPI = { | |
| generate: (data: { insight_type: string; tickers?: string[]; context?: string }) => | |
| api.post('/research/generate', data), | |
| listReports: () => api.get('/research/reports'), | |
| getReport: (id: number) => api.get(`/research/reports/${id}`), | |
| exportPdf: (id: number) => api.get(`/research/reports/${id}/export/pdf`, { responseType: 'blob' }), | |
| exportDocx: (id: number) => api.get(`/research/reports/${id}/export/docx`, { responseType: 'blob' }), | |
| }; | |
| // ββ Holdings βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const holdingsAPI = { | |
| list: () => api.get('/holdings/'), | |
| create: (data: any) => api.post('/holdings/', data), | |
| update: (id: number, data: any) => api.put(`/holdings/${id}`, data), | |
| delete: (id: number) => api.delete(`/holdings/${id}`), | |
| summary: () => api.get('/holdings/summary'), | |
| stressTest: (data: { scenario_id?: string; custom_shock?: number }) => | |
| api.post('/holdings/stress-test', data), | |
| allStressTests: () => api.get('/holdings/stress-test/all'), | |
| hedgeRecommendations: () => api.get('/holdings/hedge-recommendations'), | |
| optionsHedge: () => api.get('/holdings/options-hedge'), | |
| rebalance: () => api.get('/holdings/rebalance'), | |
| correlation: () => api.get('/holdings/correlation'), | |
| }; | |
| // ββ Sentiment ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const sentimentAPI = { | |
| ticker: (ticker: string) => api.get(`/sentiment/ticker/${ticker}`), | |
| marketMood: () => api.get('/sentiment/market-mood'), | |
| multi: (tickers: string[]) => api.post('/sentiment/multi', tickers), | |
| portfolio: () => api.get('/sentiment/portfolio'), | |
| }; | |
| // ββ Calendar βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const calendarAPI = { | |
| events: (days?: number) => api.get(`/calendar/events${days ? `?days=${days}` : ''}`), | |
| publicEvents: (days?: number) => api.get(`/calendar/events/public${days ? `?days=${days}` : ''}`), | |
| }; | |
| // ββ ML Models ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export const mlAPI = { | |
| predict: (ticker: string, period?: string, horizon?: number) => | |
| api.post('/ml/predict', { ticker, period: period || '2y', horizon: horizon || 5 }), | |
| regime: (ticker: string, period?: string, history_days?: number) => | |
| api.post('/ml/regime', { ticker, period: period || '2y', history_days: history_days || 60 }), | |
| clearCache: () => api.post('/ml/clear-cache'), | |
| }; | |
| export default api; | |