This commit is contained in:
Boki 2025-06-11 10:35:15 -04:00
parent 8955544593
commit 9d38f9a7b6
91 changed files with 2224 additions and 1400 deletions

View file

@ -1,5 +1,5 @@
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
{
"plugins": {
"@tailwindcss/postcss": {}
}
}

View file

@ -1,4 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}

View file

@ -1,20 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}

View file

@ -1,42 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}

View file

@ -1,44 +1,44 @@
{
"name": "trading-dashboard",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"devvvv": "ng serve --port 5173 --host 0.0.0.0",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^20.0.0",
"@angular/cdk": "^20.0.1",
"@angular/common": "^20.0.0",
"@angular/compiler": "^20.0.0",
"@angular/core": "^20.0.0",
"@angular/forms": "^20.0.0",
"@angular/material": "^20.0.1",
"@angular/platform-browser": "^20.0.0",
"@angular/router": "^20.0.0",
"rxjs": "~7.8.2",
"tslib": "^2.8.1",
"zone.js": "~0.15.1"
},
"devDependencies": {
"@angular/build": "^20.0.0",
"@angular/cli": "^20.0.0",
"@angular/compiler-cli": "^20.0.0",
"@tailwindcss/postcss": "^4.1.8",
"@types/jasmine": "~5.1.8",
"autoprefixer": "^10.4.21",
"jasmine-core": "~5.7.1",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.1",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"postcss": "^8.5.4",
"tailwindcss": "^4.1.8",
"typescript": "~5.8.3"
}
}
{
"name": "trading-dashboard",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"devvvv": "ng serve --port 5173 --host 0.0.0.0",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^20.0.0",
"@angular/cdk": "^20.0.1",
"@angular/common": "^20.0.0",
"@angular/compiler": "^20.0.0",
"@angular/core": "^20.0.0",
"@angular/forms": "^20.0.0",
"@angular/material": "^20.0.1",
"@angular/platform-browser": "^20.0.0",
"@angular/router": "^20.0.0",
"rxjs": "~7.8.2",
"tslib": "^2.8.1",
"zone.js": "~0.15.1"
},
"devDependencies": {
"@angular/build": "^20.0.0",
"@angular/cli": "^20.0.0",
"@angular/compiler-cli": "^20.0.0",
"@tailwindcss/postcss": "^4.1.8",
"@types/jasmine": "~5.1.8",
"autoprefixer": "^10.4.21",
"jasmine-core": "~5.7.1",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.1",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"postcss": "^8.5.4",
"tailwindcss": "^4.1.8",
"typescript": "~5.8.3"
}
}

View file

@ -82,11 +82,11 @@ export class NotificationsComponent {
const diff = now.getTime() - timestamp.getTime();
const minutes = Math.floor(diff / 60000);
if (minutes < 1) return 'Just now';
if (minutes < 60) return `${minutes}m ago`;
if (minutes < 1) {return 'Just now';}
if (minutes < 60) {return `${minutes}m ago`;}
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
if (hours < 24) {return `${hours}h ago`;}
const days = Math.floor(hours / 24);
return `${days}d ago`;

View file

@ -161,8 +161,8 @@ export class PortfolioComponent implements OnInit, OnDestroy {
}
getPnLColor(value: number): string {
if (value > 0) return 'text-green-600';
if (value < 0) return 'text-red-600';
if (value > 0) {return 'text-green-600';}
if (value < 0) {return 'text-red-600';}
return 'text-gray-600';
}
}

View file

