Sei sulla pagina 1di 23

Università degli Studi di Salerno

Facoltà di Ingegneria Elettronica

Tecnica ed Economia dell’Energia Elettrica


Prof. Pierluigi Siano

Finalità del progetto: Implementazione di un decisore in grado di presentare


automaticamente offerte atte a massimizzare il profitto per un generatore all’interno
del mercato del giorno prima attraverso Matlab, Stateflow e “MATPOWER”.

A cura di:

Minneci Claudio, matr. 0622600905


Sommario
1. Introduzione .............................................................................................................................................. 1
2. Implementazione del decisore .................................................................................................................. 2
3. Decisore ..................................................................................................................................................... 3
2.1. Passo 1 ................................................................................................................................................... 4
2.2. Passo 2 ................................................................................................................................................... 5
2.3. Passo 3 e successivi ............................................................................................................................... 6
4. Rete utilizzata ............................................................................................................................................ 7
5. Codice di simulazione ................................................................................................................................ 9
6. Grafici ...................................................................................................................................................... 16
1. Introduzione
Il presente elaborato ha la finalità di implementare, utilizzando il software Matlab e l’ambiente di lavoro
Simulink, un decisore che sia in grado di elaborare automaticamente le offerte di vendita per un produttore
di energia elettrica che operi all’interno del mercato elettrico, e di massimizzare il profitto ottenuto dalla
vendita dell’energia.
Una peculiarità che rende complessa la programmazione dei sistemi elettrici rispetto agli altri sistemi
produttivi è l’impossibilità di accumulo diretto dell’energia elettrica. In generale, per poter effettuare tale
valutazione occorre considerare sia le leggi fisiche che quelle economiche. Nel caso particolare del settore
elettrico la gestione dei flussi di energia sulla rete si è detta dispacciamento ed in Italia è affidata a
Terna - Rete Elettrica Nazionale S.p.A. Il dispacciamento richiede il monitoraggio dei flussi elettrici e
l’applicazione delle regole essenziali per l’esercizio coordinato di tutti gli elementi coinvolti in tale
sistema, come impianti di produzione, reti di trasmissione e i servizi ausiliari.
Verrà realizzato un file testo (m-file), che conterrà il codice per lo svolgimento della simulazione di
mercato e verrà creato il decisore in ambiente Simulink, ponendo come finalità quella di massimizzare il
profitto ottenuto dalla vendita di energia elettrica.
Per fare ciò è chiaramente necessario conoscere i risultati delle sessioni orarie precedenti della giornata,
al fine di presentare le proprie offerte di vendita con un prezzo che ci permetta di vendere l’intera quantità
di energia elettrica prodotta. In base a tali risultati viene individuata un’offerta valida per la sessione oraria
successiva con la quale si cerca di collocarsi in prossimità del costo marginale del sistema, garantendosi
l’accettazione della propria offerta da parte del mercato, ed il conseguente massimo guadagno.

