lunedì 17 dicembre 2012

PRESENTAZIONE BLOG


ESONERO

 

Esonero 27 novembre 2012

Generare una serie storica casuale dei prezzi per uno strumento finanziario. Rappresentare la serie storica con:

       I.            Linee delle medie mobili e running;
    II.            Bande di bollinger
 



1°STEP

·         Inizializzate una serie di variabili:

Public Class Form1
    Dim random As New Random
    Dim SS As New List(Of Osservazione)
    Dim SSRunning As New List(Of Osservazione)
    Dim SSMoving As New List(Of Osservazione)
    Dim SSBandaBollingerSup As New List(Of Osservazione)
    Dim SSBandaBollingerInf As New List(Of Osservazione)
    Dim PuntiComuni As New List(Of Osservazione)
    Dim MouseTastoPremuto As Boolean
    Dim PuntiSS As List(Of Point)
    Dim PuntiSSMoving As List(Of Point)
    Dim PuntiSSRunning As List(Of Point)
    Dim PuntiSSBBSUP As List(Of Point)
    Dim PuntiSSBBINF As List(Of Point)
    Dim PuntiPuntiComuni As List(Of Point)
  
    Public bitmap As Bitmap
    Public grafico As Graphics

    Public MinX As Double
    Public MaxX As Double
    Public MinY As Double
    Public MaxY As Double
    Public istanteIniziale As Date = Now
    Public Rettangolo As New Rectangle(10, 10, 400, 300)
    Public XinizialeMOUSE As Integer
    Public YinizialeMOUSE As Integer
    Public XinizialeRETT As Integer
    Public YinizialeRETT As Integer
    Public WInizialeRETT As Integer
    Public HInizialeRETT As Integer
    Public DistanzaDallaMedia As Integer

·         Inserisco una serie di comandi che mi consentono di resettare gli oggetti ogni volta che clicco sul bottone Serie Storica:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Me.SS.Clear()
        Me.SSMoving.Clear()
        Me.SSRunning.Clear()
        Me.SSBandaBollingerInf.Clear()
        Me.SSBandaBollingerSup.Clear()

        Dim random As New Random
        Dim SS As New List(Of Osservazione)

·         Creo la serie storica casuale (random) dei prezzi tramite un loop:
     ·         vado a impostare l’arco temporale alla giornata odierna, definendo un ciclo che termina    quando finisce la giornata:

        Dim prezzoIniziale As Decimal = 500
        Dim tick As Decimal = 1
        Dim passoTempominuti As Integer = 5
        Dim istanteCorrente = istanteIniziale
        Dim prezzoCorrente = prezzoIniziale
        Dim MediaRunning As Double

·         A seconda del valore casuale si sottrae o si aggiunge il tick:

        Do
            If random.NextDouble < 0.5 Then

                prezzoCorrente = prezzoCorrente - tick

            Else

                prezzoCorrente = prezzoCorrente + tick

            End If

·         avanziamo il tempo

            istanteCorrente = istanteCorrente.AddMinutes(passoTempominuti)


            If istanteCorrente.Subtract(istanteIniziale).TotalDays > 1 Then Exit Do
            Dim osservazione As New osservazione
            osservazione.istante = istanteCorrente
            osservazione.Prezzo = prezzoCorrente
            osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds
            osservazione.Y = osservazione.Prezzo

2°STEP

·         Vado a calcolare la media running:

            MediaRunning = (MediaRunning * SS.Count + prezzoCorrente) / (SS.Count + 1)
            Dim O_R As New Osservazione()
            O_R.Prezzo = MediaRunning
            O_R.Istante = osservazione.Istante
            O_R.X = osservazione.X
            O_R.Y = O_R.Prezzo
            SSRunning.Add(O_R)
            SS.Add(osservazione)

     ·         calcolo la media moving, utilizzando la condizione if  che mi gestisce la possibile eccezione nel caso di NumericUpDown1=0, per il quale la media mobile non si potrebbe calcolare, imponendo, in tal caso, un NumericUpDown1=1 si va ad ovviare al problema.

        Dim NUP As Integer = NumericUpDown1.Value
        If (NumericUpDown1.Value = 0) Then
            NUP = 1
        Else
            NUP = NumericUpDown1.Value
        End If
        Dim O_M As New Osservazione()

        If SS.Count > NUP Then
        MediaMoving = MediaMoving + (SS(SS.Count - 1).Prezzo / NUP) - (SS(SS.Count - NUP - 1).Prezzo / NUP)
            O_M.Prezzo = MediaMoving
            O_M.Istante = osservazione.Istante
            O_M.X = osservazione.X
            O_M.Y = O_M.Prezzo
            SSMoving.Add(O_M)
            SS.Add(osservazione)
        Else
            O_M.Prezzo = MediaMoving
            O_M.Istante = osservazione.Istante
            O_M.X = osservazione.X
            O_M.Y = O_M.Prezzo
            SSMoving.Add(O_M)

        End If
            SS.Add(osservazione)
      Loop

