running prettier for cleanup
This commit is contained in:
parent
24b7ed15e4
commit
8955544593
151 changed files with 29158 additions and 27966 deletions
|
|
@ -1,209 +1,238 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface TradingStrategy {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
status: 'ACTIVE' | 'INACTIVE' | 'PAUSED' | 'ERROR';
|
||||
type: string;
|
||||
symbols: string[];
|
||||
parameters: Record<string, any>;
|
||||
performance: {
|
||||
totalTrades: number;
|
||||
winRate: number;
|
||||
totalReturn: number;
|
||||
sharpeRatio: number;
|
||||
maxDrawdown: number;
|
||||
};
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface BacktestRequest {
|
||||
strategyType: string;
|
||||
strategyParams: Record<string, any>;
|
||||
symbols: string[];
|
||||
startDate: Date | string;
|
||||
endDate: Date | string;
|
||||
initialCapital: number;
|
||||
dataResolution: '1m' | '5m' | '15m' | '30m' | '1h' | '4h' | '1d';
|
||||
commission: number;
|
||||
slippage: number;
|
||||
mode: 'event' | 'vector';
|
||||
}
|
||||
|
||||
export interface BacktestResult {
|
||||
strategyId: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
duration: number;
|
||||
initialCapital: number;
|
||||
finalCapital: number;
|
||||
totalReturn: number;
|
||||
annualizedReturn: number;
|
||||
sharpeRatio: number;
|
||||
maxDrawdown: number;
|
||||
maxDrawdownDuration: number;
|
||||
winRate: number;
|
||||
totalTrades: number;
|
||||
winningTrades: number;
|
||||
losingTrades: number;
|
||||
averageWinningTrade: number;
|
||||
averageLosingTrade: number;
|
||||
profitFactor: number;
|
||||
dailyReturns: Array<{ date: Date; return: number }>;
|
||||
trades: Array<{
|
||||
symbol: string;
|
||||
entryTime: Date;
|
||||
entryPrice: number;
|
||||
exitTime: Date;
|
||||
exitPrice: number;
|
||||
quantity: number;
|
||||
pnl: number;
|
||||
pnlPercent: number;
|
||||
}>;
|
||||
// Advanced metrics
|
||||
sortinoRatio?: number;
|
||||
calmarRatio?: number;
|
||||
omegaRatio?: number;
|
||||
cagr?: number;
|
||||
volatility?: number;
|
||||
ulcerIndex?: number;
|
||||
}
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class StrategyService {
|
||||
private apiBaseUrl = '/api'; // Will be proxied to the correct backend endpoint
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
// Strategy Management
|
||||
getStrategies(): Observable<ApiResponse<TradingStrategy[]>> {
|
||||
return this.http.get<ApiResponse<TradingStrategy[]>>(`${this.apiBaseUrl}/strategies`);
|
||||
}
|
||||
|
||||
getStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.get<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}`);
|
||||
}
|
||||
|
||||
createStrategy(strategy: Partial<TradingStrategy>): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies`, strategy);
|
||||
}
|
||||
|
||||
updateStrategy(id: string, updates: Partial<TradingStrategy>): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.put<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}`, updates);
|
||||
}
|
||||
|
||||
startStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}/start`, {});
|
||||
}
|
||||
|
||||
stopStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}/stop`, {});
|
||||
}
|
||||
|
||||
pauseStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}/pause`, {});
|
||||
}
|
||||
|
||||
// Backtest Management
|
||||
getStrategyTypes(): Observable<ApiResponse<string[]>> {
|
||||
return this.http.get<ApiResponse<string[]>>(`${this.apiBaseUrl}/strategy-types`);
|
||||
}
|
||||
|
||||
getStrategyParameters(type: string): Observable<ApiResponse<Record<string, any>>> {
|
||||
return this.http.get<ApiResponse<Record<string, any>>>(`${this.apiBaseUrl}/strategy-parameters/${type}`);
|
||||
}
|
||||
|
||||
runBacktest(request: BacktestRequest): Observable<ApiResponse<BacktestResult>> {
|
||||
return this.http.post<ApiResponse<BacktestResult>>(`${this.apiBaseUrl}/backtest`, request);
|
||||
}
|
||||
getBacktestResult(id: string): Observable<ApiResponse<BacktestResult>> {
|
||||
return this.http.get<ApiResponse<BacktestResult>>(`${this.apiBaseUrl}/backtest/${id}`);
|
||||
}
|
||||
|
||||
optimizeStrategy(
|
||||
baseRequest: BacktestRequest,
|
||||
parameterGrid: Record<string, any[]>
|
||||
): Observable<ApiResponse<Array<BacktestResult & { parameters: Record<string, any> }>>> {
|
||||
return this.http.post<ApiResponse<Array<BacktestResult & { parameters: Record<string, any> }>>>(
|
||||
`${this.apiBaseUrl}/backtest/optimize`,
|
||||
{ baseRequest, parameterGrid }
|
||||
);
|
||||
}
|
||||
|
||||
// Strategy Signals and Trades
|
||||
getStrategySignals(strategyId: string): Observable<ApiResponse<Array<{
|
||||
id: string;
|
||||
strategyId: string;
|
||||
symbol: string;
|
||||
action: string;
|
||||
price: number;
|
||||
quantity: number;
|
||||
timestamp: Date;
|
||||
confidence: number;
|
||||
metadata?: any;
|
||||
}>>> {
|
||||
return this.http.get<ApiResponse<any[]>>(`${this.apiBaseUrl}/strategies/${strategyId}/signals`);
|
||||
}
|
||||
|
||||
getStrategyTrades(strategyId: string): Observable<ApiResponse<Array<{
|
||||
id: string;
|
||||
strategyId: string;
|
||||
symbol: string;
|
||||
entryPrice: number;
|
||||
entryTime: Date;
|
||||
exitPrice: number;
|
||||
exitTime: Date;
|
||||
quantity: number;
|
||||
pnl: number;
|
||||
pnlPercent: number;
|
||||
}>>> {
|
||||
return this.http.get<ApiResponse<any[]>>(`${this.apiBaseUrl}/strategies/${strategyId}/trades`);
|
||||
}
|
||||
|
||||
// Helper methods for common transformations
|
||||
formatBacktestRequest(formData: any): BacktestRequest {
|
||||
// Handle date formatting and parameter conversion
|
||||
return {
|
||||
...formData,
|
||||
startDate: formData.startDate instanceof Date ? formData.startDate.toISOString() : formData.startDate,
|
||||
endDate: formData.endDate instanceof Date ? formData.endDate.toISOString() : formData.endDate,
|
||||
strategyParams: this.convertParameterTypes(formData.strategyType, formData.strategyParams)
|
||||
};
|
||||
}
|
||||
|
||||
private convertParameterTypes(strategyType: string, params: Record<string, any>): Record<string, any> {
|
||||
// Convert string parameters to correct types based on strategy requirements
|
||||
const result: Record<string, any> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
if (typeof value === 'string') {
|
||||
// Try to convert to number if it looks like a number
|
||||
if (!isNaN(Number(value))) {
|
||||
result[key] = Number(value);
|
||||
} else if (value.toLowerCase() === 'true') {
|
||||
result[key] = true;
|
||||
} else if (value.toLowerCase() === 'false') {
|
||||
result[key] = false;
|
||||
} else {
|
||||
result[key] = value;
|
||||
}
|
||||
} else {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface TradingStrategy {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
status: 'ACTIVE' | 'INACTIVE' | 'PAUSED' | 'ERROR';
|
||||
type: string;
|
||||
symbols: string[];
|
||||
parameters: Record<string, any>;
|
||||
performance: {
|
||||
totalTrades: number;
|
||||
winRate: number;
|
||||
totalReturn: number;
|
||||
sharpeRatio: number;
|
||||
maxDrawdown: number;
|
||||
};
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface BacktestRequest {
|
||||
strategyType: string;
|
||||
strategyParams: Record<string, any>;
|
||||
symbols: string[];
|
||||
startDate: Date | string;
|
||||
endDate: Date | string;
|
||||
initialCapital: number;
|
||||
dataResolution: '1m' | '5m' | '15m' | '30m' | '1h' | '4h' | '1d';
|
||||
commission: number;
|
||||
slippage: number;
|
||||
mode: 'event' | 'vector';
|
||||
}
|
||||
|
||||
export interface BacktestResult {
|
||||
strategyId: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
duration: number;
|
||||
initialCapital: number;
|
||||
finalCapital: number;
|
||||
totalReturn: number;
|
||||
annualizedReturn: number;
|
||||
sharpeRatio: number;
|
||||
maxDrawdown: number;
|
||||
maxDrawdownDuration: number;
|
||||
winRate: number;
|
||||
totalTrades: number;
|
||||
winningTrades: number;
|
||||
losingTrades: number;
|
||||
averageWinningTrade: number;
|
||||
averageLosingTrade: number;
|
||||
profitFactor: number;
|
||||
dailyReturns: Array<{ date: Date; return: number }>;
|
||||
trades: Array<{
|
||||
symbol: string;
|
||||
entryTime: Date;
|
||||
entryPrice: number;
|
||||
exitTime: Date;
|
||||
exitPrice: number;
|
||||
quantity: number;
|
||||
pnl: number;
|
||||
pnlPercent: number;
|
||||
}>;
|
||||
// Advanced metrics
|
||||
sortinoRatio?: number;
|
||||
calmarRatio?: number;
|
||||
omegaRatio?: number;
|
||||
cagr?: number;
|
||||
volatility?: number;
|
||||
ulcerIndex?: number;
|
||||
}
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class StrategyService {
|
||||
private apiBaseUrl = '/api'; // Will be proxied to the correct backend endpoint
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
// Strategy Management
|
||||
getStrategies(): Observable<ApiResponse<TradingStrategy[]>> {
|
||||
return this.http.get<ApiResponse<TradingStrategy[]>>(`${this.apiBaseUrl}/strategies`);
|
||||
}
|
||||
|
||||
getStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.get<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies/${id}`);
|
||||
}
|
||||
|
||||
createStrategy(strategy: Partial<TradingStrategy>): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(`${this.apiBaseUrl}/strategies`, strategy);
|
||||
}
|
||||
|
||||
updateStrategy(
|
||||
id: string,
|
||||
updates: Partial<TradingStrategy>
|
||||
): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.put<ApiResponse<TradingStrategy>>(
|
||||
`${this.apiBaseUrl}/strategies/${id}`,
|
||||
updates
|
||||
);
|
||||
}
|
||||
|
||||
startStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(
|
||||
`${this.apiBaseUrl}/strategies/${id}/start`,
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
stopStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(
|
||||
`${this.apiBaseUrl}/strategies/${id}/stop`,
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
pauseStrategy(id: string): Observable<ApiResponse<TradingStrategy>> {
|
||||
return this.http.post<ApiResponse<TradingStrategy>>(
|
||||
`${this.apiBaseUrl}/strategies/${id}/pause`,
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
// Backtest Management
|
||||
getStrategyTypes(): Observable<ApiResponse<string[]>> {
|
||||
return this.http.get<ApiResponse<string[]>>(`${this.apiBaseUrl}/strategy-types`);
|
||||
}
|
||||
|
||||
getStrategyParameters(type: string): Observable<ApiResponse<Record<string, any>>> {
|
||||
return this.http.get<ApiResponse<Record<string, any>>>(
|
||||
`${this.apiBaseUrl}/strategy-parameters/${type}`
|
||||
);
|
||||
}
|
||||
|
||||
runBacktest(request: BacktestRequest): Observable<ApiResponse<BacktestResult>> {
|
||||
return this.http.post<ApiResponse<BacktestResult>>(`${this.apiBaseUrl}/backtest`, request);
|
||||
}
|
||||
getBacktestResult(id: string): Observable<ApiResponse<BacktestResult>> {
|
||||
return this.http.get<ApiResponse<BacktestResult>>(`${this.apiBaseUrl}/backtest/${id}`);
|
||||
}
|
||||
|
||||
optimizeStrategy(
|
||||
baseRequest: BacktestRequest,
|
||||
parameterGrid: Record<string, any[]>
|
||||
): Observable<ApiResponse<Array<BacktestResult & { parameters: Record<string, any> }>>> {
|
||||
return this.http.post<ApiResponse<Array<BacktestResult & { parameters: Record<string, any> }>>>(
|
||||
`${this.apiBaseUrl}/backtest/optimize`,
|
||||
{ baseRequest, parameterGrid }
|
||||
);
|
||||
}
|
||||
|
||||
// Strategy Signals and Trades
|
||||
getStrategySignals(strategyId: string): Observable<
|
||||
ApiResponse<
|
||||
Array<{
|
||||
id: string;
|
||||
strategyId: string;
|
||||
symbol: string;
|
||||
action: string;
|
||||
price: number;
|
||||
quantity: number;
|
||||
timestamp: Date;
|
||||
confidence: number;
|
||||
metadata?: any;
|
||||
}>
|
||||
>
|
||||
> {
|
||||
return this.http.get<ApiResponse<any[]>>(`${this.apiBaseUrl}/strategies/${strategyId}/signals`);
|
||||
}
|
||||
|
||||
getStrategyTrades(strategyId: string): Observable<
|
||||
ApiResponse<
|
||||
Array<{
|
||||
id: string;
|
||||
strategyId: string;
|
||||
symbol: string;
|
||||
entryPrice: number;
|
||||
entryTime: Date;
|
||||
exitPrice: number;
|
||||
exitTime: Date;
|
||||
quantity: number;
|
||||
pnl: number;
|
||||
pnlPercent: number;
|
||||
}>
|
||||
>
|
||||
> {
|
||||
return this.http.get<ApiResponse<any[]>>(`${this.apiBaseUrl}/strategies/${strategyId}/trades`);
|
||||
}
|
||||
|
||||
// Helper methods for common transformations
|
||||
formatBacktestRequest(formData: any): BacktestRequest {
|
||||
// Handle date formatting and parameter conversion
|
||||
return {
|
||||
...formData,
|
||||
startDate:
|
||||
formData.startDate instanceof Date ? formData.startDate.toISOString() : formData.startDate,
|
||||
endDate: formData.endDate instanceof Date ? formData.endDate.toISOString() : formData.endDate,
|
||||
strategyParams: this.convertParameterTypes(formData.strategyType, formData.strategyParams),
|
||||
};
|
||||
}
|
||||
|
||||
private convertParameterTypes(
|
||||
strategyType: string,
|
||||
params: Record<string, any>
|
||||
): Record<string, any> {
|
||||
// Convert string parameters to correct types based on strategy requirements
|
||||
const result: Record<string, any> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
if (typeof value === 'string') {
|
||||
// Try to convert to number if it looks like a number
|
||||
if (!isNaN(Number(value))) {
|
||||
result[key] = Number(value);
|
||||
} else if (value.toLowerCase() === 'true') {
|
||||
result[key] = true;
|
||||
} else if (value.toLowerCase() === 'false') {
|
||||
result[key] = false;
|
||||
} else {
|
||||
result[key] = value;
|
||||
}
|
||||
} else {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue