From e4728cf79eb228a266449c85e48b6af25ae0bf8c Mon Sep 17 00:00:00 2001 From: SmartRootsSrl Date: Wed, 27 May 2026 16:35:48 +0200 Subject: [PATCH] fix: revert to cedlab_Chart_UL1 (already has all V2 fields); remove cedlab_Chart_UL2; fix AllSeriesV2 SQL with DailyUL1 logic --- .gitignore | 3 + .../Implementations/ChartDataServiceV2.cs | 5 +- docs/sql/cedlab_Chart_AllSeriesV2.sql | 55 ++++++---- docs/sql/cedlab_Chart_UL1.sql | 90 ---------------- docs/sql/cedlab_Chart_UL2.sql | 102 ------------------ 5 files changed, 39 insertions(+), 216 deletions(-) delete mode 100644 docs/sql/cedlab_Chart_UL1.sql delete mode 100644 docs/sql/cedlab_Chart_UL2.sql diff --git a/.gitignore b/.gitignore index 2b0f986..89f892f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Git worktrees .worktrees/ +# Windows artifacts +nul + # Visual Studio .vs/ *.user diff --git a/CertReports.Syncfusion/Services/Implementations/ChartDataServiceV2.cs b/CertReports.Syncfusion/Services/Implementations/ChartDataServiceV2.cs index 4fdc6bc..94ded5c 100644 --- a/CertReports.Syncfusion/Services/Implementations/ChartDataServiceV2.cs +++ b/CertReports.Syncfusion/Services/Implementations/ChartDataServiceV2.cs @@ -33,10 +33,11 @@ public class ChartDataServiceV2 : IChartDataServiceV2 await using var conn = new SqlConnection(_connectionString); await conn.OpenAsync(); - // ── 1. Metadata sottostanti (cedlab_Chart_UL2) ───────────────── + // ── 1. Metadata sottostanti (cedlab_Chart_UL1) ───────────────── + // cedlab_Chart_UL1 già restituisce tutti i campi necessari per V2 var underlyings = new List(); - await using (var cmd = new SqlCommand("cedlab_Chart_UL2", conn) + await using (var cmd = new SqlCommand("cedlab_Chart_UL1", conn) { CommandType = CommandType.StoredProcedure }) { cmd.Parameters.AddWithValue("@isin", isin); diff --git a/docs/sql/cedlab_Chart_AllSeriesV2.sql b/docs/sql/cedlab_Chart_AllSeriesV2.sql index a94c9af..3e4cd45 100644 --- a/docs/sql/cedlab_Chart_AllSeriesV2.sql +++ b/docs/sql/cedlab_Chart_AllSeriesV2.sql @@ -3,18 +3,19 @@ GO -- ============================================================ -- SP: cedlab_Chart_AllSeriesV2 --- Restituisce tutte le serie (CTF + UL) in un unico round-trip. +-- Restituisce tutte le serie (CTF + tutti UL) in un unico round-trip. -- Usata da ChartDataServiceV2 per il grafico V2. -- -- Logica UL: identica a cedlab_Chart_DailyUL1, estesa a tutti i --- sottostanti del certificato in un unico UNION ALL. +-- sottostanti del certificato tramite INNER JOIN su dbo.Underlyings. -- -- Output (ordinato IDUnderlyings ASC, Px_date ASC): -- IDUnderlyings INT -- 0 = CTF, altrimenti UnderlyingsID -- Px_date DATE -- Performance DECIMAL -- % su strike/nominal -- --- Colonne con <<< verify: adatta al tuo schema reale. +-- Note: cedlab_Chart_UL1 già restituisce tutti i campi metadata +-- (IsWorstOf, PriceWorst, Barriere, NomeCFT, ecc.) — non serve una nuova SP. -- ============================================================ CREATE OR ALTER PROCEDURE [dbo].[cedlab_Chart_AllSeriesV2] @@ -23,32 +24,42 @@ AS BEGIN SET NOCOUNT ON; + -- Recupera IDCertificates DECLARE @IDCertificates INT; DECLARE @Nominal DECIMAL(18, 6); SELECT TOP 1 - @IDCertificates = c.IDCertificates, -- <<< verify - @Nominal = c.Nominal_amount -- <<< verify: valore nominale per CTF % - FROM [dbo].[Certificates] c -- <<< verify: nome tabella certificati - WHERE c.ISIN = @isin; + @IDCertificates = p.CertificatesID + FROM dbo.Prices p + INNER JOIN dbo.Certificates c ON c.IDCertificates = p.CertificatesID -- <<< verify: tabella e colonna ISIN in Certificates + WHERE c.ISIN = @isin + AND p.PX_LAST_EOD IS NOT NULL + AND p.PX_LAST_EOD <> 0; + + -- Nominal per calcolo performance CTF: adatta se usi un'altra colonna + SELECT TOP 1 + @Nominal = c.Nominal_amount -- <<< verify: colonna nominale in Certificates + FROM dbo.Certificates c + WHERE c.IDCertificates = @IDCertificates; IF @IDCertificates IS NULL RETURN; - -- ── CTE: calcola performance per ogni serie, TOP 350 per-serie ───── + -- ── CTE: TOP 350 per-serie, poi reinverte in ASC ─────────────────── WITH AllSeriesRaw AS ( -- ── Serie CTF (IDUnderlyings = 0) ──────────────────────────────── -- Performance = PX_LAST_EOD / Nominal * 100 - SELECT - 0 AS IDUnderlyings, + -- (stessa logica di cedlab_Chart_DailyCTF) + SELECT TOP 350 + 0 AS IDUnderlyings, pc.Px_date, CONVERT(DECIMAL(18, 4), pc.PX_LAST_EOD / NULLIF(@Nominal, 0) * 100 - ) AS Performance, + ) AS Performance, ROW_NUMBER() OVER ( PARTITION BY 0 ORDER BY pc.Px_date DESC - ) AS rn + ) AS rn FROM dbo.Prices pc WHERE pc.CertificatesID = @IDCertificates AND pc.PX_LAST_EOD IS NOT NULL @@ -56,11 +67,12 @@ BEGIN UNION ALL - -- ── Serie UL (una per ogni sottostante) ────────────────────────── - -- Stessa logica di cedlab_Chart_DailyUL1, estesa a tutti gli UL. + -- ── Serie UL (tutti i sottostanti del certificato) ──────────────── + -- Performance = (Px_close o Px_closeadj) / Strike * 100 + -- Identica a cedlab_Chart_DailyUL1 ma per TUTTI gli UL in un colpo. -- Date allineate al CTF (INNER JOIN su Px_date). - SELECT - pu.UnderlyingsID AS IDUnderlyings, + SELECT TOP 350 + pu.UnderlyingsID AS IDUnderlyings, pu.Px_date, CONVERT(DECIMAL(18, 4), CASE @@ -68,29 +80,28 @@ BEGIN ELSE pu.Px_closeadj END / NULLIF(u.Strike, 0) * 100 - ) AS Performance, + ) AS Performance, ROW_NUMBER() OVER ( PARTITION BY pu.UnderlyingsID ORDER BY pu.Px_date DESC - ) AS rn + ) AS rn FROM dbo.Prices pu LEFT JOIN dbo.Underlyings u ON u.IDUnderlyings = pu.UnderlyingsID - -- Allinea date UL al CTF (solo date presenti nel certificato) + -- Allinea date UL al CTF (solo date con prezzo CTF valido) INNER JOIN dbo.Prices pc ON pu.Px_date = pc.Px_date AND pc.CertificatesID = @IDCertificates AND pc.PX_LAST_EOD IS NOT NULL AND pc.PX_LAST_EOD <> 0 - WHERE u.IDCertificates = @IDCertificates -- <<< verify: colonna FK in Underlyings + WHERE u.IDCertificates = @IDCertificates AND ( pu.px_low IS NOT NULL OR pu.Px_high IS NOT NULL OR pu.Px_open IS NOT NULL OR pu.Px_close IS NOT NULL ) - AND pu.px_date >= u.StartDate -- <<< verify: colonna StartDate in Underlyings + AND pu.px_date >= u.StartDate -- <<< verify: colonna StartDate in Underlyings ) - -- ── Filtra TOP 350 per serie e reinverte in ordine ASC ─────────────── SELECT IDUnderlyings, Px_date, diff --git a/docs/sql/cedlab_Chart_UL1.sql b/docs/sql/cedlab_Chart_UL1.sql deleted file mode 100644 index 64cfd7d..0000000 --- a/docs/sql/cedlab_Chart_UL1.sql +++ /dev/null @@ -1,90 +0,0 @@ --- ============================================================ --- SP: cedlab_Chart_UL1 --- Metadata dei sottostanti per il grafico V2. --- Estende FSWeb_Chart_UL con: --- IsWorstOf, PriceWorst, PriceWorstPerc, --- NumPrezziCFT, NomeCFT, --- BarrieraCouponPerc, BarrieraCapitalePerc, --- TriggerAutocallPerc, AutocallValue --- --- Ordinato: IsWorstOf DESC (worst-of nella prima riga) --- --- NOTA: se questa SP esiste già nel DB con questo nome e restituisce --- già tutte queste colonne, questo file è solo documentazione. --- Eseguilo solo se la SP non esiste o mancano le colonne. --- --- ADATTAMENTO RICHIESTO: stessi nomi tabella del file cedlab_Chart_AllSeriesV2.sql --- ============================================================ - -USE [FirstSolutionDB] -GO - -CREATE OR ALTER PROCEDURE [dbo].[cedlab_Chart_UL1] - @isin NVARCHAR(12) -AS -BEGIN - SET NOCOUNT ON; - - -- Numero prezzi CTF disponibili (usato per il sub-titolo) - DECLARE @NumPrezziCFT INT; - DECLARE @IDCertificates INT; - DECLARE @Nominal DECIMAL(18,6); - DECLARE @NomeCFT NVARCHAR(200); - - SELECT TOP 1 - @IDCertificates = c.IDCertificates, -- <<< adatta - @Nominal = c.Nominal_amount, -- <<< adatta - @NomeCFT = c.Descrizione + ' - ' + c.ISIN -- <<< adatta - FROM [dbo].[Certificates] c -- <<< adatta - WHERE c.ISIN = @isin; - - SELECT @NumPrezziCFT = COUNT(*) - FROM [dbo].[CFT_PriceHistory] -- <<< adatta - WHERE IDCertificates = @IDCertificates; - - -- Prezzo attuale worst-of (prezzo corrente / strike * 100) - -- La logica di IsWorstOf dipende dalla tua definizione (es: peggior performer) - SELECT - u.IDCertificates, - u.IDUnderlyings, - u.StartDate, -- <<< adatta - u.Strike, -- <<< adatta - -- Percentuali barriere (es: BarrieraCoupon / Nominal * 100) - u.BarrieraCouponPerc, -- <<< adatta o calcola - u.BarrieraCoupon, -- <<< adatta (valore assoluto) - u.BarrieraCapitalePerc, -- <<< adatta o calcola - u.BarrieraCapitale, -- <<< adatta (valore assoluto) - u.Name AS Sottostante, -- <<< adatta nome colonna - u.IsWorstOf, -- <<< adatta: 1=worst-of, 0=altri - -- Prezzo attuale worst-of: 0 per non-worst-of - CASE WHEN u.IsWorstOf = 1 - THEN ISNULL(last_px.Px_close, 0) -- <<< adatta: ultimo prezzo disponibile - ELSE 0 - END AS PriceWorst, - CASE WHEN u.IsWorstOf = 1 AND u.Strike > 0 - THEN ISNULL(last_px.Px_close, 0) / u.Strike * 100 - ELSE 0 - END AS PriceWorstPerc, - @NumPrezziCFT AS NumPrezziCFT, - @NomeCFT AS NomeCFT, - ISNULL(u.TriggerAutocallPerc, 0) AS TriggerAutocallPerc, -- <<< adatta - ISNULL(u.AutocallValue, 0) AS AutocallValue -- <<< adatta - FROM [dbo].[Underlyings] u -- <<< adatta nome tabella - -- Join per ottenere l'ultimo prezzo disponibile - LEFT JOIN ( - SELECT ul.IDCertificates, ul.IDUnderlyings, - ul.Px_close, - ROW_NUMBER() OVER ( - PARTITION BY ul.IDCertificates, ul.IDUnderlyings - ORDER BY ul.Px_date DESC - ) AS rn - FROM [dbo].[UL_PriceHistory] ul -- <<< adatta nome tabella - ) last_px - ON last_px.IDCertificates = u.IDCertificates - AND last_px.IDUnderlyings = u.IDUnderlyings - AND last_px.rn = 1 - WHERE u.IDCertificates = @IDCertificates - ORDER BY u.IsWorstOf DESC; -- worst-of prima - -END -GO diff --git a/docs/sql/cedlab_Chart_UL2.sql b/docs/sql/cedlab_Chart_UL2.sql deleted file mode 100644 index a55c185..0000000 --- a/docs/sql/cedlab_Chart_UL2.sql +++ /dev/null @@ -1,102 +0,0 @@ -USE [FirstSolutionDB] -GO - --- ============================================================ --- SP: cedlab_Chart_UL2 --- Metadata dei sottostanti per il grafico V2. --- NON modifica cedlab_Chart_UL1 (esistente, usata altrove). --- --- Restituisce (ordinato IsWorstOf DESC, worst-of nella prima riga): --- IDCertificates, IDUnderlyings, StartDate, Strike, --- BarrieraCouponPerc, BarrieraCoupon, --- BarrieraCapitalePerc, BarrieraCapitale, --- Sottostante, IsWorstOf, --- PriceWorst, PriceWorstPerc, --- NumPrezziCFT, NomeCFT, --- TriggerAutocallPerc, AutocallValue --- --- Colonne con <<< verify: adatta al tuo schema reale. --- ============================================================ - -CREATE OR ALTER PROCEDURE [dbo].[cedlab_Chart_UL2] - @isin NVARCHAR(12) -AS -BEGIN - SET NOCOUNT ON; - - -- Recupera IDCertificates - DECLARE @IDCertificates INT; - - SELECT TOP 1 - @IDCertificates = c.IDCertificates -- <<< verify: colonna ID nel tuo Certificates - FROM [dbo].[Certificates] c -- <<< verify: nome tabella certificati - WHERE c.ISIN = @isin; - - IF @IDCertificates IS NULL RETURN; - - -- Conta prezzi EOD disponibili del certificato (usato per il sub-titolo "< 30 gg") - DECLARE @NumPrezziCFT INT; - SELECT @NumPrezziCFT = COUNT(*) - FROM dbo.Prices - WHERE CertificatesID = @IDCertificates - AND PX_LAST_EOD IS NOT NULL - AND PX_LAST_EOD <> 0; - - SELECT - u.IDCertificates, - u.IDUnderlyings, - u.StartDate, -- <<< verify: colonna StartDate in Underlyings - u.Strike, -- <<< verify: colonna Strike in Underlyings - - -- Barriere (% e assolute) - u.BarrieraCouponPerc, -- <<< verify: colonna % barriera coupon - u.BarrieraCoupon, -- <<< verify: colonna assoluta barriera coupon - u.BarrieraCapitalePerc, -- <<< verify: colonna % barriera capitale - u.BarrieraCapitale, -- <<< verify: colonna assoluta barriera capitale - - u.Name AS Sottostante, -- <<< verify: colonna nome sottostante - - u.IsWorstOf, -- <<< verify: colonna 1/0 worst-of in Underlyings - - -- PriceWorst: ultimo Px_close per il worst-of (0 per gli altri) - CASE - WHEN u.IsWorstOf = 1 THEN ISNULL(lp.Px_close, 0) - ELSE 0 - END AS PriceWorst, - - -- PriceWorstPerc: PriceWorst / Strike * 100 - CASE - WHEN u.IsWorstOf = 1 AND ISNULL(u.Strike, 0) > 0 - THEN ISNULL(lp.Px_close, 0) / u.Strike * 100 - ELSE 0 - END AS PriceWorstPerc, - - @NumPrezziCFT AS NumPrezziCFT, - - -- NomeCFT: Descrizione + ' - ' + ISIN (adatta nomi colonne) - c.Descrizione + ' - ' + c.ISIN AS NomeCFT, -- <<< verify: colonne Descrizione e ISIN - - ISNULL(u.TriggerAutocallPerc, 0) AS TriggerAutocallPerc, -- <<< verify - ISNULL(u.AutocallValue, 0) AS AutocallValue -- <<< verify - - FROM dbo.Underlyings u - JOIN [dbo].[Certificates] c -- <<< verify - ON c.IDCertificates = u.IDCertificates - -- Ultimo prezzo disponibile per ogni sottostante (per PriceWorst) - LEFT JOIN ( - SELECT - UnderlyingsID, - Px_close, - ROW_NUMBER() OVER ( - PARTITION BY UnderlyingsID - ORDER BY Px_date DESC - ) AS rn - FROM dbo.Prices - WHERE Px_close IS NOT NULL - ) lp ON lp.UnderlyingsID = u.IDUnderlyings AND lp.rn = 1 - - WHERE u.IDCertificates = @IDCertificates - ORDER BY u.IsWorstOf DESC; -- worst-of nella prima riga - -END -GO