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$
  • $\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 '12 at 4:31
  • $\begingroup$ You seem to be generating a time series; you might want to look into Accumulate[]. $\endgroup$ – J. M. will be back soon Jun 17 '12 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 '12 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 '12 at 4:41
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, privacy policy and cookie policy

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