1
$\begingroup$

I am not sure whether it a bug. Documentation on FinancialData states that we can choose possible frequency as "Day", "Week", "Month", "Year". However, when I choose "Month" as frequency to download historical stock price, I have noticed three problems with the downloaded historical prices. First, I have two prices for the same month. For example, I have two prices for third month of every year. Second problem is associated with date/price in every month. For some months, the date/price is at beginning of the month and for other months,the date/price is at end of the month. Third, I have no data for November.

FinancialData["MSFT", {{2015, 01, 30}, {2017, 05, 30}, "Month"}] // MatrixForm

enter image description here

Any help to fix this problem would be highly appreciated. I want one price per month and consistency about the date, either beginning of the month or end of the month or any chosen date of each month. Thank you in advance.

Update: While trying to do in more flexible way, I was able to use GatherBy (with the help of answer provided by b3m2a1) as follows: To get end of the month data:

Last /@ GatherBy[FinancialData["MSFT", {{2015, 01, 05}, {2017, 05, 30}}], #[[1, ;; 2]] &]

To get beginning of the month data:

First /@ GatherBy[FinancialData["MSFT", {{2015, 01, 05}, {2017, 05, 30}}], #[[1, ;; 2]] &]

I am still trying to figure out how to choose a specific date and get the data. If some months do not have specified date, the data must be missing. The following code gives me the data for chosen date but it does not include months that do not have the specified date.

yourselecteddate = 24;
Select[FinancialData["MSFT", {{2015, 01, 05}, {2017, 05, 30}}], #[[1, 3]] == 
   yourselecteddate &]
$\endgroup$
  • 2
    $\begingroup$ This all seems like some bugginess in calculating the dates. It's honestly probably all the same issue. Also try this: FinancialData["MSFT", {{2015, 01, 30}, {2015, 02, 4}}] It's dropped two days there. But who knows, maybe whatever data source they're fed from also doesn't have those days. Try this too FinancialData["MSFT", {{2015, 10, 30, 0, 0}, {2015, 11, 30, 0, 0}}] and you'll see that there certainly is some November data. Just nothing for the first or last day of the month. That may be why it drops November. I'd just use "Day" and sample it myself. Easy enough to do. $\endgroup$ – b3m2a1 Sep 7 '17 at 5:53
  • $\begingroup$ I am quite perplexed about the logic of FinancialData: If you look at the values for 2017 given in MatrixForm above, you will note, that the value for Jan 1 and Mar 1 is the last value (price) for that month. Also the value for Mar 31 is the last value for April. But the values given for Feb 1 and Apr 30 never appear in the daily values for either February or May. Where do these values ( Feb 1, 2017 and Apr 30, 2017) come from, e.g. what is their meaning? $\endgroup$ – gwr Sep 14 '17 at 15:21
2
$\begingroup$

So I mentioned this in a comment, but one work-around is to sample the closest-to-the-first day of the month you can, e.g.:

DeleteDuplicatesBy[
 FinancialData["MSFT", {{2015, 1, 1}, {2016, 1, 31}}], #[[1, ;; 2]] &]

{{{2015, 1, 2}, 43.555}, {{2015, 2, 2}, 38.4506}, {{2015, 3, 2}, 
  41.1633}, {{2015, 4, 1}, 38.1989}, {{2015, 5, 1}, 
  45.6473}, {{2015, 6, 1}, 44.5938}, {{2015, 7, 1}, 
  41.969}, {{2015, 8, 3}, 44.1973}, {{2015, 9, 1}, 
  39.7461}, {{2015, 10, 1}, 42.3978}, {{2015, 11, 2}, 
  50.5998}, {{2015, 12, 1}, 52.8354}, {{2016, 1, 4}, 52.4335}}
$\endgroup$
  • $\begingroup$ @ b3m2a1, thank you for your answer. $\endgroup$ – ramesh Sep 7 '17 at 13:43
  • $\begingroup$ I am not sure why this would not give monthly data: DeleteDuplicatesBy[ FinancialData["MSFT", {{2010, 1, 2}, {2017, 5, 31}}], #[[1, 2]] &] $\endgroup$ – ramesh Sep 7 '17 at 14:01
  • $\begingroup$ @ramesh which months is it missing? You can see if there's any data for them at all by removing the DeleteDuplicatesBy call $\endgroup$ – b3m2a1 Sep 7 '17 at 14:22
  • $\begingroup$ @ b3m2a1, if you see the downloaded data using DeleteDuplicatesBy[ FinancialData["MSFT", {{2010, 1, 2}, {2017, 5, 31}}], #[[1, 2]] &] , you will see the problem. FinancialData["MSFT", {{2010, 1, 2}, {2017, 5, 31}}] downloaded the daily data for all the periods chosen but DeleteDuplicatesBy[ FinancialData["MSFT", {{2010, 1, 2}, {2017, 5, 31}}], #[[1, 2]] &] keeps only 12 months of data. I can fix it. $\endgroup$ – ramesh Sep 7 '17 at 21:51
  • $\begingroup$ @ramesh that's what the DeleteDuplicatesBy is doing. It's deleting everything but the first day of each month. To preserve it across years replace 2 with ;;2. $\endgroup$ – b3m2a1 Sep 7 '17 at 21:53
2
$\begingroup$

A more general (albeit slower) approach

DeleteDuplicates will work fast, but it is not very general: What we may want is to work with a range of dates in the same way DateRange does and then give the financial value for the nearest trading day for any date.

While we may make use of Nearest, an easier approach would be to take the value of the first trading day after a given date to be the nearest financial value should a given date not be a trading day.

We would thus like to define a function nearestFinancialData that would work like this for a single datum (e.g. not returning Missing[NotAvailable]):

(*
SameQ[
    nearestFinancialData[ "MSFT", { {2015, 2, 1} }, "Value" ], 
    FinancialData[        "MSFT", { {2015, 2, 2} }, "Value" ]
]
*)

(* True *)

We would also like this function to work on a period by using DateRange and given values according to the specification for a single datum above.

Implementation

around[ date_, prox_Integer: 3 (* days *) ] := List[
    DateList@date,
    DatePlus[ DateList @ date, Quantity[ prox, "Days" ] ]
]; (* define the period for the next trading day *)

nearestFinancialData[ name_String, prop___, { date_ }, form_:"DateValue" ] := With[
   {
       dataRange = around[ date ]
   },
   Module[
       {
           finData = FinancialData[ 
               name, 
               prop, 
               { First @ dataRange, Last @ dataRange, "Day" },
               "Value" 
           ]
       },
       Switch[ form,
           "DateValue" , { { date,  First @ finData } },
           _           , { First @ finData }
       ]
   ]
]

Testing this first part:

nearestFinancialData[ "MSFT", { {2015, 1} }, "Value"]

{43.555}

As this basic functionality works out, we can expand upon it:

nearestFinancialData[ name_String, prop___, {start_, end_, period_ } , form_: "DateValue" ] := With[
    {
        (* define a DateRange using {y,m,d}-format *)
        dataRange = DateRange[ start, end, period ] // Take[#, All, 3] &
    },
    ParallelMap[
        Flatten[ nearestFinancialData[ name, prop { # }, form ], 1 ] &,
        dataRange
    ] // Switch[ form,
        "Value" , Flatten ,
        _       , Identity
    ]
]

Now, something like the following will work out nicely:

nearestFinancialData[ "MSFT" , { {2015, 1, 1}, {2015, 12, 31}, "Quarter" } ]

{{{2015, 1, 1}, 43.555}, {{2015, 4, 1}, 38.1989}, {{2015, 7, 1}, 41.969}, {{2015, 10, 1}, 42.3978}}

$\endgroup$
  • $\begingroup$ @ gwr, I really appreciate it for taking time to answer my question. Thank you. $\endgroup$ – ramesh Sep 15 '17 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.