sabato 20 novembre 2010

Carrieri Alessandra - Esercizio 1

Public Class Form1
    Private b As Bitmap
    Private g As Graphics

    Private MargineSinistro As Integer = 10
    Private MargineDestro As Integer = 10

    Private MargineAlto As Integer = 10
    Private MargineBasso As Integer = 10

    Private MinimoPrezzo As Decimal
    Private MassimoPrezzo As Decimal

    Private MinimoTempo As Double
    Private MassimoTempo As Double

    Private Y_MM As New List(Of Integer)
    Private X_MM As New List(Of Integer)

    Dim FontPrezzi As New Font("Arial", 10, FontStyle.Bold)

    Dim ListaOsservazioni_BID As List(Of Osservazione)
    Dim ListaOsservazioni_ASK As List(Of Osservazione)
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim o As New OpenFileDialog
        Dim FileDeiPrezzi As String
        With o
            .ShowDialog()
            If .FileName = String.Empty Then Exit Sub
            FileDeiPrezzi = .FileName
        End With
        Dim DatiTxtContenutiInFile As String = My.Computer.FileSystem.ReadAllText(FileDeiPrezzi)
        Dim RigheDelFile As String() = DatiTxtContenutiInFile.Split(vbCrLf.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
        '----------------------------------
        'Ogni riga diventa una osservazione
        '----------------------------------
        Dim CulturaUSA As System.Globalization.CultureInfo = System.Globalization.CultureInfo.GetCultureInfo("en-US")
        ListaOsservazioni_BID = New List(Of Osservazione)
        ListaOsservazioni_ASK = New List(Of Osservazione)
        For Each Riga As String In RigheDelFile

            Dim ValoriInUnaRiga As String() = Riga.Split(" ".ToCharArray, StringSplitOptions.RemoveEmptyEntries)
            Dim Osservazione As New Osservazione
            With Osservazione
                Dim Ora As Integer = CInt(ValoriInUnaRiga(0))
                Dim Minuti As Integer = CInt(ValoriInUnaRiga(1))
                Dim Secondi As Integer = CInt(ValoriInUnaRiga(2))
                Dim Millisecs As Integer = CInt(ValoriInUnaRiga(3))

                .Istante = New Date(Now.Year, Now.Month, Now.Day, Ora, Minuti, Secondi, Millisecs)
                .TipoPrezzo = CInt(ValoriInUnaRiga(4))
                .Prezzo = Decimal.Parse(ValoriInUnaRiga(5), CulturaUSA)

                If .TipoPrezzo = 1 Then
                    ListaOsservazioni_BID.Add(Osservazione)
                ElseIf .TipoPrezzo = 2 Then
                    ListaOsservazioni_ASK.Add(Osservazione)
                Else
                    'Throw New Exception("inatteso")
                End If
            End With

        Next Riga

        Me.DisegnaGRafico()
    End Sub

    Sub DisegnaGRafico()
        If Me.ListaOsservazioni_ASK Is Nothing Then Exit Sub

        b = New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
        g = Graphics.FromImage(b)

        '---------------------------------------------------------------
        ' Adesso le 2 liste osservazioni diventano delle liste di punti da rappresentare su un bitmap
        '---------------------------------------------------------------
        Dim ListaDiPunti_BID As List(Of Point) = Me.CreaListaPuntiDaListaOsservazioni(ListaOsservazioni_BID)
        Dim ListaDiPunti_ASK As List(Of Point) = Me.CreaListaPuntiDaListaOsservazioni(ListaOsservazioni_ASK)


        'Visualizzo margini
        g.DrawRectangle(Pens.Black, New Rectangle(Me.MargineSinistro, Me.MargineAlto, _
                                                      b.Width - Me.MargineSinistro - Me.MargineDestro, b.Height - Me.MargineAlto - Me.MargineBasso))

        'Usare drawlines per il plot delle 2 curve
        'Curve dei prezzi
        'BID
        Dim p_BID As New Pen(Color.Red, 1)
        g.DrawLines(p_BID, ListaDiPunti_BID.ToArray)
        'ASK
        Dim p_ASK As New Pen(Color.Blue, 0.5)
        g.DrawLines(p_ASK, ListaDiPunti_ASK.ToArray)
        'Medie mobili
        g.DrawLines(New Pen(Color.Yellow, 3), Me.MediaMobile(ListaOsservazioni_ASK, NumeroTerminiMediaMobile).ToArray)
        g.DrawLines(New Pen(Color.Chocolate, 1), Me.MediaMobile(ListaOsservazioni_BID, NumeroTerminiMediaMobile).ToArray)
        'Disegno asse dei prezzi
        Me.DrawPriceRuler()
        Me.PictureBox1.Image = b

    End Sub

    Function CreaListaPuntiDaListaOsservazioni(ByVal ListaOsservazioni As List(Of Osservazione)) As List(Of Point)

        'Determinazione del minimo e massimo prezzo
        Dim TempoOrigine As Date = New Date(Now.Year, Now.Month, Now.Day, 0, 0, 0)

        Me.MinimoPrezzo = Decimal.MaxValue
        Me.MassimoPrezzo = Decimal.MinValue

        Me.MinimoTempo = Double.MaxValue
        Me.MassimoTempo = Double.MinValue

        For Each Osservazione As Osservazione In ListaOsservazioni
            With Osservazione
                'prezzo
                If MinimoPrezzo > .Prezzo Then MinimoPrezzo = .Prezzo
                If MassimoPrezzo < .Prezzo Then MassimoPrezzo = .Prezzo
                'tempo
                Dim Tempo As Double = .Istante.Subtract(TempoOrigine).TotalMilliseconds
                If MinimoTempo > Tempo Then MinimoTempo = Tempo
                If MassimoTempo < Tempo Then MassimoTempo = Tempo
            End With
        Next Osservazione
        Dim ListaPunti As New List(Of Point)
        For Each Osservazione As Osservazione In ListaOsservazioni

            With Osservazione
                'Determinare il punto!
                Dim x As Double = .Istante.Subtract(TempoOrigine).TotalMilliseconds
                Dim y As Decimal = .Prezzo
                'Trasformare il punto per rappresentarlo sul bitmap!
                Dim X_Sul_Bitmap As Integer = Me.Trasforma_X(x, MinimoTempo, MassimoTempo, MargineSinistro, MargineDestro)

                X_MM.Add(X_Sul_Bitmap)

                Dim Y_Sul_Bitmap As Integer = Me.Trasforma_Y(y, MinimoPrezzo, MassimoPrezzo, MargineAlto, MargineBasso)

                Y_MM.Add(Y_Sul_Bitmap)

                Dim p As New Point(X_Sul_Bitmap, Y_Sul_Bitmap)
                ListaPunti.Add(p)
            End With

        Next Osservazione

        Return ListaPunti
    End Function



    Function Trasforma_X(ByVal x As Double, ByVal MinX As Double, ByVal MaxX As Double, _
                         ByVal MarginLeft As Integer, ByVal MarginRight As Integer) As Integer
        Dim X_Trasformata As Integer = MarginLeft + CInt((Me.b.Width - MarginLeft - MarginRight) * (x - MinX) / (MaxX - MinX))
        Return X_Trasformata

    End Function

    Function Trasforma_Y(ByVal y As Double, ByVal MinY As Double, ByVal MaxY As Double, _
                         ByVal MarginTop As Integer, ByVal MarginBottom As Integer) As Integer
        Dim Y_Trasformata As Integer = Me.b.Height - MarginTop - CInt((Me.b.Height - MarginTop - MarginBottom) * (y - MinY) / (MaxY - MinY))
        Return Y_Trasformata

    End Function

  

    Sub DrawPriceRuler()
        Dim NumeroSuddivisioni As Integer = 10
        Dim Passo As Double = (Me.MassimoPrezzo - Me.MinimoPrezzo) / NumeroSuddivisioni
        Dim Prezzo As Double = Me.MinimoPrezzo
        Do
            Prezzo += Passo
            If Prezzo > Me.MassimoPrezzo Then Exit Do
            'Disegno della tacca e del prezzo

            Dim Y_Bitmap = Me.Trasforma_Y(Prezzo, Me.MinimoPrezzo, Me.MassimoPrezzo, Me.MargineAlto, Me.MargineBasso)
            Me.g.DrawString(Prezzo.ToString, Me.FontPrezzi, Brushes.Black, Me.MargineSinistro + 5, Y_Bitmap)
        Loop

    End Sub

    Private Sub Form1_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
        Me.DisegnaGRafico()
    End Sub

    Private NumeroTerminiMediaMobile As Integer

    Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
        Me.NumeroTerminiMediaMobile = CInt(Me.NumericUpDown1.Value)
        Me.DisegnaGRafico()
    End Sub
    'Funzione per il calcolo della Media Mobile
    Function MediaMobile(ByVal ListaTermini As List(Of Osservazione), ByVal NumTermMM As Integer) As List(Of Point)

        Dim MMobili As New List(Of Integer)
        Dim sum As Double = 0
        Dim i As Integer = 0
        Dim j As Integer = 0

        For i = 0 To ListaTermini.Count
            If (i = NumTermMM) Then
                For j = i - NumeroTerminiMediaMobile To i
                    sum += Y_MM.Item(j)
                Next j
                MMobili.Add(CInt(sum / NumeroTerminiMediaMobile))
                sum = 0
                NumTermMM += 1
            End If
        Next i

        Dim PuntiMediaMobile As New List(Of Point)

        For i = 0 To (MMobili.Count - 1)
            Dim InserisciPunto As New Point(X_MM.Item(i), MMobili.Item(i))
            PuntiMediaMobile.Add(InserisciPunto)
        Next

        Return PuntiMediaMobile


    End Function


End Class

Public Class Osservazione
    Public Istante As Date
    Public TipoPrezzo As Integer
    Public Prezzo As Decimal
End Class

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.