Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4

    [MYSQL] Query on stock split

    Ho una domanda relativa ad una query per creare un portafoglio a partire da una collezione di record di ordini (tradelog).

    Cerco di spiegare meglio ciò di cui ho bisogno

    Supponiamo di avere un tradelog di azioni


    #TRADELOG TABLE#



    |symbol | date | type | quantity | split_ratio |
    | --------- | ---------- | ---- | -------- | ----------- |
    |AMZN | 12-11-2020 | BUY | 200 | - |
    |GOOGL | 14-11-2020 | BUY | 200 | - |
    |GOOGL | 18-11-2020 | BUY | 400 | - |
    |AMZN | 02-01-2021 | BUY | 600 | - |
    |GOOGL | 04-01-2021 | SPLIT| - | 10 |
    |GOOGL | 22-11-2021 | BUY | 80 | - |
    |AMZN | 24-11-2021 | SPLIT| - | 10 |
    |GOOGL | 31-11-2021 | BUY | 100 | - |
    |GOOGL | 12-12-2021 | SPLIT| - | 2 |
    |GOOGL | 22-12-2021 | BUY | 10 | - |
    |AMZN | 12-07-2022 | BUY | 80 | - |
    |AMZN | 14-08-2022 | BUY | 40 | - |
    |AMZN | 12-09-2022 | SPLIT| - | 2 |
    |AMZN | 15-11-2022 | BUY | 8 | - |




    Per chi non è pratico di operazioni su azioni in borsa, quando c'è uno split significa che il numero di azioni possedute si riduce dello split_ratio

    Secondo quanto riportato nel tradelog superiore il mio portafoglio risultante dovrebbe essere il seguente:

    AMZN: (((200+600)/10) +80 +40)/2 +8 = 108
    GOOGL: (((200+400)/10) +80 +100)/2 +10 = 130


    #PORTFOLIO TABLE#


    | symbol | quantity |
    | ------ | -------- |
    |AMZN|108|
    |GOOGL|130|








    Non ho trovato un modo per creare questo database del portafoglio utilizzando una query. La cosa piàu complicata è gestire lo split che obliga a dividere le quantità di tutti i record precedenti dello stesso simbolo

    Avete qualche idea per aiutarmi?
    Ultima modifica di makksi; 20-11-2022 a 23:51

  2. #2
    se procedi riga per riga, quando trovi BUY sommi, quando trovi SPLIT dividi. La cosa ti viene semplice se ogni volta che inserisci una riga in TRADELOG aggiorni PORTFOLIO
    ARTRIPE

  3. #3
    Utente di HTML.it L'avatar di Joe Taras
    Registrato dal
    Nov 2003
    residenza
    Taranto
    Messaggi
    936
    Quote Originariamente inviata da makksi Visualizza il messaggio
    Ho una domanda relativa ad una query per creare un portafoglio a partire da una collezione di record di ordini (tradelog).

    Cerco di spiegare meglio ciò di cui ho bisogno

    Supponiamo di avere un tradelog di azioni


    #TRADELOG TABLE#



    |symbol | date | type | quantity | split_ratio |
    | --------- | ---------- | ---- | -------- | ----------- |
    |AMZN | 12-11-2020 | BUY | 200 | - |
    |GOOGL | 14-11-2020 | BUY | 200 | - |
    |GOOGL | 18-11-2020 | BUY | 400 | - |
    |AMZN | 02-01-2021 | BUY | 600 | - |
    |GOOGL | 04-01-2021 | SPLIT| - | 10 |
    |GOOGL | 22-11-2021 | BUY | 80 | - |
    |AMZN | 24-11-2021 | SPLIT| - | 10 |
    |GOOGL | 31-11-2021 | BUY | 100 | - |
    |GOOGL | 12-12-2021 | SPLIT| - | 2 |
    |GOOGL | 22-12-2021 | BUY | 10 | - |
    |AMZN | 12-07-2022 | BUY | 80 | - |
    |AMZN | 14-08-2022 | BUY | 40 | - |
    |AMZN | 12-09-2022 | SPLIT| - | 2 |
    |AMZN | 15-11-2022 | BUY | 8 | - |




    Per chi non è pratico di operazioni su azioni in borsa, quando c'è uno split significa che il numero di azioni possedute si riduce dello split_ratio

    Secondo quanto riportato nel tradelog superiore il mio portafoglio risultante dovrebbe essere il seguente:

    AMZN: (((200+600)/10) +80 +40)/2 +8 = 108
    GOOGL: (((200+400)/10) +80 +100)/2 +10 = 130


    #PORTFOLIO TABLE#


    | symbol | quantity |
    | ------ | -------- |
    |AMZN|108|
    |GOOGL|130|








    Non ho trovato un modo per creare questo database del portafoglio utilizzando una query. La cosa piàu complicata è gestire lo split che obliga a dividere le quantità di tutti i record precedenti dello stesso simbolo

    Avete qualche idea per aiutarmi?
    Ciao,
    a mio avviso dovresti provare a scrivere una procedura che fa questa operazione.

    Al massimo puoi cercare di creare una tabella temporanea con step intermedio, dove sommi le azioni prima di ogni split, e poi associ lo split alla somma.

    Una tabella tipo
    NOME_AZIONE - SOMMA_PRE_SPLIT SPLIT DATA_RIF_ULTIMO_ACQUISTO DATA_SPLIT

    dopo di che applichi il tuo split sia alla riga in corso che alla precedente.

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4
    Quote Originariamente inviata da optime Visualizza il messaggio
    se procedi riga per riga, quando trovi BUY sommi, quando trovi SPLIT dividi. La cosa ti viene semplice se ogni volta che inserisci una riga in TRADELOG aggiorni PORTFOLIO
    grazie per il consiglio ma vorrei evitare di fare questo in quanto è previsto anche di poter modificare le righe di tutto il tradelog in qualunque momento. Preferirei per questo motivo che una singola query generasse il PORTFOLIO

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4
    Intendi comunque sempre tramite quesry sql? Io vorrei gestire tutto con una query sql. Anche una tabella intermedia andrebbe bene (alla fine potrei gestirla credo anche come subquery) ma non ho capito bene cosa intendevi. La complicazione è che ci possono essere anche più split e quindi ad esempio nel caso di 3 split devi dividere le azioni prima del primo split per 3 split_ratio quelle tra il primo e il secondo per 2 split_ratio quelle tra il secondo e il terzo per uno split ratio e quelle dopo l'ultimo split_ratio non vanno per nulla divise

  6. #6
    puoi usare un cursore di mysql per creare la tua procedura, sempre in mysql
    ARTRIPE

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4
    gr<zie mille! non conoscevo i cursori. Ho studiato un p'o e alla fine sono arrivato ad una soluzione funzionante che riporto di seguito:

    BEGIN
    # DROP stock_tradelog_after_split and recreate from stock_tradelog before
    DECLARE done INT DEFAULT 0;
    DECLARE split decimal(11,3) DEFAULT 1;
    DECLARE stock_name varchar(20) DEFAULT "";
    DECLARE idx int(5) DEFAULT 1;
    DECLARE cur CURSOR FOR
    SELECT
    name,
    split_ratio,
    id
    FROM stock_tradelog
    WHERE type='SPLIT';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    label: LOOP
    FETCH cur INTO stock_name,split,idx;
    UPDATE stock_tradelog_after_split
    SET quantity = CAST((quantity/split) AS decimal(11,3))
    WHERE name = stock_name AND id < idx AND (type='BUY' OR type='SELL');
    IF done = 1 THEN LEAVE label;
    END IF;
    END LOOP;
    CLOSE cur;
    END


    Mi manca solo una cosa che ancora non sono riuscito a risolvere.
    Il codice precedente è memorizzato in una " stored procedure".

    All' interno della stessa procedura avrei voluto cancellare preliminarmente la tabella stock_tradelog_after_split e ricrearla con i seguenti comandi sql:

    DROP TABLE IF EXISTS stock_tradelog_after_split;
    CREATE TABLE stock_tradelog_after_split AS SELECT * FROM stock_tradelog;

    ma quando provo in phpmyadmin a salvare la procedura mi da errore.

    Consigli su questo problema e in generale sulla procedura?

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4
    gr<zie mille! non conoscevo i cursori. Ho studiato un p'o e alla fine sono arrivato ad una soluzione funzionante che riporto di seguito:

    BEGIN
    # DROP stock_tradelog_after_split and recreate from stock_tradelog before
    DECLARE done INT DEFAULT 0;
    DECLARE split decimal(11,3) DEFAULT 1;
    DECLARE stock_name varchar(20) DEFAULT "";
    DECLARE idx int(5) DEFAULT 1;
    DECLARE cur CURSOR FOR
    SELECT
    name,
    split_ratio,
    id
    FROM stock_tradelog
    WHERE type='SPLIT';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    label: LOOP
    FETCH cur INTO stock_name,split,idx;
    UPDATE stock_tradelog_after_split
    SET quantity = CAST((quantity/split) AS decimal(11,3))
    WHERE name = stock_name AND id < idx AND (type='BUY' OR type='SELL');
    IF done = 1 THEN LEAVE label;
    END IF;
    END LOOP;
    CLOSE cur;
    END


    Mi manca solo una cosa che ancora non sono riuscito a risolvere.
    Il codice precedente è memorizzato in una " stored procedure".

    All' interno della stessa procedura avrei voluto cancellare preliminarmente la tabella stock_tradelog_after_split e ricrearla con i seguenti comandi sql:

    DROP TABLE IF EXISTS stock_tradelog_after_split;
    CREATE TABLE stock_tradelog_after_split AS SELECT * FROM stock_tradelog;

    ma quando provo in phpmyadmin a salvare la procedura mi da errore.

    Consigli su questo problema e in generale sulla procedura?

  9. #9
    2 cose:
    1. converrai con me che scrivere "mi da errore" senza specificare l'errore non è utile
    2. indenta bene il codice (tramite uno dei tanti sql beautifiers che trovi in giro) e quendo lo posti mettilo tra i tag "code"

    ARTRIPE

  10. #10
    Utente di HTML.it
    Registrato dal
    Nov 2022
    Messaggi
    4
    Quote Originariamente inviata da optime Visualizza il messaggio
    2 cose:
    1. converrai con me che scrivere "mi da errore" senza specificare l'errore non è utile
    2. indenta bene il codice (tramite uno dei tanti sql beautifiers che trovi in giro) e quendo lo posti mettilo tra i tag "code"

    Si, hai perfettamente ragione. Non avevo messo l'errore perchè è una stringa lunghissima, comunque la riporto:

    Si sono verificati uno o più errori durante l'esecuzione della tua richiesta:


    • La seguente query è fallita: "CREATE DEFINER=`zoozleit10872`@`%` PROCEDURE `create_tradelog_after_split`() NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER BEGIN DROP TABLE IF EXISTS stock_tradelog_after_split CREATE TABLE stock_tradelog_after_split AS SELECT * from stock_tradelog DECLARE done INT DEFAULT 0; DECLARE split decimal(11,3) DEFAULT 1; DECLARE stock_name varchar(20) DEFAULT ""; DECLARE idx int(5) DEFAULT 1; DECLARE cur CURSOR FOR SELECT name, split_ratio, id FROM stock_tradelog WHERE type='SPLIT'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur; label: LOOP FETCH cur INTO stock_name,split,idx; UPDATE stock_tradelog_after_split SET quantity = CAST((quantity/split) AS decimal(11,3)) WHERE name = stock_name AND id < idx AND (type='BUY' OR type='SELL'); IF done = 1 THEN LEAVE label; END IF; END LOOP; CLOSE cur; END"
      Messaggio di MySQL: #1064 - Errore di sintassi nella query SQL vicino a 'CREATE TABLE stock_tradelog_after_split AS SELECT * from stock_tradelog DECLARE' linea 3




    Questo accade quando aggiungo le seguenti righe di codice alla procedura:
    codice:
    BEGIN
    DROP TABLE IF EXISTS stock_tradelog_after_split 
    CREATE TABLE stock_tradelog_after_split AS SELECT * from stock_tradelog
    ....
    mentre il codice seguente senza quelle due righr funziona perfettamente:
    codice:
    BEGIN DECLARE done INT DEFAULT 0;
    DECLARE split decimal(11, 3) DEFAULT 1;
    DECLARE stock_name varchar(20) DEFAULT "";
    DECLARE idx int(5) DEFAULT 1;
    DECLARE cur CURSOR FOR 
    SELECT 
      name, 
      split_ratio, 
      id 
    FROM 
      stock_tradelog 
    WHERE 
      type = 'SPLIT';
    DECLARE CONTINUE HANDLER FOR NOT FOUND 
    SET 
      done = 1;
    OPEN cur;
    label : LOOP 
    FETCH cur INTO stock_name, 
    split, 
    idx;
    UPDATE 
      stock_tradelog_after_split 
    SET 
      quantity = CAST(
        (quantity / split) AS decimal(11, 3)
      ) 
    WHERE 
      name = stock_name 
      AND id < idx 
      AND (
        type = 'BUY' 
        OR type = 'SELL'
      );
    IF done = 1 THEN LEAVE label;
    END IF;
    END LOOP;
    CLOSE cur;
    END

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2022 vBulletin Solutions, Inc. All rights reserved.