5
$\begingroup$

I'm trying to build a financial indicator in mathematica. I import some historical data

 Data = FinancialData["^GSPC", "OHLCV", {2009}];
 Data[[1;;5]]

 {{{2009, 1, 2}, {902.99, 934.73, 899.35, 931.8, 4048270000}}, 
  {{2009, 1, 5}, {929.17, 936.63, 919.53, 927.45, 5413910000}}, 
  {{2009, 1, 6}, {931.17, 943.85, 927.28, 934.7, 5392620000}}, 
  {{2009, 1, 7}, {927.45, 927.45, 902.37, 906.65, 4704940000}}, 
  {{2009, 1, 8}, {905.73, 910., 896.81, 909.73, 4991550000}}}

Now I want to apply a function to a moving window of the data:

 MovingMap[foo[#] &, Data, 5]

However, MovingMap does something unexpected it maps over the second entry in each list:

{{3440361600, 
  foo[{{902.99, 934.73, 899.35, 931.8, 4048270000}, 
       {929.17, 936.63, 919.53, 927.45, 5413910000}, 
       {931.17, 943.85, 927.28, 934.7, 5392620000}, 
       {927.45, 927.45, 902.37, 906.65, 4704940000}, 
       {905.73, 910., 896.81, 909.73, 4991550000}}]},
       {3440448000, 
       foo[{{929.17, 936.63, 919.53, 927.45, 5413910000}, 
            {931.17, 943.85, 927.28, 934.7, 5392620000}, 
            {927.45, 927.45, 902.37, 906.65, 4704940000}, 
            {905.73, 910., 896.81, 909.73, 4991550000}, 
            {909.91, 911.93, 888.31, 890.35, 4716500000}}]}, ...}

I was expecting something like a moving window through the list:

  foo[{{{date}, {O, H, L, C, V}},
       {{date}, {O, H, L, C, V}},
       {{date}, {O, H, L, C, V}},
       {{date}, {O, H, L, C, V}}, ...}]

What have I misunderstood or done wrong here?

Just to be thorough

 MovingMap[foo &, dowData[[1 ;; 200]], {20, "Day"}]

Produces this output:

{{3441484800, foo}, 
 {3441571200, foo}, 
 {3441657600, foo},...}

EDIT: It seems when given a time series like that which FinancialData returns MovingMap will Map over the data for you. Removing the need to deal with the dates yourself. Poorly documented, but convenient if you know about this behaviour.

However, my indicator is calling FinancialIndicator itself, which seems to need the full date/OHLCV time series. Is there any way to have this work as one might expect?

Example of what I'm trying to do:

 intraTotal[ts_] := Total[FinancialIndicator["TrueRange" ][ts]];

 periodRange[ts_] := Max[Map[ #[[2, 2]] &, ts]] - Min[Map[ #[[2, 3]] &, ts]];

 FracDim[ts_, period_] := intraTotal[Take[ts, -period]]/periodRange[Take[ts, -period]];
$\endgroup$
4
  • $\begingroup$ MovingMap[foo, Data, {5, "Day"}] $\endgroup$ Mar 14, 2015 at 1:05
  • $\begingroup$ Still shows the same behaviour. $\endgroup$
    – user4860
    Mar 14, 2015 at 1:08
  • $\begingroup$ You can just rewrite your FracDim to work similar to the FinancialIndicators. Something like fracDim[ts_, period_] := Table[ intraTotal[ts[[s ;; s + period]]]/ periodRange[ts[[s ;; s + period]]], {s, Length@ts - period}];. $\endgroup$
    – Karsten7
    Mar 14, 2015 at 4:22
  • $\begingroup$ That would work in the small. But it stops me from writing indicators which rely on other indicators to do part of the work. and this seems like exactly the sort of use case MovingMap was designed for. $\endgroup$
    – user4860
    Mar 14, 2015 at 4:38

1 Answer 1

6
$\begingroup$

MovingMap is doing, what it is supposed to do.
Evaluating

AbsoluteTime /@ (Data[[1 ;; 5]][[All, 1]])

{3439843200, 3440102400, 3440188800, 3440275200, 3440361600}

gives the timestamps for the first five data points in absolute time.
The output of

MovingMap[foo[#] &, Data, 5]

or simpler

MovingMap[foo[#] &, Data[[1 ;; 5]], 5]
{{3440361600, 
  foo[{{902.99, 934.73, 899.35, 931.8, 4048270000}, 
       {929.17, 936.63, 919.53, 927.45, 5413910000}, 
       {931.17, 943.85, 927.28, 934.7, 5392620000}, 
       {927.45, 927.45, 902.37, 906.65, 4704940000}, 
       {905.73, 910., 896.81, 909.73, 4991550000}}]}}

shows that foo is applied to the values of the first five data points and gets combined with the timestamps of the fifth data point.


How to make a FinancialIndicator work within MovingMap

I didn't test all, but it seems like no FinancialIndicator is actually using the timestamps and I can't see a reason why any should. Therefore you only need to create the expected input structure.
For your example:

intraTotal[ts_] := 
 Total[FinancialIndicator["TrueRange"][Transpose[{ConstantArray[{}, Length@ts], ts}]]]

Now

MovingMap[intraTotal[#] &, data, 5]

will work as you had expected.

$\endgroup$
7
  • $\begingroup$ Yeah, that's it $\endgroup$ Mar 14, 2015 at 1:12
  • $\begingroup$ Okay, the documentation isn't clear on this then. You're right that it IS mentioned that it understands time series, but only much farther down the page. Passing in these naked OHLCV lists causes problems using FinancialIndicator within the functions. $\endgroup$
    – user4860
    Mar 14, 2015 at 1:30
  • $\begingroup$ @Steven Most FinancialIndicators have time frame as a parameter (most with a default value) and already do some kind of moving mapping. Therefore they don't seem to be build to work together with MovingMap. $\endgroup$
    – Karsten7
    Mar 14, 2015 at 2:54
  • $\begingroup$ I understand that, I'm using a FinancialIndicator inside of my own indicator which I'd be using MovingMap to calculate. So moving MovingMap is losing me information that FinancialIndicator needs. $\endgroup$
    – user4860
    Mar 14, 2015 at 3:56
  • $\begingroup$ @Steven To the end of my answer I added a way how you can make FinancialIndicator work together with MovingMap. Does this solve your problems? $\endgroup$
    – Karsten7
    Mar 20, 2015 at 8:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.