1
2. Implementazione del decisore
Obiettivo
L’obiettivo di questo lavoro è di realizzare, tramite il programma Matlab, un sistema intelligente in
grado di presentare automaticamente offerte a nome di un produttore. Con Simulink ed in particolare
Stateflow, è stato realizzato un modello in grado di simulare una sessione di mercato. Il produttore
propone una propria offerta, sia in termini di energia che di prezzo, suddivisa in due blocchi, dove il
primo presenta un prezzo minore rispetto all’altro blocco ed una quantità maggiore per avere la
certezza di vendita di una buona quota dell’energia.
La strategia adottata dal produttore è la seguente: inizialmente propone un’offerta (composta da due
coppie quantità-prezzo), in seguito coi risultati alla mano della prima sessione di mercato decide se e
di quanto modificare l’offerta a seconda che essa sia stata accettata totalmente, parzialmente o per
niente. Soltanto dopo la seconda sessione di mercato il produttore si potrà regolare, anche
considerando il guadagno che ha ottenuto e alla percentuale di vendita dei propri blocchi.
Strumenti del progetto
Verrà realizzato il progetto con ausilio del software Matlab®, un ambiente per il calcolo numerico e
l'analisi statistica scritto in C, che comprende anche l'omonimo linguaggio di programmazione creato
dalla MathWorks, tramite la programmazione di una serie di comandi, contenuti in un file testo (m-
file), con l’utilizzo dell’editor, finestra predisposta a tale funzione. L’m-file, costruito appositamente,
è di tipo script e si differenzia da un tipo function perché tutte le variabili contenute sono già definite
in Matlab (variabili globali) e non nascono e muoiono in esso. Questo file di testo, eseguendolo,
simulerà il mercato elettrico d’interesse e stamperà sullo schermo una serie di grafici che descrivono
le variabili d’interesse e il risultato finale.
Inoltre, oltre alla programmazione dell’m-file, è necessario avere come aiuto l’ambiente Simulink, in
particolar modo l’utilizzo di Stateflow.
Simulink è uno strumento integrato con Matlab per modellazione, simulazione ed analisi di sistemi
dinamici. Sarà possibile rappresentare con molta semplicità un sistema complesso tramite
interconnessioni di sottosistemi. Stateflow invece è uno strumento di progetto e sviluppo di sistemi
di supervisione all’interno di Simulink tramite creazione grafica di sistemi. Permette di rappresentare
in modo conciso il comportamento di sistemi complessi, usando un approccio State-Driven
(esecuzioni di determinate azioni sul processo in base allo stato di evoluzione del processo dipendente
dalla sequenza degli ingressi che si sono presentati).
Infine bisogna scaricare ed implementare in Matlab un pacchetto di m-file disponibile online
chiamato Matpower. Il pacchetto, sviluppato inizialmente come parte del progetto PowerWeb, è
inteso come uno strumento di simulazione per ricercatori e studenti facile da modificare ed usare per
risolvere problemi come il flusso di potenza ottimale o il mercato elettrico.

2
3. Decisore
Simulink
In ambiente Simulink, attraverso Stateflow, è stato realizzato uno strumento in grado di verificare se
l’offerta presentata nella precedente sessione di mercato è stata accettata completamente,
parzialmente oppure non è stata accettata. In base a ciò il decisore stabilisce i prezzi della sessione
successiva, basandosi sul ΔP, ovvero la differenza tra il market clearing price e il prezzo da noi
proposto.
Nel seguente schema sono illustrate le variabili di input e output del nostro decisore.

Figura 1 – Schema delle variabili del decisore in Simulink

Le variabili che sono state utilizzate sono:


INPUT
 t: passo dell’iterazione;
 Poff1: prezzo offerto per il primo blocco;
 Poff2: prezzo offerto per il secondo blocco;
 MCP (Market Clearing Price): prezzo di equilibrio del mercato;
 D: delta Prezzo medio;
 D1: differenza tra MCP e Poff1;
 D2: differenza tra MCP e Poff2;
 Rtot: ricavo dei due blocchi nella sessione appena svolta;
 RtotPrec: ricavo dei due blocchi nella sessione precedentemente svolta;
Tali variabili sono determinate in Matlab e memorizzate all’interno del Workspace, da cui verranno
richiamate. Si utilizza infatti il blocco “From Workspace” all’interno di Simulink.

3
OUTPUT
 Pout1: prezzo del primo blocco da offrire per la sessione successiva;
 Pout2: prezzo del secondo blocco da offrire per la sessione successiva;
Tali variabili vanno poi esportate in Matlab per cui si usa il blocco “To Workspace” in Simulink.
Stateflow
La logica su cui si basa il decisore è invece stata implementata attraverso Stateflow:

Figura 2 – Schema di funzionamento del decisore in Stateflow

Vediamo adesso cosa accade nei diversi passi di simulazione.

2.1. Passo 1

Figura 3 – Schema del primo passo di simulazione

Al passo 1, la variabile “t” vale 1, per cui è verificata la condizione 1. L’offerta iniziale sarà proprio
quella che noi abbiamo scelto prima di iniziare la simulazione.
4
2.2. Passo 2

Figura 4 – Schema del secondo passo di simulazione

Al passo 2 la variabile “t” è pari a 2, per cui si verifica la condizione 2. Si presentano adesso tre
possibili casi:
 Offerta parzialmente accettata: questo caso si verifica quando il Poff1 è minore o uguale del