·         Calcoliamo le bande di bollinger (NUMERICUPDOWN2 * DEVSTD):

        Dim NUP2 As Integer = NumericUpDown2.Value
       If (NumericUpDown2.Value = 0) Then
            NUP = 1
        Else
            NUP = NumericUpDown2.Value
        End If
        Dim i As Integer = 0
        For i = i To SSMoving.Count - 1

·         Si calcola la deviazione standard della serie moving:

            Dim devstd As Double = Me.CalcoloDevStd(SSMoving, i)
            Dim b1 As New Osservazione
            Dim b2 As New Osservazione
            With b1
                .Prezzo = SSMoving(i).Prezzo + NUP2 * devstd
                .Istante = SSMoving(i).Istante
            End With
            Me.SSBandaBollingerSup.Add(b1)
            With b2
               .Prezzo = SSMoving(i).Prezzo - NUP2 * devstd
                .Istante = SSMoving(i).Istante
            End With

            Me.SSBandaBollingerInf.Add(b2)

        Next

        Me.MinX = Double.MaxValue
        Me.MaxX = Double.MinValue
        Me.MinY = Double.MaxValue
        Me.MaxY = Double.MinValue

 'calcolo coordinate reali della serie storica dei prezzi

       For Each osservazione As Osservazione In SS
           osservazione.Y = osservazione.Prezzo
            osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds

            If MinX > osservazione.X Then MinX = osservazione.X
            If MaxX < osservazione.X Then MaxX = osservazione.X
            If MinY > osservazione.Prezzo Then MinY = osservazione.Prezzo
            If MaxY < osservazione.Prezzo Then MaxY = osservazione.Prezzo

            Application.DoEvents()
            Me.SS.Add(osservazione)
        Next
        ' si richiamano le su definite per la trasformsazione della serie e per il disegno

        Me.TrasfomaCoordInPnt()
        Me.DisegnaLeSerie()

    End Sub
 

3°STEP

Non resta che andare  disegnare la nostra serie storica, le bande di bollinger e le medie.

·         Per prima cosa abbiamo voluto riportare tutto in un rettangolo all’interno della pictureBox;

abbiamo quindi calcolato le coordinate virtuali, trasferendo quelle originali in un rettangolo.

Sub TrasfomaCoordInPnt()

         PuntiSS = New List(Of Point)
       For Each osservazione As Osservazione In SS
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiSS.Add(Punto)
        Next

 
        PuntiSSRunning = New List(Of Point)
        For Each osservazione As Osservazione In SSRunning
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiSSRunning.Add(Punto)
        Next

         For Each osservazione As Osservazione In SSMoving
          osservazione.Y = osservazione.Prezzo
          osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds()
          Application.DoEvents()
       Next

        PuntiSSMoving = New List(Of Point)
        For Each osservazione As Osservazione In SSMoving
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiSSMoving.Add(Punto)
        Next
       For Each osservazione As Osservazione In SSBandaBollingerSup
            osservazione.Y = osservazione.Prezzo
          osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds()
            Application.DoEvents()
        Next

        PuntiSSBBSUP = New List(Of Point)
        For Each osservazione As Osservazione In SSBandaBollingerSup
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiSSBBSUP.Add(Punto)

        Next

        For Each osservazione As Osservazione In SSBandaBollingerInf
            osservazione.Y = osservazione.Prezzo
          osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds()
            Application.DoEvents()

         Next

        PuntiSSBBINF = New List(Of Point)
       For Each osservazione As Osservazione In SSBandaBollingerInf
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiSSBBINF.Add(Punto)

        Next

        For Each osservazione As Osservazione In PuntiComuni
            osservazione.Y = osservazione.Prezzo
          osservazione.X = osservazione.Istante.Subtract(istanteIniziale).TotalMilliseconds()
            Application.DoEvents()

        Next

        PuntiPuntiComuni = New List(Of Point)
        For Each osservazione As Osservazione In PuntiComuni
            Dim Punto As New Point
            Punto.X = Rettangolo.Left + CInt(Rettangolo.Width * (osservazione.X - Me.MinX) / (Me.MaxX - Me.MinX))
            Punto.Y = (Rettangolo.Top + CInt(Rettangolo.Height)) - (Rettangolo.Height * (osservazione.Y - Me.MinY) / (Me.MaxY - Me.MinY))
            PuntiPuntiComuni.Add(Punto)
        Next
    End Sub