@ -40,7 +40,7 @@ export class DrawdownChartComponent implements OnChanges {
}
private renderChart(): void {
if (!this.chartElement || !this.backtestResult) return;
if (!this.chartElement || !this.backtestResult) {return;}
// Clean up previous chart if it exists
if (this.chart) {

View file

@ -40,7 +40,7 @@ export class EquityChartComponent implements OnChanges {
}
private renderChart(): void {
if (!this.chartElement || !this.backtestResult) return;
if (!this.chartElement || !this.backtestResult) {return;}
// Clean up previous chart if it exists
if (this.chart) {

View file

@ -278,27 +278,27 @@ export class PerformanceMetricsComponent {
// Conditional classes
getReturnClass(value: number): string {
if (value > 0) return 'positive';
if (value < 0) return 'negative';
if (value > 0) {return 'positive';}
if (value < 0) {return 'negative';}
return '';
}
getRatioClass(value: number): string {
if (value >= 1.5) return 'positive';
if (value >= 1) return 'neutral';
if (value < 0) return 'negative';
if (value >= 1.5) {return 'positive';}
if (value >= 1) {return 'neutral';}
if (value < 0) {return 'negative';}
return '';
}
getWinRateClass(value: number): string {
if (value >= 0.55) return 'positive';
if (value >= 0.45) return 'neutral';
if (value >= 0.55) {return 'positive';}
if (value >= 0.45) {return 'neutral';}
return 'negative';
}
getProfitFactorClass(value: number): string {
if (value >= 1.5) return 'positive';
if (value >= 1) return 'neutral';
if (value >= 1.5) {return 'positive';}
if (value >= 1) {return 'neutral';}
return 'negative';
}
}

View file

@ -139,7 +139,7 @@ export class BacktestDialogComponent implements OnInit {
}
addSymbol(symbol: string): void {
if (!symbol || this.selectedSymbols.includes(symbol)) return;
if (!symbol || this.selectedSymbols.includes(symbol)) {return;}
this.selectedSymbols.push(symbol);
}

View file

@ -126,7 +126,7 @@ export class StrategyDialogComponent implements OnInit {
}
addSymbol(symbol: string): void {
if (!symbol || this.selectedSymbols.includes(symbol)) return;
if (!symbol || this.selectedSymbols.includes(symbol)) {return;}
this.selectedSymbols.push(symbol);
}

View file

@ -67,7 +67,9 @@ export class StrategyDetailsComponent implements OnChanges {
}
loadStrategyData(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
// In a real implementation, these would call API methods to fetch the data
this.loadSignals();
@ -75,7 +77,9 @@ export class StrategyDetailsComponent implements OnChanges {
this.loadPerformance();
}
loadSignals(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
this.isLoadingSignals = true;
@ -100,7 +104,9 @@ export class StrategyDetailsComponent implements OnChanges {
}
loadTrades(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
this.isLoadingTrades = true;
@ -140,7 +146,9 @@ export class StrategyDetailsComponent implements OnChanges {
};
}
listenForUpdates(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
// Subscribe to strategy signals
this.webSocketService.getStrategySignals(this.strategy.id).subscribe((signal: any) => {
@ -186,7 +194,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Update performance metrics when new trades come in
*/
private updatePerformanceMetrics(): void {
if (!this.strategy || this.trades.length === 0) return;
if (!this.strategy || this.trades.length === 0) {
return;
}
// Calculate basic metrics
const winningTrades = this.trades.filter(t => t.pnl > 0);
@ -201,6 +211,8 @@ export class StrategyDetailsComponent implements OnChanges {
...currentPerformance,
totalTrades: this.trades.length,
winRate: winRate,
winningTrades,
losingTrades,
totalReturn: (currentPerformance.totalReturn || 0) + totalPnl / 10000, // Approximate
};
@ -242,7 +254,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Open the backtest dialog to run a backtest for this strategy
*/
openBacktestDialog(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
const dialogRef = this.dialog.open(BacktestDialogComponent, {
width: '800px',
@ -261,7 +275,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Open the strategy edit dialog
*/
openEditDialog(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
const dialogRef = this.dialog.open(StrategyDialogComponent, {
width: '600px',
@ -280,7 +296,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Start the strategy
*/
activateStrategy(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
this.strategyService.startStrategy(this.strategy.id).subscribe({
next: response => {
@ -298,7 +316,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Pause the strategy
*/
pauseStrategy(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
this.strategyService.pauseStrategy(this.strategy.id).subscribe({
next: response => {
@ -316,7 +336,9 @@ export class StrategyDetailsComponent implements OnChanges {
* Stop the strategy
*/
stopStrategy(): void {
if (!this.strategy) return;
if (!this.strategy) {
return;
}
this.strategyService.stopStrategy(this.strategy.id).subscribe({
next: response => {
@ -332,7 +354,9 @@ export class StrategyDetailsComponent implements OnChanges {
// Methods to generate mock data
private generateMockSignals(): any[] {
if (!this.strategy) return [];
if (!this.strategy) {
return [];
}
const signals = [];
const actions = ['BUY', 'SELL', 'HOLD'];
@ -358,7 +382,9 @@ export class StrategyDetailsComponent implements OnChanges {
}
private generateMockTrades(): any[] {
if (!this.strategy) return [];
if (!this.strategy) {
return [];
}
const trades = [];
const now = new Date();

View file

@ -1,5 +1,5 @@
import { Injectable, signal } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { Observable, Subject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
export interface WebSocketMessage {
@ -204,7 +204,7 @@ export class WebSocketService {
// Cleanup
disconnect() {
this.connections.forEach((ws, serviceName) => {
this.connections.forEach((ws, _serviceName) => {
if (ws.readyState === WebSocket.OPEN) {
ws.close();
}

View file

@ -1,15 +1,11 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/**/*.spec.ts"
]
}
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.spec.ts"]
}

View file

@ -1,32 +1,32 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "../../tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"isolatedModules": true,
"experimentalDecorators": true,
"importHelpers": true,
"module": "preserve"
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"typeCheckHostBindings": true,
"strictTemplates": true
},
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "../../tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"isolatedModules": true,
"experimentalDecorators": true,
"importHelpers": true,
"module": "preserve"
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"typeCheckHostBindings": true,
"strictTemplates": true
},
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}

View file

@ -1,14 +1,10 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"src/**/*.ts"
]
}
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": ["jasmine"]
},
"include": ["src/**/*.ts"]
}