MCP, per cui l’offerta relativa al primo blocco viene accettata, mentre Poff2 è maggiore del
MCP, quindi l’offerta relativa al secondo blocco viene rifiutata. In questo caso decido di
uguagliare Poff2 al MCP, per avere più possibilità che nella sessione successiva venga
accettata, mentre lascio invariato Poff1, poiché molto probabilmente quest’offerta sarà
accettata anche nella prossima sessione.
 Offerta totalmente accettata: questo caso si verifica quando sia Poff1 che Poff2 sono minori
del MCP. Decido quindi di porre Poff1 leggermente al di sotto del MCP, uguagliandolo a
MCP-D2/2 (scelgo D2 poiché in questo caso D2<D1, così facendo non mi allontano troppo
dal MCP); pongo poi Poff2 pari proprio al MCP.
 Offerta non accettata: l’ultimo caso si verifica se sia Poff1 che Poff2 sono maggiori del MCP,
in questo caso D2>D1. Devo fare in modo che nella prossima sessione almeno un’offerta
venga accettata, di conseguenza decido di porre Poff1 al di sotto del MCP (Poff1=MCP-D2)
e Poff2 leggermente al di sotto del MCP (Poff2=MCP-D1/3)

5
2.3. Passo 3 e successivi

Figura 5 – Schema dei successivi passi di simulazione

Al passo 3, così come nei successivi, la variabile t risulterà maggiore o uguale di 3, per cui si verifica
la condizione 3. Il decisore a questo punto esamina la differenza G tra i ricavi derivanti dalla sessione
appena conclusa e quelli derivanti dalla sessione precedente. Se tale differenza è positiva, vuol dire
che la strategia che si è perseguita è giusta e quindi i prezzi vengono calcolati nello stesso modo. Se
invece G dovesse essere negativa, allora si distinguono nuovamente tre possibilità.
 Offerta parzialmente accettata: riduco Poff1 e pongo Poff2 pari al MCP per cercare di vendere
tutto il quantitativo energetico disponibile ed aumentare i ricavi;
 Offerta totalmente accettata: in questo caso dobbiamo cercare di portare il MCP ad un valore
superiore perché, pur essendo l’offerta precedente totalmente accettata, i ricavi sono diminuiti.
Per questo motivo, poniamo Poff1 leggermente al di sotto del MCP, mentre poniamo Poff2 al
di sopra.
 Offerta non accettata: nessuna delle due offerte è stata accettata nella sessione precedente e
quindi i ricavi sono diminuiti. Dobbiamo fare in modo da far accettare le nuove offerte, che
per tale motivo verranno poste al di sotto del MCP.

6
4. Rete utilizzata
All’interno del package di casi è stata scelta la rete denominata “case 9” a cui sono state apportate le
necessarie modifiche per soddisfare le esigenze progettuali. Tale rete presenta le seguenti
caratteristiche:

Numero di nodi: 9

di cui: 4 nodi di acquisto, 5 nodi di vendita.

Valori di tensione per ciascun nodo: V=345 ± 34.5 kV

Power Factor: 1 (Solo potenza attiva)

Numero di generatori: 5

Numero di consumatori: 4

Nello specifico la rete è così strutturata:


%CASE9 Power flow data for 9 bus, 3 generator case.
% Please see CASEFORMAT for details on the case file format.
%
% Based on data from Joe H. Chow's book, p. 70.

% MATPOWER
% $Id: case9.m 1559 2010-03-10 18:08:32Z ray $

%% MATPOWER Case Format : Version 2


mpc.version = '2';

%%----- Power Flow Data -----%%


%% system MVA base
mpc.baseMVA = 100;

%% bus data
% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin
mpc.bus = [
1 3 0 0 0 0 1 1 0 345 1 1.1 0.9;
2 2 0 0 0 0 1 1 0 345 1 1.1 0.9;
3 2 0 0 0 0 1 1 0 345 1 1.1 0.9;
4 1 0 0 0 0 1 1 0 345 1 1.1 0.9;
5 1 0 0 0 0 1 1 0 345 1 1.1 0.9;
6 1 0 0 0 0 1 1 0 345 1 1.1 0.9;
7 2 0 0 0 0 1 1 0 345 1 1.1 0.9;
8 2 0 0 0 0 1 1 0 345 1 1.1 0.9;
9 2 0 0 0 0 1 1 0 345 1 1.1 0.9];

