' ******************************************************************************
' **
' ** 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>
''' Class for managing stock exchange information.
''' </summary>
''' <remarks></remarks>
Public Class StockExchange
Private mExchangeID As String = String.Empty
Private mName As String = String.Empty
Private mSuffix As String = String.Empty
Private mCountry As Country = Country.AR
Private mCurrency As Currency = Finance.Currency.AED
Private mDelayMinutes, mRelativeToUTC, mTradingHours, mTradingMinutes As Integer
Private mOpeningTimeUTC, mClosingTimeUTC, mOpeningTimeLocalExchange As DateTime
Private mTradingDays As New List(Of DayOfWeek)
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 ReadOnly Property ID() As String
Get
Return mExchangeID
End Get
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 ReadOnly Property Suffix() As String
Get
Return mSuffix
End Get
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
Private ReadOnly mTags As New List(Of String)
Friend ReadOnly Property Tags() As List(Of String)
Get
Return mTags
End Get
End Property
''' <summary>
''' Default constructor
''' </summary>
''' <param name="id"></param>
''' <param name="suffix"></param>
''' <remarks></remarks>
Public Sub New(ByVal id As String, ByVal suffix As String)
Me.Clear()
Dim setted As Boolean = False
Dim suff As String = suffix.ToUpper
Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(suffix, "\.[a-zA-Z0-9][a-zA-Z0-9]?$")
If m.Success Then suff = m.Value.ToUpper
If WorldMarket.DefaultStockExchanges IsNot Nothing Then
For Each se As StockExchange In WorldMarket.DefaultStockExchanges
If se IsNot Nothing AndAlso se.ID.ToUpper = id.ToUpper Then
Me.CopyValues(se)
setted = True
Exit For
End If
Next
If Not setted Then
For Each se As StockExchange In WorldMarket.DefaultStockExchanges
If suffix <> String.Empty And suff = se.Suffix Then
Me.CopyValues(se)
setted = True
Exit For
End If
Next
End If
End If
If Not setted Then
mExchangeID = id.ToUpper
If mSuffix = String.Empty Then mSuffix = suff
End If
mTradingDays.AddRange(New DayOfWeek() {DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday})
End Sub
''' <summary>
''' Overloaded constructor
''' </summary>
''' <param name="id">The ID of the stock exchange</param>
''' <param name="suffix">The suffix of the stock exchange ID</param>
''' <param name="name">The name of the stock exchange</param>
''' <remarks></remarks>
Public Sub New(ByVal id As String, ByVal suffix As String, ByVal name As String)
Me.New(id, suffix)
mName = name
End Sub
Friend Sub New(ByVal se As StockExchange)
If se Is Nothing Then Throw New ArgumentNullException("se", "Original StockExchange is null.")
Me.CopyValues(se)
End Sub
''' <summary>
''' Clears all values.
''' </summary>
''' <remarks></remarks>
Public Sub Clear()
mName = String.Empty
mCountry = Country.US
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 in relation to machine's current timezone.
''' </summary>
''' <param name="atThisLocalTime">The result will be in relation to the passed DateTime of the machine's local time zone.</param>
''' <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 DateTime in relation to UTC datetime.
''' </summary>
''' <param name="atThisUTCTime">The result will be in relation to the passed DateTime of UTC time zone.</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(ts.TotalHours - (ts.TotalHours Mod 1))
mTradingMinutes = CInt((ts.TotalHours Mod 1) * 60)
Else
Dim endDate As DateTime = mClosingTimeUTC.AddDays(1)
Dim ts As TimeSpan = endDate - mOpeningTimeUTC
mTradingHours = CInt(ts.TotalHours - (ts.TotalHours Mod 1))
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