I've been successfully running this code for a while now using an abbreviated set of data of approximately 15 stocks worth of historical stock prices (example: http://ichart.yahoo.com/table.csv?s=goog). I just scaled up the amount of data to approximately 6,000 stocks (920,570 records in my DataTable
) and now I am having some problems.
Here is the code:
Public Sub Update_Quarterly_Growth_Rates()
ToolStripStatusLabel2.Text = "Updating Quarterly Growth Rates"
con.Open()
Try
Dim cmd As OleDbCommand = New OleDbCommand("CREATE PROC Stock_Price_with_qtr AS SELECT Historical_Stock_Prices.*, Year([Date]) AS [Year], Switch(Month([Date])<4,1,Month([Date])<7,2,Month([Date])<10,3,True,4) AS Qtr FROM Historical_Stock_Prices", con)
cmd.ExecuteNonQuery()
Catch ex As Exception
Finally
Dim cmda As OleDbCommand = New OleDbCommand("DROP PROCEDURE Stock_Price_with_qtr", con)
cmda.ExecuteNonQuery()
Dim cmdb As OleDbCommand = New OleDbCommand("CREATE PROC Stock_Price_with_qtr AS SELECT Historical_Stock_Prices.*, Year([Date]) AS [Year], Switch(Month([Date])<4,1,Month([Date])<7,2,Month([Date])<10,3,True,4) AS Qtr FROM Historical_Stock_Prices", con)
cmdb.ExecuteNonQuery()
End Try
Try
Dim cmd1 As OleDbCommand = New OleDbCommand("CREATE PROC Qtr_Dates AS SELECT Stock_Price_with_qtr.Ticker, Stock_Price_with_qtr.[Year], Stock_Price_with_qtr.Qtr, Min(Stock_Price_with_qtr.[Date]) AS Qtr_Start, Max(Stock_Price_with_qtr.[Date]) AS Qtr_End FROM Stock_Price_with_qtr GROUP BY Stock_Price_with_qtr.Ticker, Stock_Price_with_qtr.[Year], Stock_Price_with_qtr.Qtr", con)
cmd1.ExecuteNonQuery()
Catch ex As Exception
Finally
Dim cmd1a As OleDbCommand = New OleDbCommand("DROP PROCEDURE Qtr_Dates", con)
cmd1a.ExecuteNonQuery()
Dim cmd1b As OleDbCommand = New OleDbCommand("CREATE PROC Qtr_Dates AS SELECT Stock_Price_with_qtr.Ticker, Stock_Price_with_qtr.[Year], Stock_Price_with_qtr.Qtr, Min(Stock_Price_with_qtr.[Date]) AS Qtr_Start, Max(Stock_Price_with_qtr.[Date]) AS Qtr_End FROM Stock_Price_with_qtr GROUP BY Stock_Price_with_qtr.Ticker, Stock_Price_with_qtr.[Year], Stock_Price_with_qtr.Qtr", con)
cmd1b.ExecuteNonQuery()
End Try
Try
Dim cmd2 As OleDbCommand = New OleDbCommand("CREATE PROC Quarterly_Growth_Rates AS SELECT Qtr_Dates.Ticker, Qtr_Dates.[Year], Qtr_Dates.Qtr, (([Close_Prices]![Close]/[Open_Prices]![Open])-1)*100 AS Growth_Rate FROM (Historical_Stock_Prices AS Open_Prices INNER JOIN Qtr_Dates ON (Open_Prices.Ticker = Qtr_Dates.Ticker) AND (Open_Prices.[Date] = Qtr_Dates.Qtr_Start)) INNER JOIN Historical_Stock_Prices AS Close_Prices ON (Qtr_Dates.Ticker = Close_Prices.Ticker) AND (Qtr_Dates.Qtr_End = Close_Prices.[Date])", con)
cmd2.ExecuteNonQuery()
Catch ex As Exception
Finally
Dim cmd2a As OleDbCommand = New OleDbCommand("DROP PROCEDURE Quarterly_Growth_Rates", con)
cmd2a.ExecuteNonQuery()
Dim cmd2b As OleDbCommand = New OleDbCommand("CREATE PROC Quarterly_Growth_Rates AS SELECT Qtr_Dates.Ticker, Qtr_Dates.[Year], Qtr_Dates.Qtr, (([Close_Prices]![Close]/[Open_Prices]![Open])-1)*100 AS Growth_Rate FROM (Historical_Stock_Prices AS Open_Prices INNER JOIN Qtr_Dates ON (Open_Prices.Ticker = Qtr_Dates.Ticker) AND (Open_Prices.[Date] = Qtr_Dates.Qtr_Start)) INNER JOIN Historical_Stock_Prices AS Close_Prices ON (Qtr_Dates.Ticker = Close_Prices.Ticker) AND (Qtr_Dates.Qtr_End = Close_Prices.[Date])", con)
cmd2b.ExecuteNonQuery()
End Try
Close()
ToolStripStatusLabel2.Text = ""
End Sub
Private Sub Load_Quarterly_Growth_Rates()
con.Open()
Dim cmd3 As OleDbCommand = New OleDbCommand("TRANSFORM First(y.Growth_Rate) AS FirstOfGrowth Select y.Ticker FROM Quarterly_Growth_Rates AS y GROUP BY y.Ticker ORDER BY y.Year & '-' & y.Qtr DESC PIVOT y.Year & '-' & y.Qtr", con)
Dim reader As OleDbDataReader = cmd3.ExecuteReader()
Dim da As New DataTable
da.Load(reader)
DataGridView_Quarterly_Growth_Rates.DataSource = da
reader.Close()
con.Close()
End Sub
When I try to display the query by loading it into a DataGridView
, I get a Division by zero
error. I'm not quite sure where to go from here. I guess I would like to disregard any results that are affected by dividing by zero and just return a blank.
In both your growth calculations, use something like
IIf([Open_Prices]![Open] <> 0,
(([Close_Prices]![Close]/[Open_Prices]![Open])-1)*100,
null
)
instead of
(([Close_Prices]![Close]/[Open_Prices]![Open])-1)*100
This checks for 0
and avoids executing the division if the denominator would be 0
.