%% generator data
% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min
Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf
mpc.gen = [
1 160 0 60 -60 1 100 1 1000 0;
2 200 0 60 -60 1 100 1 1000 0;
3 150 0 60 -60 1 100 1 1000 0;
4 200 0 60 -60 1 100 1 1000 0;
5 250 0 60 -60 1 100 1 1000 0;
6 -1 0 0 0 1 100 1 0 -1000;

7
7 -1 0 0 0 1 100 1 0 -1000;
8 -1 0 0 0 1 100 1 0 -1000;
9 -1 0 0 0 1 100 1 0 -1000];

%% branch data
% fbus tbus r x b rateA rateB rateC ratio angle status
angmin angmax
mpc.branch = [
1 4 0 0.0576 0 250 250 250 0 0 1 -360 360;
4 5 0.017 0.092 0.158 250 250 250 0 0 1 -360 360;
5 6 0.039 0.17 0.358 150 150 150 0 0 1 -360 360;
3 6 0 0.0586 0 300 300 300 0 0 1 -360 360;
6 7 0.0119 0.1008 0.209 150 150 150 0 0 1 -360 360;
7 8 0.0085 0.072 0.149 250 250 250 0 0 1 -360 360;
8 2 0 0.0625 0 250 250 250 0 0 1 -360 360;
8 9 0.032 0.161 0.306 250 250 250 0 0 1 -360 360;
9 4 0.01 0.085 0.176 250 250 250 0 0 1 -360 360;
];

mpc.branch(: , 6)=mpc.branch(: , 6)*100;


mpc.branch(: , 3:5)=mpc.branch(: , 3:5)/1000000;

%%----- OPF Data -----%%


%% area data
% area refbus
mpc.areas = [
1 5;
];

%% generator cost data


% 1 startup shutdown n x1 y1 ... xn yn
% 2 startup shutdown n c(n-1) ... c0
mpc.gencost = [
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0;
2 0 0 3 0 0 0];

8
5. Codice di simulazione
Al fine di avere una simulazione quanto più realistica possibile è necessario basarsi su dati reali per
cui sono state prelevate delle informazioni dal gestore della rete relativamente a quantità e prezzi.

Figura 6 - Previsione del fabbisogno Nazionale del 15/01/2018 ricavato da TERNA

Partendo da queste informazioni sono stati creati due vettori di dati normalizzati rispetto al massimo
di ciascun vettore.
%Vettore delle quantità di corrente, definite come rapporto tra la quantità i-
esima e la quantità massima
Vett_qty=[0.58 0.55 0.53 0.54 0.57 0.61 0.76 0.89 0.95 0.98 0.98 0.97 0.89 0.90
0.93 0.92 0.94 1 0.98 0.95 0.87 0.78 0.70 0.64];

%Vettore dei prezzi


Vett_prc=[0.74 0.78 0.81 0.85 0.80 0.82 0.70 0.73 0.79 0.84 0.89 0.93 1 1.1 1.1
1.2 1.1 0.82 0.87 1 0.96 0.94 1 0.97];

Figura 7 – Andamento delle quantità richieste e dei prezzi nel corso della giornata

9
La rete è stata richiamata nel codice di simulazione attraverso la funzione “loadcase”:
mpc=loadcase('market_case9');

Sono poi stati definiti i parametri del mercato:


%Per la corrente alternata usiamo 'AC'
mkt.OPF='AC';
%Per operare in un mercato LAO, usiamo 1
mkt.aution_type=1;

%Dal momento che il mercato si svolge sulle 24 ore, creiamo un indice che
%va da 1 a 24
x=[1:1:24];

Possiamo adesso passare alla definizione delle offerte di vendita e di acquisto, dette rispettivamente
offers e bids.
% Matrici delle offerte di vendita e di acquisto:

%Matrice delle quantità offerte dai produttori


offers.P.qty=[
90 40;
40 40;
100 30;
120 0;
60 40];

%Matrice dei prezzi delle offerte di vendita dei produttori


offers.P.prc=[
Poff1_m Poff2_m;
60 85;
70 80;
65 0
75 90];

