py-trade / src /app /analysispage /analysispage.ts
Oviya
prediciton update
26a0a10
import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { Location } from '@angular/common';
import { NgApexchartsModule } from 'ng-apexcharts';
import { ChartService } from './chart.service';
import { MatPaginatorModule } from '@angular/material/paginator';
import { PageEvent } from '@angular/material/paginator';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@Component({
selector: 'app-analysispage',
standalone: true,
imports: [CommonModule, MatSlideToggleModule, MatCardModule, MatPaginatorModule, NgApexchartsModule],
templateUrl: './analysispage.html',
styleUrls: ['./analysispage.scss']
})
export class Analysispage implements OnInit {
originalOrder = (): number => 0;
private location = inject(Location);
result: any;
pageIndex = 0;
pageSize = 5;
sort: {
key: 'combined_overall_score' | 'overall_ta_score' | 'overall_fa_score' | 'news_overall_score',
direction: 'asc' | 'desc'
} = {
key: 'combined_overall_score',
direction: 'desc'
};
closeAreaOptions: any;
candlestickChartOptions: any;
overallChart: any;
strategyChart: any;
strategyChartIndex: number = 0;
predictedChart: any;
highLowChartOptions: any;
selectedIndicator: any = 'RSI';
selectedStrategy: any = 'RSI 14';
activeCompany: number = 0;
isCandlestick = true;
constructor(private chartService: ChartService) { }
ngOnInit(): void {
const s = this.location.getState() as { result?: unknown } | null;
this.result = s?.result ?? null;
const validData = this.result.filter((item: any) => !item.error);
const invalidData = this.result.filter((item: any) => item.error);
validData.sort((a: any, b: any) => b.combined_overall_score - a.combined_overall_score);
this.result = [...validData, ...invalidData];
console.log('Analysis result:', this.result);
this.loadCharts();
this.loadPredictedCharts();
this.loadStrategiesChart('RSI 14');
}
// Map a row to the numeric value for a given sort key
private sortValue(row: any, key: typeof this.sort.key): number {
switch (key) {
case 'combined_overall_score': return Number(row?.combined_overall_score ?? -Infinity);
case 'overall_ta_score': return Number(row?.overall_ta_score ?? -Infinity);
case 'overall_fa_score': return Number(row?.fundamental_analysis?.overall_fa_score ?? -Infinity);
case 'news_overall_score': return Number(row?.news_overall_score ?? -Infinity);
}
}
// Sorted list (used by the paginator slice)
get sortedResults(): any[] {
if (!Array.isArray(this.result)) return [];
const arr = [...this.result];
arr.sort((a, b) => {
const av = this.sortValue(a, this.sort.key);
const bv = this.sortValue(b, this.sort.key);
return this.sort.direction === 'asc' ? av - bv : bv - av;
});
return arr;
}
// Page slice over the sorted list
get pagedResults(): any[] {
const start = this.pageIndex * this.pageSize;
return this.sortedResults.slice(start, start + this.pageSize);
}
// Toggle sort on header click
toggleSort(key: typeof this.sort.key) {
if (this.sort.key === key) {
this.sort.direction = this.sort.direction === 'asc' ? 'desc' : 'asc';
} else {
this.sort.key = key;
this.sort.direction = 'desc'; // default direction on new column
}
this.pageIndex = 0; // reset to first page on sort change
}
// paginator change
onPage(e: PageEvent) {
this.pageIndex = e.pageIndex;
this.pageSize = e.pageSize;
}
showStrategies(selectedIndicator: any) {
this.selectedIndicator = selectedIndicator;
const strategies = this.result[this.activeCompany][selectedIndicator];
const firstStrategyKey = Object.keys(strategies)[0];
if (firstStrategyKey) {
this.selectedStrategy = firstStrategyKey;
this.loadStrategiesChart(firstStrategyKey);
}
}
loadStrategiesChart(strategyName: any) {
this.strategyChartIndex = 0;
this.selectedStrategy = strategyName;
this.strategyChart = this.chartService.getChartOptions(strategyName, this.result[this.activeCompany]);
console.log(this.strategyChart);
}
getClass(signal: any) {
if (typeof signal === 'string') {
switch (signal.toLowerCase()) {
case 'buy':
case 'good':
case 'positive':
case 'bullish':
return 'green';
case 'dbuy':
case 'bad':
case 'negative':
case 'bearish':
return 'red';
case 'neutral':
case 'none':
return 'yellow';
default:
return '';
}
} else {
return 'strategyvalue'
}
}
loadCharts() {
// close price chart
const data = this.result[this.activeCompany]['ohlc_data'] as Array<{ x: string; y: [number, number, number, number] }>;
// Optional: keep sorted and remove duplicate dates
const closeSeries = [...data]
.sort((a, b) => a.x.localeCompare(b.x))
.filter((d, i, arr) => i === 0 || d.x !== arr[i - 1].x)
.map(d => ({ x: d.x, y: d.y[3] })); // close = index 3
this.closeAreaOptions = {
chart: { type: 'area', height: 400, width: 1200 },
series: [
{
name: 'Close',
data: closeSeries // [{x: '2025-08-01', y: 2350.9}, ...]
}
],
xaxis: {
type: 'category',
labels: { style: { colors: '#ffffff' } }
},
yaxis: {
opposite: true,
labels: { style: { colors: '#ffffff' } }
},
tooltip: {
theme: 'dark'
}
};
//candlestick chart
this.candlestickChartOptions = {
chart: { type: 'candlestick', height: 400, width: 1200 },
series: [{ name: this.activeCompany, data }], // x can be a plain string when type='category'
xaxis: {
type: 'category',
labels: { style: { colors: '#ffffff' } }
},
yaxis: {
opposite: true,
labels: { style: { colors: '#ffffff' } }
},
tooltip: { theme: 'dark' }
};
}
loadPredictedCharts() {
//donut chart
this.overallChart = {
series: [
this.result[this.activeCompany].overall_ta_score,
this.result[this.activeCompany].overall_fa_score,
this.result[this.activeCompany].news_overall_score
], // Three values for the donut chart
chart: {
type: 'donut',
width: 500
},
labels: ['TA', 'FA', 'News'], // Set the labels to show on the chart
plotOptions: {
pie: {
donut: {
size: '60%', // Control the thickness of the donut
labels: {
show: true,
name: {
show: false
},
value: {
show: true, // Show values inside the donut chart
fontSize: '16px', // Font size for values
color: 'white' // White color for the values
},
total: {
show: true,
label: 'Total', // Label at the center
formatter: (w: any) => {
// Display the total value (sum of all slices)
return w.globals.seriesTotals.reduce((a: any, b: any) => a + b, 0) + '%';
}
}
}
}
}
},
fill: {
type: 'solid',
colors: ['#ff5733', '#33ff57', '#ffcc00'] // Colors for TA, FA, and News
},
tooltip: {
enabled: true, // Enable tooltips for the chart
fillSeriesColor: false,
theme: 'dark',
style: {
fontSize: '14px',
color: 'white' // White text color for tooltips
}
},
legend: {
show: true,
position: 'bottom', // Position the legend at the bottom
labels: {
useSeriesColors: true, // Use the series colors for legend
colors: ['white'] // White text color for legend
}
}
};
// Predicted High/Low 15-day chart (single chart with two series)
const highsRaw = this.result[this.activeCompany].ai_predicted_daily_high_15 ?? [];
const lowsRaw = this.result[this.activeCompany].ai_predicted_daily_low_15 ?? [];
const dates15 = this.result[this.activeCompany].ai_predicted_dates_15 ?? [];
const highs = highsRaw.map((v: any) => Number(Number(v).toFixed(2)));
const lows = lowsRaw.map((v: any) => Number(Number(v).toFixed(2)));
if (highs.length && lows.length && dates15.length && highs.length === lows.length && highs.length === dates15.length) {
this.highLowChartOptions = {
chart: { type: 'line', height: 400, width: 1500, toolbar: { show: false } },
series: [
{ name: 'Predicted High', data: highs, color: '#22C55E' }, // green
{ name: 'Predicted Low', data: lows, color: '#EF4444' } // red
],
stroke: { width: 2, curve: 'smooth' },
markers: { size: 3 },
xaxis: { categories: dates15, type: 'category', tickPlacement: 'on', labels: { rotate: -45, rotateAlways: true, hideOverlappingLabels: false, trim: false, minHeight: 70, style: { colors: '#ffffff', fontSize: '12px' } } },
yaxis: {
opposite: true,
labels: { style: { colors: '#ffffff' } }
},
tooltip: {
shared: true,
intersect: false,
theme: 'dark',
y: {
formatter: (val: number) => (val != null ? val.toFixed(2) : '')
}
},
legend: {
position: 'top',
labels: {
colors: '#ffffff',
useSeriesColors: false
}
}
};
} else {
this.highLowChartOptions = null;
}
}
selectCompany(index: number) {
this.activeCompany = index;
this.loadCharts();
this.loadPredictedCharts();
}
onModeChange(checked: boolean) {
this.isCandlestick = checked;
this.loadCharts();
}
previousChart(): void {
if (this.strategyChartIndex > 0) {
this.strategyChartIndex--;
}
}
nextChart(): void {
if (this.strategyChartIndex < this.strategyChart.length - 1) {
this.strategyChartIndex++;
}
}
}