' ******************************************************************************
' **
' ** Yahoo Finance Managed
' ** Written by Marius Häusler 2010
' ** It would be pleasant, if you contact me when you are using this code.
' ** Contact: YahooFinanceManaged@gmail.com
' ** Project Home: http://code.google.com/p/yahoo-finance-managed/
' **
' ******************************************************************************
' **
' ** Copyright 2010 Marius Häusler
' **
' ** Licensed under the Apache License, Version 2.0 (the "License");
' ** you may not use this file except in compliance with the License.
' ** You may obtain a copy of the License at
' **
' ** http://www.apache.org/licenses/LICENSE-2.0
' **
' ** Unless required by applicable law or agreed to in writing, software
' ** distributed under the License is distributed on an "AS IS" BASIS,
' ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' ** See the License for the specific language governing permissions and
' ** limitations under the License.
' **
' ******************************************************************************
Namespace Finance.Support
''' <summary>
''' Serializable. Class for managing stock exchange information.
''' </summary>
''' <remarks></remarks>
<Serializable()> _
Public Class StockExchange
Private mExchangeID, mName, mSuffix As String
Private mCountry As Country = Country.Unknown
Private mDelayMinutes, mRelativeToUTC, mTradingHours, mTradingMinutes As Integer
Private mOpeningTimeUTC, mClosingTimeUTC, mOpeningTimeLocalExchange As DateTime
Private mTradingDays As New List(Of DayOfWeek)
Private mCurrency As Currency
Private mHolidays As New List(Of Date)
''' <summary>
''' The ID of the exchange
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>If the ID is in WorldMarket.DefaultStockExchanges, properties will be setted automatically</remarks>
Public Property ID() As String
Get
Return mExchangeID
End Get
Set(ByVal value As String)
If value = String.Empty Then
Me.Clear()
Else
mExchangeID = value.ToUpper
If WorldMarket.StockExchanges IsNot Nothing Then
For Each se As StockExchange In WorldMarket.StockExchanges
If se IsNot Nothing AndAlso se.ID.ToLower = value.ToLower Then
Me.CopyValues(se)
Exit For
End If
Next
End If
End If
End Set
End Property
''' <summary>
''' The ending string for stock IDs
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>If the suffix is in DefaultStockExchanges, properties will get automatically</remarks>
Public Property Suffix() As String
Get
Return mSuffix
End Get
Set(ByVal value As String)
If mSuffix <> value.ToUpper Then
If value <> String.Empty Then
Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(value, "\.[a-zA-Z0-9][a-zA-Z0-9]?$")
If m.Success Then
mSuffix = m.Value.ToUpper
If WorldMarket.StockExchanges IsNot Nothing Then
For Each se As StockExchange In WorldMarket.StockExchanges
If se IsNot Nothing AndAlso se.ID.ToUpper = m.Value.ToUpper Then
Me.CopyValues(se)
Exit For
End If
Next
End If
End If
Else
mSuffix = String.Empty
End If
End If
End Set
End Property
''' <summary>
''' The name of the exchange
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Name() As String
Get
Return mName
End Get
Set(ByVal value As String)
mName = value
End Set
End Property
''' <summary>
''' The country of the exchange
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Country() As Country
Get
Return mCountry
End Get
Set(ByVal value As Country)
mCountry = value
End Set
End Property
''' <summary>
''' The currency of the country
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Currency() As Currency
Get
Return mCurrency
End Get
Set(ByVal value As Currency)
mCurrency = value
End Set
End Property
''' <summary>
''' The days when trading is active
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property TradingDays() As List(Of DayOfWeek)
Get
Return mTradingDays
End Get
Set(ByVal value As List(Of DayOfWeek))
mTradingDays = value
End Set
End Property
''' <summary>
''' Days without active trading time.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Holidays() As List(Of Date)
Get
Return mHolidays
End Get
Set(ByVal value As List(Of Date))
mHolidays = value
End Set
End Property
''' <summary>
''' The data response delay to realtime of yahoo servers
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property DelayMinutes() As Integer
Get
Return mDelayMinutes
End Get
Set(ByVal value As Integer)
If value > 0 And value < 3600 Then mDelayMinutes = value
End Set
End Property
''' <summary>
''' The number of hours relative to UTC of the exchange's timezone
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property RelativeToUTC() As Integer
Get
Return mRelativeToUTC
End Get
Set(ByVal value As Integer)
If value >= -12 And value <= 12 Then
mRelativeToUTC = value
Me.SetTradingTimes()
End If
End Set
End Property
''' <summary>
''' The time when trading starts
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>By setting a value, the date is not important, only hour and minute</remarks>
Public Property OpeningTimeUTC() As DateTime
Get
Return mOpeningTimeUTC
End Get
Set(ByVal value As DateTime)
mOpeningTimeUTC = #12:00:00 AM#.AddHours(value.Hour).AddMinutes(value.Minute)
Me.SetTradingTimes()
End Set
End Property
''' <summary>
''' The time when trading ends
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>By setting a value, the date is not important, only hour and minute. If time value is smaler than opening, trading ends on the next day. 24 hours trading is maximum</remarks>
Public Property ClosingTimeUTC() As DateTime
Get
Return mClosingTimeUTC
End Get
Set(ByVal value As DateTime)
mClosingTimeUTC = #12:00:00 AM#.AddHours(value.Hour).AddMinutes(value.Minute)
Me.SetTradingTimes()
End Set
End Property
''' <summary>
''' The local time of exchange's timezone when trading starts
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property OpeningTimeLocalExchange() As DateTime
Get
Return mOpeningTimeLocalExchange
End Get
End Property
''' <summary>
''' Default constructor
''' </summary>
''' <remarks></remarks>
Public Sub New()
Me.Clear()
mTradingDays.AddRange(New DayOfWeek() {DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday})
End Sub
''' <summary>
''' Overloaded constructor
''' </summary>
''' <param name="excID">The ID of the stock exchange</param>
''' <remarks></remarks>
Public Sub New(ByVal excID As String)
Me.New()
Me.ID = excID
End Sub
''' <summary>
''' Overloaded constructor
''' </summary>
''' <param name="excID">The ID of the stock exchange</param>
''' <param name="name">The name of the stock exchange</param>
''' <param name="suffix">The suffix of the stock exchange ID</param>
''' <remarks></remarks>
Public Sub New(ByVal excID As String, ByVal name As String, ByVal suffix As String)
Me.New()
mExchangeID = excID
mName = name
mSuffix = suffix
End Sub
''' <summary>
''' Clears all values
''' </summary>
''' <remarks></remarks>
Public Sub Clear()
mName = String.Empty
mSuffix = String.Empty
mExchangeID = String.Empty
mCountry = Country.Unknown
mCurrency = Currency.AED
mTradingHours = 24
mRelativeToUTC = 0
mOpeningTimeUTC = #12:00:00 AM#
mClosingTimeUTC = #12:00:00 AM#
mDelayMinutes = 0
mTradingDays = New List(Of DayOfWeek)
Me.SetTradingTimes()
End Sub
''' <summary>
''' Returns if trading is active at a specific datetime using the machines current timezone
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function IsActiveLocal(ByVal atThisLocalTime As DateTime) As Boolean
Return IsActiveUTC(TimeZone.CurrentTimeZone.ToUniversalTime(atThisLocalTime))
End Function
''' <summary>
''' Returns if trading is active at a specific UTC datetime
''' </summary>
''' <param name="atThisUTCTime"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function IsActiveUTC(ByVal atThisUTCTime As DateTime) As Boolean
Dim timeZoneDate As DateTime = atThisUTCTime.AddHours(mRelativeToUTC)
Dim tradingSpan As New TimeSpan(mTradingHours, mTradingMinutes, 0)
Dim holiday As Boolean = False
If mHolidays IsNot Nothing Then
For Each h As Date In mHolidays
If h.Date = timeZoneDate.Date Then
holiday = True
Exit For
End If
Next
End If
If Not holiday Then
If mTradingDays.Contains(timeZoneDate.DayOfWeek) Then
If IsInSpan(timeZoneDate, tradingSpan) Then
Return True
Else
Return IsInSpan(timeZoneDate, tradingSpan, -1)
End If
Else
Return ((mOpeningTimeUTC.Hour + mTradingHours + ((mOpeningTimeUTC.Minute + mTradingMinutes) / 60) > 24 And _
mTradingDays.Contains(timeZoneDate.AddDays(-1).DayOfWeek)) AndAlso _
IsInSpan(timeZoneDate, tradingSpan, -1))
End If
Else
Return False
End If
End Function
Private Function IsInSpan(ByVal d As DateTime, ByVal ts As TimeSpan, Optional ByVal relativeDays As Integer = 0) As Boolean
Dim newD As DateTime = d.AddMinutes(mDelayMinutes * -1)
With newD.AddDays(relativeDays)
If mTradingDays IsNot Nothing AndAlso mTradingDays.Contains(.DayOfWeek) Then
Dim startDate As DateTime = .Date.AddHours(mOpeningTimeLocalExchange.Hour).AddMinutes(mOpeningTimeLocalExchange.Minute)
Dim endDate As DateTime = startDate.Add(ts)
Return (newD >= startDate And newD <= endDate)
Else
Return False
End If
End With
End Function
Private Sub SetTradingTimes()
If mOpeningTimeUTC = mClosingTimeUTC Then
mTradingHours = 24
mTradingMinutes = 0
ElseIf mOpeningTimeUTC < mClosingTimeUTC Then
Dim ts As TimeSpan = mClosingTimeUTC - mOpeningTimeUTC
mTradingHours = CInt(Math.Truncate(ts.TotalHours))
mTradingMinutes = CInt((ts.TotalHours Mod 1) * 60)
Else
Dim endDate As DateTime = mClosingTimeUTC.AddDays(1)
Dim ts As TimeSpan = endDate - mOpeningTimeUTC
mTradingHours = CInt(Math.Truncate(ts.TotalHours))
mTradingMinutes = CInt((ts.TotalHours Mod 1) * 60)
End If
Dim diff As Double = (mOpeningTimeUTC.Hour * 60 + mOpeningTimeUTC.Minute) + (mRelativeToUTC * 60)
If diff < 0 Then
mOpeningTimeLocalExchange = #12:00:00 AM#.AddDays(1).AddMinutes(diff)
Else
Dim open As Date = mOpeningTimeUTC.AddHours(mRelativeToUTC)
mOpeningTimeLocalExchange = #12:00:00 AM#.AddHours(open.Hour).AddMinutes(open.Minute)
End If
End Sub
Private Sub CopyValues(ByVal se As StockExchange)
If se IsNot Nothing Then
mExchangeID = se.ID
mCountry = se.Country
mSuffix = se.Suffix
mName = se.Name
mCountry = se.Country
mCurrency = se.Currency
mTradingDays.Clear()
mTradingDays.AddRange(se.TradingDays)
mDelayMinutes = se.DelayMinutes
mRelativeToUTC = se.RelativeToUTC
mOpeningTimeUTC = se.OpeningTimeUTC
mClosingTimeUTC = se.ClosingTimeUTC
Me.SetTradingTimes()
End If
End Sub
''' <summary>
''' Returns the name of the stock exchange
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Overrides Function ToString() As String
Return mName
End Function
End Class
End Namespace