In realtà questa matrice non viene definita adesso, è riportata solo per completezza. La matrice delle
offerte di vendita viene definita di volta in volta nel ciclo for che costruiremo successivamente.
Notiamo che la matrice delle offerte di vendita è incompleta, mancano infatti i prezzi relativi al prima
produttore. Tali prezzi saranno infatti determinati dal decisore, e cambieranno in ogni sessione del
Mercato del Giorno Prima.
%Matrice delle quantità di acquisto dei compratori
b.P.qty=[
60 60;
100 0;
80 20;
50 30];
%Matrice dei prezzi delle offerte di acquisto dei compratori
b.P.prc=[
150 50;
100 0;
110 80;
120 60];

Scegliamo adesso il valore iniziale di Poff1 e Poff2:


Poff1_m=50;
Poff2_m=100;

10
Possiamo quindi riportare sui grafici le diverse offerte.

11
12
Una volta definite le offerte di vendita e di acquisto, i vettori delle quantità e dei prezzi, possiamo
passare alla scrittura del codice che definisce lo svolgimento della simulazione del mercato.
Innanzitutto è necessario definire le variabili globali che costituiranno le variabili di input per il
decisore implementato in Stateflow.
%Definisco le variabili globali che usa il decisore di Stateflow, che hanno
%26 componenti per permettere il calcolo al decisore nelle prime due
%iterazioni
global t Poff1 Poff2 mcp Rtot RtotPrec D1 D2 D

È necessario poi creare dei vettori di appoggio relativi alle quantità accettate, al MCP, ai prezzi
accettati delle offerte e ai ricavi totali. Questi vettori hanno 26 componenti in modo tale da permettere
al decisore di effettuare i primi due passi prima dell’inizio della simulazione vera e propria.
%vettori di appoggio
Qacc1_vett=zeros(1,26);
Qacc2_vett=zeros(1,26);
mcp_vett=zeros(1,26);
Poff1_vett=zeros(1,26);
Poff2_vett=zeros(1,26);
Rtot_vett=zeros(1,26);

%prima del ciclo for inizializzo i tempi


t_iniz=0;
t_fin=1;

Per effettuare una simulazione completa del Mercato del Giorno Prima, le operazioni vanno ripetute
per 24 volte, una volta per ogni ora del giorno, attraverso un ciclo for. Dopo aver inizializzato il ciclo
for vanno definiti i ricavi e i vettori che costituiranno gli input per il decisore precedentemente
implementato in Stateflow.
%il ciclo for deve reiterare le stesse operazioni 24 volte, una per ogni
%ora del giorno
for t_m=1:24
t=[1, t_m];

%definisco i ricavi relativamente ai singoli blocchi come quantità*prezzo e


%definisco il ricavo totale come somma
R1_vett=Qacc1_vett.*mcp_vett;
R2_vett=Qacc2_vett.*mcp_vett;
Rtot_vett=R1_vett+R2_vett;

%input per stateflow, sono vettori di due elementi, il primo indica la


%durata di ciascuna simulazione, ed è pari ad 1 dal momento che la
%simulazione è relativa ad una singola ora del giorno, il secondo elemento
%invece, indica il valore numerico della variabile corrispondente
Poff1=[1, Poff1_m];
Poff2=[1, Poff2_m];
mcp=[1, mcp_vett(t_m+1)];
Rtot=[1, Rtot_vett(t_m+1)];
RtotPrec=[1, Rtot_vett(t_m)];

%D è la variabile che il decisore utilizza per formulare le offerte per il


%successivo svolgimento del mercato, D1 è relativa al primo blocco, D2 al
%secondo, si calcola una media tra i due valori, e la si assegna alla
%variabile globale D, il cui primo elemento è 1 poichè rappresenta la
%durata temporale della singola simulazione.
%Nel calcolo della D, il valore viene aumentato di 1 per evitare valori
%nulli.

D1_m=(abs(mcp_vett(t_m+1)-Poff1_vett(t_m))+1)/2;
13
D2_m=(abs(mcp_vett(t_m+1)-Poff2_vett(t_m))+1)/2;
D_m=(D1_m+D2_m)/2;
D1=[1, D1_m];
D2=[1,D2_m];
D=[1, D_m];

Una volta definite tutti gli input possiamo richiamare il decisore attraverso la funzione “sim”; per
farlo funzionare correttamente vanno definiti gli estremi temporali della simulazione, che erano stati
definiti prima del ciclo for.
%Simulazione con stateflow
sim('decisoreCM.slx',[t_iniz t_fin]);

