I’m no expert programmer, but I’m attempting to change the way in which some technical indicators are displayed in a financial charting package called TradeStation (not that the specific charting supplier is relevant).
Here is the problem: Most indicators are plotted around a Zero point, sometimes they oscillate close to this point and sometimes far away. I would like to change the way in which the indicators are plotted so that they oscillate around Zero much more. But here is the tricky part, I don’t wish to distort their shape too much; some change is fine and inevitable, but I still would like the indicators to be recognisable for what they originally were.
In the past I have tried many ways, one way was using a logarithmic type scale, but this was not successful as it made any oscillation that was at a very high value almost inconsequential- which is not the goal. The goal is to try to keep any one oscillation of the indicator almost the same, but change the placement of it so that its closer to Zero (centre). Or put another way; the goal is to make the indicators perform similar shaped oscillations, but the centre of these oscillations should be closer to Zero (the centre of the indicators scale).
Does anyone know of, or can think of a way that this can be done? Are there any algorithms that might help keep any price series oscillating more around a centre point without too much distortion to the original?
Any help on this would be greatly appreciated, thank you.
==UPDATE==
The pink line is the original oscillator, the black line I have drawn in. It crudely represents what my goal would be for this. The circled areas show where the drawn in line crosses Zero so that its Zero value is rou开发者_如何学Pythonghly in the center of the oscillation... But the overall shape of the oscillation remains recognizable compared to the original one, also there is less discrepancy in the highs and lows of each oscillation; i.e. they are more similar in value . I have tried adding several different Detrend functions to various indicators but I have found that this distorts the shape for too much.UPDATE 2
I have tried dividing reducing linearly the y axis by 50% and 80%, Unfortunately this seems to just act in the same was as a scale factor would? Is this correct? It does not seem to change the relationship between different oscillations. If you see my example plot, the drawn in black line has more stable high and low oscillations i.e they are more similar in value/size and this is the key goal.
Next, I am going to try to add a high pass filter to the plot to see what result that gives and if it is closer in any way to my goal.
As usual, feel free to post any comments as they are gratefully received.
Chris
UPDATE 3
I have also implemented a high pass filter to an indicator. This did not do the trick either. This also seems to act as a scale factor. What I am after essentially, is to make large oscillations smaller, and small oscillations larger. Bringing any indicator used into a more synchronised range- and do this while maintaining the basic properties of the indicator in question. A better way to describe it may be that I'm after a damping formula?
Does anyone have any other ideas, or things I should be trying?
If you want to do something tailor-made, you could for example filter the low frequency components of the Fourier transform.
Suppose we have the following signal:
Then we calculate the FFT, and keep only the higher frequency components. Let's say we disregard the first 1.5% of the components. The resulting Plot of the original signal and the resulting oscillating one is:
HTH!
Edit 2
This is what you can expect from a hi-pass filter as described above, adding an exponential damping, instead of just disposing the low frequency components.
Program in Mathematica (just in case):
centerOsc[x_] :=
Module[{list, n, fp, coef, s},
list = (Transpose@FinancialData[#, "Jan. 1, 2005"])[[2]] &@x;
n = Length@list;
fp = Transpose[{N[Range[n]]/n, list}];
coef = FourierDST[list, 1]/Sqrt[n/2];
coef = Table[N[coef[[i]] (1 - E^(-i/6))], {i, 1, Length@coef}];
s = IntegerPart[Length@coef/100]; s = 1;
{fp, {#,
Sum[coef[[r]]*Sin[Pi r #], {r, s, n - 1}]} & /@ (N[Range[n]]/
n)}];
l = {"GE", "GOOG", "IBM", "MSFT"} ;(*Real prices from*)
GraphicsGrid@
Partition[ListLinePlot[centerOsc[#],
Axes -> False, Frame -> True, PlotLabel -> #,
PlotRange -> {{0.1, .9}, Full},
Epilog -> Line[{{0, 0}, {1, 0}}]] & /@ l, 2]
Edit 2
Based on your last update, it seems that what you want can be achieved easier. Just see what you get by dividing reducing linearly the y axis by 50% and 80% (using your data, extracted from your plot):
and compare with your plot:
The first thing I suggest you do is too standardize all of the indicators to a mean of 0 and standard deviation of 1. This at least will center all of your indicators around 0.
http://en.wikipedia.org/wiki/Standard_score
-Ralph Winters
I've marked low frequency component of input/output signals in your example:
Seems really as @belisarius says what you want is - just do FFT on signal and remove low frequency parts. That is - you need high pass filter algorithm. BTW, high pass filter can be also implemented with 1D convolution and high-pass kernel. For example,- for 3 component kernel vector, high-pass kernel could be[-1; 3; -1]
. In my opinion high-pass filter implementation with convolution is easiest one. But usually implementation through FFT is fastest one in relation to cpu usage.
hth
精彩评论