4
$\begingroup$

I am making a very basic stock simulation. I want ListLinePlot to color my stock viewer based on whether the price went up or down from the previous price. Here is what I have:

RemoveScheduledTask[ScheduledTasks[]];
price = 100;
time = 0;
nextPrice := price += 2Random[]-1;
nextTime := time += Random[];
data = Table[{nextTime, nextPrice},{i,1,1000}];
Dynamic@ListLinePlot[
    data,
    ImageSize->1000,
    PlotRange->{{time-525,time+25}},
    ColorFunction->Function[If[Last@data[[-2]]<Last@data[[-1]], Green, Red]]
]
RunScheduledTask[
    data = Rest[data];
    AppendTo[data,{nextTime,nextPrice}];,
    .1
];

Currently this code makes the graph all one color (not what I want). Does anyone know how to implement the functionality that I want? Also any general code improvements are very welcome (I feel like the way I am pushing/popping data is inefficient).

$\endgroup$
4
  • $\begingroup$ Have you looked at the various financial charting function such as TradingChart and InteractiveTradingChart? See the documentation. I can never bring myself to explore them further (just can't come up with any use for them), but they look close to what you want. $\endgroup$
    – Jens
    Jun 17, 2012 at 4:31
  • $\begingroup$ You seem to be generating a time series; you might want to look into Accumulate[]. $\endgroup$ Jun 17, 2012 at 4:32
  • $\begingroup$ @Jens I saw those functions, but they seem limited to "dates", I am thinking more along the lines of "microseconds". @J.M. I don't want to use Accumulate because I don't want to store all the data at once. Or perhaps I am misunderstanding how you think I should use it? $\endgroup$
    – nullUser
    Jun 17, 2012 at 4:39
  • $\begingroup$ Also, as long as I'm at it, any tips on how to make the graph less shaky looking? $\endgroup$
    – nullUser
    Jun 17, 2012 at 4:41

2 Answers 2

2
$\begingroup$

This small modification to your code

  • Seems to flicker less than your code
  • Doesn't make use of Scheduled Tasks
  • Stops when you click on the plot

price = 100;
 time = 0;
nextPrice := price += 2 Random[] - 1;
nextTime := time += Random[];
data = Table[{nextTime, nextPrice}, {i, 1, 1000}];
lastPriceChecked = price;
lastTimeChecked = time;
colorFunction[x_, y_] := 
  If[x == First[First[data]], lastPriceChecked = y;
   Return[Blue], If[y > lastPriceChecked, lastPriceChecked = y;
     Return[Green], lastPriceChecked = y;
     Return[Red]];];
cont = True;
DynamicModule[{}, 
 EventHandler[
  Dynamic@ListLinePlot[data, ImageSize -> 1000, 
    PlotRange -> {{time - 525, time + 25}}, 
    ColorFunction -> Function[{x, y}, colorFunction[x, y]], 
    AxesOrigin -> {time - 525, 100}], "MouseDown" :> (cont = False)]]
While[cont, (Pause[.1]; data = Rest[data];
   AppendTo[data, {nextTime, nextPrice}])];
$\endgroup$
1
$\begingroup$

I think I solved my own question, though there is almost certainly a "more proper" way to do it. Please post if you have a better way than this.

RemoveScheduledTask[ScheduledTasks[]];
price = 100;
time = 0;
nextPrice := price += 2 Random[] - 1;
nextTime := time += Random[];
data = Table[{nextTime, nextPrice}, {i, 1, 1000}];
lastPriceChecked = price;
lastTimeChecked = time;
colorFunction[x_, y_] := If[
   x == First[First[data]],
   lastPriceChecked = y;
   Return[Blue],
   If[
     y > lastPriceChecked,
     lastPriceChecked = y;
     Return[Green],
     lastPriceChecked = y;
     Return[Red]
     ];
   ];
Dynamic@ListLinePlot[data, ImageSize -> 1000, 
  PlotRange -> {{time - 525, time + 25}}, 
  ColorFunction -> Function[{x, y}, colorFunction[x, y]]]
RunScheduledTask[
  data = Rest[data];
  AppendTo[data, {nextTime, nextPrice}];
  , .1];
$\endgroup$

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.

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