Possiamo quindi elaborare gli output di Stateflow, prima però è necessario effettuare una media tra i
diversi valori che il decisore ha restituito ed arrotondare la media, in modo tale da non portarci dietro
troppe cifre decimali. Il decisore effettua infatti più simulazioni e pertanto va fatta una media tra i
valori derivanti dalle diverse simulazioni. Gli output che elaboreremo sono, come detto
precedentemente, i prezzi delle offerte di vendita dei nostri due blocchi di energia.
%Effettuo una media tra i diversi valori e la arrotondo alla prima cifra decimale
%con "round"
[r1,c1]=size(Pout1.signals.values);
[r2,c2]=size(Pout2.signals.values);
Poff1_m=round(10*Pout1.signals.values(r1,1))/10;
Poff2_m=round(10*Pout2.signals.values(r2,1))/10;
Poff1_vett(t_m+1)=Poff1_m;
Poff2_vett(t_m+1)=Poff2_m;

%Faccio variare le matrici di quantità e prezzo dei consumatori


%moltiplicandole per i coefficienti dei vettori delle quantità di corrente
%e dei prezzi
bids.P.qty=b.P.qty*Vett_qty(t_m);
bids.P.prc=b.P.prc*Vett_prc(t_m);

%Riporto la matrice delle offerte dei produttori, in cui al primo


%produttore assegno proprio gli output ottenuti
offers.P.prc=[
Poff1_m Poff2_m;
60 85;
70 80;
65 0
75 90];

Inseriti i prezzi delle nostre offerte di vendita nella matrice “offers.P.prc”, ovvero la matrice dei
prezzi dei venditori, abbiamo a disposizione tutte le matrici complete. Pertanto è possibile svolgere il
Mercato del Giorno Prima attraverso la funzione “runmarket”. Tale funzione richiede in input: mpc,
ovvero la rete su cui basiamo la simulazione, nel nostro caso la rete era “market_case9”, offers e bids,
cioè le matrici di quantità e prezzi dei produttori e degli acquirenti, e mkt, in cui sono contenuti i
parametri del nostro mercato che erano stati assegnati precedentemente, corrente alternata e mercato
LAO (Last Accepted Offer). Tra gli output di questa funzione ci interessano: mpc_out, ovvero il
prezzo di equilibrio nelle 24 ore, dispatch, che indica la potenza dispacciata, f, che rappresenta il
social welfare, co e cb, cioè le offerte accettate per quanto riguarda rispettivamente produttori e
consumatori.
%Svolgimento sessione di mercato attraverso la funzione "runmarket"
[mpc_out, co,cb,f,dispatch,success,et]=runmarket(mpc,offers,bids,mkt);
Qacc1_vett(t_m+2)=co.P.qty(1,1);
Qacc2_vett(t_m+2)=co.P.qty(1,2);
mcp_vett(t_m+2)=round(10*co.P.prc(1,1))/10;
14
A questo punto possiamo raccogliere le informazioni che ci servono all’interno di appositi vettori,
che verranno riportati su dei grafici. In particolare ci interessano: gli andamenti di MCP, Prezzo
dell’offerta 1 e Prezzo dell’offerta 2, i ricavi derivanti dalla vendita di ciascuno dei due blocchi di
energia e il ricavo totale.
%vettori per i grafici
Poff1vett(t_m)=Poff1_m;
Poff2vett(t_m)=Poff2_m;
MCPvett(t_m)=mcp_vett(t_m+2);
Ricavo1(t_m)= mcp_vett(t_m+2)*Qacc1_vett(t_m+2);
Ricavo2(t_m)= mcp_vett(t_m+2)*Qacc2_vett(t_m+2);
RicavoTot(t_m)= Ricavo1(t_m)+Ricavo2(t_m);
RicavoCum(t_m)=sum(RicavoTot);
end

Si può quindi chiudere il ciclo for.

15
6. Grafici
L’ultima parte del codice è quella relativa ai comandi per la rappresentazione grafica.

Riportiamo innanzitutto il grafico relativo all’andamento del fabbisogno nel corso della giornata.

