Esercizio 6

HMW applicativo:

Utilizzare un Processo Stocastico dagli HMWK precedenti (es. GBM) e aggiungere una strategia (buy/sell secondo regole stabilite). Calcolare PnL e DD (ovvero profitto o perdita totale e massimo declino del PnL).

Ho preso il codice del GBM che avevo già fatto e ci ho aggiunto una semplice strategia di trading basata sulla media mobile. In pratica, dopo aver simulato il prezzo, calcolo la media e decido se entrare o no confrontandola con il valore corrente.

Poi ho aggiunto il calcolo dei rendimenti e del PnL cumulato, così posso vedere quanto la strategia guadagna o perde nel tempo.

In più ho inserito il drawdown, cioè la perdita rispetto al massimo raggiunto, e il massimo drawdown per avere un’idea del rischio.

A livello grafico, oltre al prezzo, ho aggiunto anche i grafici del PnL e del drawdown su canvas separati, così si vede subito sia la performance che il rischio.

HTML:

<!DOCTYPE html>
<html lang=”it”>
<head>
<meta charset=”UTF-8″>
<title>Simulatore GBM + Strategia</title>

<style>
body {
  font-family: ‘Segoe UI’, Arial;
  max-width: 1000px;
  margin: 30px auto;
  padding: 20px;
  background: linear-gradient(135deg, #d9e8ff, #f0f6ff);
  color: #0a2a43;
}

h1 {
  text-align: center;
}

button {
  display: block;
  margin: 20px auto;
  padding: 12px 20px;
  background: #6c5ce7;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: bold;
}

button:hover {
  opacity: 0.85;
}

.box {
  margin-top: 20px;
  padding: 15px;
  background: white;
  border-radius: 8px;
}

canvas {
  border: 2px solid #a8c4e6;
  margin-top: 10px;
  border-radius: 6px;
  background: white;
}

#output {
  margin-top: 15px;
  padding: 10px;
  background: #e6f4ea;
  border-radius: 6px;
  font-family: monospace;
}
</style>
</head>

<body>

<h1>Simulazione GBM + Strategia Trading</h1>

<button onclick=”generaSimulazione()”>Simula Strategia</button>

<div class=”box”>
  <h3>Prezzo (GBM) + Media Mobile</h3>
  <canvas id=”canvasPrice” width=”900″ height=”200″></canvas>
</div>

<div class=”box”>
  <h3>PnL Strategia</h3>
  <canvas id=”canvasPnL” width=”900″ height=”200″></canvas>
</div>

<div class=”box”>
  <h3>Drawdown</h3>
  <canvas id=”canvasDD” width=”900″ height=”200″></canvas>
</div>

<div id=”output”></div>

<script src=”main.js”></script>

</body>
</html>

JS:

function generaSimulazione() {
  let n = 1000;
  let T = 1;
  let dt = T / n;
  let mu = 0.1;
  let sigma = 0.25;
  let S0 = 100;
  
  let S = [S0];
  for (let k = 1; k <= n; k++) {
    let U1 = Math.random();
    let U2 = Math.random();
    let Z = Math.sqrt(-2 * Math.log(U1)) * Math.cos(2 * Math.PI * U2);
    let prev = S[S.length – 1];
    let next = prev * Math.exp(
      (mu – 0.5 * sigma * sigma) * dt +
      sigma * Math.sqrt(dt) * Z
    );
    S.push(next);
  }
 
  let window = 20;
  let MA = [];
  for (let i = 0; i < S.length; i++) {
    if (i < window) {
      MA.push(null);
    } else {
      let sum = 0;
      for (let j = i – window; j < i; j++) {
        sum += S[j];
      }
      MA.push(sum / window);
    }
  }
 
  let position = [];
  for (let i = 0; i < S.length; i++) {
    if (MA[i] === null) {
      position.push(0);
    } else if (S[i] > MA[i]) {
      position.push(1);
    } else {
      position.push(0);
    }
  }
 
  let returns = [0];
  for (let i = 1; i < S.length; i++) {
    returns.push((S[i] – S[i – 1]) / S[i – 1]);
  }
  let strategyReturns = [];
  for (let i = 0; i < returns.length; i++) {
    strategyReturns.push(returns[i] * position[i]);
  }

 

  let PnL = [];
  let cum = 0;

 

  for (let i = 0; i < strategyReturns.length; i++) {
    cum += strategyReturns[i];
    PnL.push(cum);
  }
 
  let DD = [];
  let maxVal = -Infinity;

 

  for (let i = 0; i < PnL.length; i++) {
    if (PnL[i] > maxVal) maxVal = PnL[i];
    DD.push(PnL[i] – maxVal);
  }
  let MDD = Math.min(…DD);
 
disegnaLinea(“canvasPrice”, S, “#6c5ce7”, MA);
  disegnaLinea(“canvasPnL”, PnL, “#00b894”);
  disegnaLinea(“canvasDD”, DD, “#d63031”);
 
  document.getElementById(“output”).textContent =
    “Parametri:\n” +
    “S0 = ” + S0 +
    “, μ = ” + mu +
    “, σ = ” + sigma +
    “\n\nPnL finale: ” + PnL[PnL.length – 1].toFixed(4) +
    “\nMax Drawdown: ” + MDD.toFixed(4);
}
 
function disegnaLinea(canvasId, dati, colore, secondaLinea = null) {

 

  let canvas = document.getElementById(canvasId);
  let ctx = canvas.getContext(“2d”);

 

  ctx.clearRect(0, 0, canvas.width, canvas.height);

 

  let min = Math.min(…dati);
  let max = Math.max(…dati);

 

  let range = max – min;
  if (range === 0) range = 1;

 

  let scaleX = canvas.width / (dati.length – 1);
  let scaleY = canvas.height / range;
 
  ctx.beginPath();
  ctx.moveTo(0, canvas.height – (dati[0] – min) * scaleY);

 

  for (let i = 1; i < dati.length; i++) {
    let x = i * scaleX;
    let y = canvas.height – (dati[i] – min) * scaleY;
    ctx.lineTo(x, y);
  }

 

  ctx.strokeStyle = colore;
  ctx.lineWidth = 2;
  ctx.stroke();
 
  if (secondaLinea) {
    ctx.beginPath();

 

    let firstIndex = secondaLinea.findIndex(x => x !== null);

 

    if (firstIndex !== -1) {
      ctx.moveTo(
        firstIndex * scaleX,
        canvas.height – (secondaLinea[firstIndex] – min) * scaleY
      );
      for (let i = firstIndex + 1; i < secondaLinea.length; i++) {
        if (secondaLinea[i] !== null) {
          let x = i * scaleX;
          let y = canvas.height – (secondaLinea[i] – min) * scaleY;
          ctx.lineTo(x, y);
        }
      }
      ctx.strokeStyle = “#0984e3”;
      ctx.lineWidth = 1.5;
      ctx.stroke();
    }
  }
}

HMW teorico:

In questo homework utilizzo il Geometric Brownian Motion (GBM), già introdotto nei lavori precedenti, per simulare l’andamento di un prezzo nel tempo. L’obiettivo è aggiungere una semplice strategia di trading (buy/sell) e valutarne la performance attraverso il Profit and Loss (PnL) e il drawdown.

Il prezzo segue un GBM descritto dalla relazione:S(t) = S_0 \cdot \exp\left[(\mu – \tfrac{\sigma^2}{2})t + \sigma B(t)\right]

dove  è il prezzo iniziale, rappresenta il drift, la volatilità e un moto browniano. Questo modello è utile perché mantiene il prezzo sempre positivo e introduce una dinamica casuale realistica.

La strategia di trading è basata su una media mobile: si assume una posizione long quando

S(t)>MA(t)S(t) > MA(t)

e si esce dal mercato quando

S(t)<MA(t)S(t) < MA(t)

.

L’idea è seguire il trend del prezzo senza considerare posizioni short o costi di transazione.

Il Profit and Loss misura il guadagno cumulato della strategia ed è definito come:

ΔPnL(t)=position(t−1) [S(t)−S(t−1)]\Delta PnL(t) = position(t-1)\,[S(t) – S(t-1)]

PnL(t)=∑i=1tΔPnL(i)PnL(t) = \sum_{i=1}^{t} \Delta PnL(i)

Il drawdown misura invece la perdita rispetto al massimo valore raggiunto dal PnL:

DD(t)=max⁡s≤tPnL(s)−PnL(t)DD(t) = \max_{s \le t} PnL(s) – PnL(t)

mentre il massimo drawdown è:

MDD=max⁡tDD(t)MDD = \max_t DD(t)

In generale, la performance della strategia dipende sia dal processo stocastico che dai parametri scelti. Il PnL da solo non è sufficiente a valutare la bontà della strategia, poiché non considera il rischio: per questo il drawdown è fondamentale per analizzare la stabilità dei risultati nel tempo.