·         Siamo quindi andati a scrivere i comandi per disegnare la serie, le medie e le bande, scegliendo i colori e il tipo di linee da utilizzare:

   Sub DisegnaLeSerie()
       bitmap = New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
        grafico = Graphics.FromImage(bitmap)
        Dim PennaTratteggiata As Pen
        PennaTratteggiata = New Pen(Color.Orange, 1)
        PennaTratteggiata.DashStyle = Drawing2D.DashStyle.Dot

        grafico.Clear(Color.White)
        grafico.DrawRectangle(Pens.Black, Rettangolo)
        grafico.DrawLines(Pens.SkyBlue, PuntiSS.ToArray)
        grafico.DrawLines(Pens.YellowGreen, PuntiSSMoving.ToArray)
        grafico.DrawLines(Pens.Fuchsia, PuntiSSRunning.ToArray)
        grafico.DrawLines(PennaTratteggiata, PuntiSSBBSUP.ToArray)
        grafico.DrawLines(PennaTratteggiata, PuntiSSBBINF.ToArray)

·         abbiamo inserito l’intestazione e la leggenda:

         Dim drawFont2 As New Font("Arial", 12, FontStyle.Bold)
       grafico.DrawString("SERIE STORICA", drawFont2, Brushes.Purple, 380, 10)
        Dim drawfont3 As New Font("arial", 8)
        grafico.FillRectangle(Brushes.SkyBlue, Me.PictureBox1.Width - 605, Me.PictureBox1.Height - 88, 6, 6)
        grafico.DrawString("Serie Storica", drawfont3, Brushes.Gray, Me.PictureBox1.Width - 600, Me.PictureBox1.Height - 92)
        grafico.FillRectangle(Brushes.YellowGreen, Me.PictureBox1.Width - 605, Me.PictureBox1.Height - 72, 6, 6)
        grafico.DrawString("Media Moving", drawfont3, Brushes.Gray, Me.PictureBox1.Width - 600, Me.PictureBox1.Height - 75)
        grafico.FillRectangle(Brushes.Fuchsia, Me.PictureBox1.Width - 605, Me.PictureBox1.Height - 55, 6, 6)
        grafico.DrawString("Media Running", drawfont3, Brushes.Gray, Me.PictureBox1.Width - 600, Me.PictureBox1.Height - 58)
        grafico.FillRectangle(Brushes.Orange, Me.PictureBox1.Width - 605, Me.PictureBox1.Height - 38, 6, 6)
        grafico.DrawString("Bande Bollinger", drawfont3, Brushes.Gray, Me.PictureBox1.Width - 600, Me.PictureBox1.Height - 41)

       Me.PictureBox1.Image = Me.bitmap
    End Sub

·         abbiamo infine inserito dei comandi per poter muovere il rettangolo e ridimensionarlo a nostro piacimento all’interno della pictureBox.

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

        If Me.SS Is Nothing Then Exit Sub
        Me.MouseTastoPremuto = True
        Me.XinizialeMOUSE = e.X
        Me.YinizialeMOUSE = e.Y
        Me.XinizialeRETT = Rettangolo.X
        Me.YinizialeRETT = Rettangolo.Y
        Me.WInizialeRETT = Rettangolo.Width
        Me.HInizialeRETT = Rettangolo.Height

    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

        If Me.grafico Is Nothing Then Exit Sub
        If Not Me.MouseTastoPremuto Then Exit Sub
         If e.Button = Windows.Forms.MouseButtons.Left Then
           Rettangolo.X = Me.XinizialeRETT + (e.X - Me.XinizialeMOUSE)
            Rettangolo.Y = Me.YinizialeRETT + (e.Y - Me.YinizialeMOUSE)
        Else

            Rettangolo.Width = Me.WInizialeRETT + (e.X - Me.XinizialeMOUSE)
            Rettangolo.Height = Me.HInizialeRETT + (e.X - Me.XinizialeMOUSE)

        End If

        Me.TrasfomaCoordInPnt()
        Me.DisegnaLeSerie()

    End Sub

 

·         Riporto la funzione per il calcolo dellla deviazione standard

 Function CalcoloDevStd(ByVal serie As List(Of Osservazione), ByVal Posto As Integer)

        If (NumericUpDown1.Value = 0) Then
           DistanzaDallaMedia = 1
        Else
            Me.DistanzaDallaMedia = CInt(Me.NumericUpDown1.Value - 1)
        End If
        Dim somma As Double
        Dim count As Double
        Dim scarti As Double
        Dim scartiquadrati As Double
        Dim media As Double
        Dim var As Double
        Dim deviazionestandard As Double
        For i As Integer = i To serie.Count - 1
            somma += serie(i).Prezzo
            count += 1
            media = somma / count
            scarti = serie(i).Prezzo - media
            scartiquadrati = scarti ^ 2
            var = scartiquadrati / count
        Next
        deviazionestandard = Math.Sqrt(var)
        Return deviazionestandard

    End Function

RISULTATO OTTENUTO


 




LINK:https://www.box.com/s/x0hgqvkszv6v2pjk1toa