Vediamo quindi come il picco di richiesta sia alle ore 18, mentre valori comunque elevati si
riscontrano nelle ore mattutine. Tra le 13 e le 17 c’è una lieve flessione della domanda, che invece
cala drasticamente dalle 21 in poi, per raggiungere il minimo alle 3 di notte. Dalle 7 di mattina, con
la ripresa delle attività, cresce nuovamente il fabbisogno energetico.
Quest’andamento rispecchia chiaramente le abitudini della popolazione, ed era pertanto di facile
previsione.

16
Con un primo grafico vogliamo rappresentare contemporaneamente gli andamenti del MCP, del
prezzo relativo al primo blocco e al secondo nel corso delle diverse ore del giorno.
figure (1)
plot(x,MCPvett,'r')
hold on
plot(x,Poff1vett,'y')
plot(x,Poff2vett,'b')
grid on
xlabel('Tempo')
legend('MCP','Poff1','Poff2')
axis([1 24 35 75])
hold off

Da questo grafico vediamo come fossimo partiti con un prezzo del primo blocco basso, e un prezzo
del secondo blocco alto; tali prezzi si sono rapidamente allineati al MCP, già dalla quarta ora infatti i
prezzi si mostrano in linea con il mercato. Seguiranno poi l’andamento del MCP, trovandosi, come
desiderato, quasi sempre di poco al di sotto del MCP, in modo tale da garantire l’accettazione delle
offerte.

17
Col successivo grafico verifichiamo proprio l’andamento delle quantità accettate del primo e del
secondo blocco di energia elettrica.
figure (2)
plot(Qacc1_vett,'r')
hold on
plot(Qacc2_vett,'y')
grid on
xlabel('Tempo')
legend('Quantità 1','Quantità 2')
hold off

Come giustamente dedotto dall’andamento dei prezzi rispetto al MCP, il primo blocco viene venduto
sempre interamente, ad eccezione di un’ora, le 22, che come abbiamo visto corrisponde all’orario in
cui diminuisce fortemente il fabbisogno di energia elettrica. Il secondo blocco viene anch’esso
venduto interamente nella maggior parte delle sessioni, ad eccezione di qualche ora pomeridiana in
cui c’è una lieve flessione di richiesta di energia elettrica. Alle 22 la seconda offerta viene
completamente rifiutata, e questo deriva dalla forte diminuzione di richiesta. Il decisore è però molto
reattivo nell’adattare i prezzi al MCP, e infatti, nonostante l’esigua domanda nelle ore notturne,
riusciamo comunque a vendere per intero sia il primo che il secondo blocco di energia.

18
Il terzo grafico è costruito al fine di visualizzare la variazione del ricavo rispetto a quelle dell’MCP e
del fabbisogno.

figure (3)
plot (x,Vett_qty*100,'r')
hold on
plot(x,MCPvett,'y--')
plot(x,RicavoTot/100,'b')
legend('Fabbisogno','MCP','Ricavo')
ylabel('Variazioni')
xlabel('Tempo')
grid on
hold off

Dal grafico vediamo come ovviamente il nostro ricavo dipenda fortemente dal fabbisogno del mercato
di energia elettrica. L’efficienza del decisore costruito si evince dalle ultime due ore in cui, nonostante
una forte diminuzione della richiesta, riusciamo a conseguire un ricavo in linea con quello ottenuto
nelle ore di picco di domanda di energia.

19
Nel quarto grafico possiamo vedere quanto vale il ricavo totale dopo ogni sessione del mercato del
giorno prima.
figure(4)
plot(x,RicavoCum,'r')
xlabel('Tempo')
grid on
ylabel('Ricavo cumulato')
axis([1 24 0 250000])

A fine giornata il ricavo totale risulta essere pari a 198 670 €. Questo è un dato molto buono ed è
dovuto al fatto che nella maggior parte delle sessioni di mercato siamo riusciti a vendere tutta
l’energia prodotta.

20
Infine con l’ultimo grafico si vuole dare una visione d’insieme, mostrando contemporaneamente le
variazioni di fabbisogno, MCP, ricavo e prezzi delle singole offerte.
figure (5)
plot (x,Vett_qty*100,'r')
hold on
plot(x,MCPvett,'y--')
plot(x,RicavoTot/100,'b:')
plot(x,Poff1vett,'g')
plot(x,Poff2vett,'c')
legend('Fabbisogno','MCP','Ricavo','Poff1','Poff2')
ylabel('Variazioni')
xlabel('Tempo')
grid on
hold off

21