Fourier Analysis Decomposition & RMS Energy For ThinkOrSwim

mashume

Expert
VIP
Lifetime

FOURIER TRANSFORM RMS ENERGY

link: http://tos.mx/1Wkl4Ht
DESCRIPTION
This indicator is an attempt to look at the energy present in the market's price action by looking at the RMS (root mean squared) energy shared between four harmonic fourier transformations of the CLOSE price series.

It does this by calculating the Fourier transform approximation of the 1st harmonic (the length parameter defines half a wavelength, so that the default value of 64 is actually looking at a wave 128 bars in length) along with the 3rd, 5th, and 7th harmonics. The RMS energy in these waves is then calculated for lengths of L, L/2, L/4, and L/6. These lengths are shown as vertical dashed lines on the chart for ease of reference. The RMS energy of the four waves is summed, and the portion of that energy possessed by each of the waves is plotted.

In keeping with my love of physics, the longest wavelengths are red, followed by orange, green, and the shortest is blue. This is really the only way the colors make any sense to my poor head.

USAGE
when reading this indicator, note when the red line has the highest position. That indicates that the long-term wave (1st harmonic) has the bulk of the energy in the Fourier decomposition. Conversely if the blue line has the greatest value, the price movements have generally been short term but dramatic. If either of the other lines, orange or green are showing energy, fluctuations in the middle are more likely.

I use this to determine whether I should expect to be in a trade for a short time (measured in bars) or a long time.


Code:
####################################################
#
#  FOURIER TRANSFORM DECOMPOSITION
#  RMS ENERGY FOR 1st, 3rd, 5th, and 7th Harmonics
#
#  A guage of market instability and flutter
#
#  by mashume for the usethinkscript.com community
#
#  2022.03.28
#
#  Released the MIT License as open source
#  (c) mashume 2022
#
####################################################

declare lower;
declare once_per_bar;

def pi = Double.Pi;
input n = 64;

script ReX_k {
    input k = 0;
    input n = 64;
    def return_value = fold i = 0 to n - 1 with value = 0 do value + close[i] * Cos(2 * Double.Pi * k * i / n);
    plot ReX_k = return_value;
};

script ImX_k {
    input k = 0;
    input n = 64;
    def return_value = fold j = 0 to n - 1 with value = 0 do value + close[j] * Sin(2 * Double.Pi * k * j / n);
    plot ImX_k = -return_value;
};

script ReX {
    input k = 0;
    input n = 64;
    def return_value =
        if (k != 0 and k != (n / 2))
            then 2 * ReX_k(k, n) / n
        else if k == 0
            then ReX_k(k, n) / n
        else if k == n / 2
            then ReX_k(k, n) / n
        else 0;
    plot ReX = return_value;
};

script ImX {
    input k = 0;
    input n = 64;
    plot ImX_value = -2 * ImX_k(k, n) / n;
};

script x {
    input i = 1;
    input k = 0;
    input n = 64;
    def sum1 = fold a = 0 to n / 2 with value = 0.0 do value + ReX(k, n) * Cos(2 * Double.Pi * k * (n - a) / n);
    def sum2 = fold b = 0 to n / 2 with value2 = 0.0 do value2 + ImX(k, n) * Sin(2 * Double.Pi * k * (n - b)/ n);
    plot x = sum1;
};

def curve_1 = x(i = 0, k = 1, n = n);
def curve_2 = x(i = 0, k = 3, n = n);
def curve_3 = x(i = 0, k = 5, n = n);
def curve_4 = x(i = 0, k = 7, n = n);

def d = 2 * n;

def c1_mean = Average(curve_1, d);
def c1_rms = sqrt(fold i1 = 0 to d with ms1 = 0 do ms1 + sqr(curve_1[i1] - c1_mean));

def c2_mean = Average(curve_2, floor(d / 2));
def c2_rms = sqrt(fold i2 = 0 to floor(d / 2) with ms2 = 0 do ms2 + sqr(curve_2[i2] - c2_mean));

def c3_mean = Average(curve_3, floor(d / 4));
def c3_rms = sqrt(fold i3 = 0 to floor(d / 4) with ms3 = 0 do ms3 + sqr(curve_3[i3] - c3_mean));

def c4_mean = Average(curve_4, floor(d / 6));
def c4_rms = sqrt(fold i4 = 0 to floor(d / 6) with ms4 = 0 do ms4 + sqr(curve_4[i4] - c4_mean));

def bar = barNumber();
AddVerticalLine(visible = bar == highestAll(bar) - d, "2n", color.red);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 2), 0), "2n / 3", color.orange);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 4), 0), "2n / 4", color.green);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 6), 0), "2n / 6", color.cyan);

def dist_sum = c1_rms + c2_rms * 4 + c3_rms * 8 + c4_rms * 16;

plot FirstHarmonicPercent = c1_rms / dist_sum;
plot ThirdHarmonicPercent = (c2_rms / dist_sum) * 4;
plot FifthHarmonicPercent = (c3_rms / dist_sum) * 8;
plot SeventhHarmonicPercent = (c4_rms / dist_sum) * 16;

FirstHarmonicPercent.setDefaultColor(color.red);
ThirdHarmonicPercent.setDefaultColor(color.orange);
FifthHarmonicPercent.setDefaultColor(color.green);
SeventhHarmonicPercent.setDefaultColor(color.cyan);



EYE CANDY AND DESCRIPTION

This is not investment advice.
npSPztw.png



Several new indicators are included in this screen shot. But I'm lazy and only did one write up. You can find the other threads somewhere on usethinkscript.com


A
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a clear enter signal which lasts nicely through the bulk of the upward movement.

B
The PRICE ACTION within LINEAR REGRESSION CHANNEL indicator shows a squeeze and a bounce off the lower line which corresponds nicely with a move upward in the price chart.

C
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a good short signal, though the signal does not last as long as the downward trend.

D
Fourier RMS shows an increase in short term energy as a proportion of the total energy (the blue line rises and the red falls).

E
Fourier RMS shows a dramatic decrease in the short term (blue) line and a distinct rise in the long term (red).
 
Last edited:

FOURIER TRANSFORM RMS ENERGY

[link]http://tos.mx/1Wkl4Ht[/link]
DESCRIPTION
This indicator is an attempt to look at the energy present in the market's price action by looking at the RMS (root mean squared) energy shared between four harmonic fourier transformations of the CLOSE price series.

It does this by calculating the Fourier transform approximation of the 1st harmonic (the length parameter defines half a wavelength, so that the default value of 64 is actually looking at a wave 128 bars in length) along with the 3rd, 5th, and 7th harmonics. The RMS energy in these waves is then calculated for lengths of L, L/2, L/4, and L/6. These lengths are shown as vertical dashed lines on the chart for ease of reference. The RMS energy of the four waves is summed, and the portion of that energy possessed by each of the waves is plotted.

In keeping with my love of physics, the longest wavelengths are red, followed by orange, green, and the shortest is blue. This is really the only way the colors make any sense to my poor head.

USAGE
when reading this indicator, note when the red line has the highest position. That indicates that the long-term wave (1st harmonic) has the bulk of the energy in the Fourier decomposition. Conversely if the blue line has the greatest value, the price movements have generally been short term but dramatic. If either of the other lines, orange or green are showing energy, fluctuations in the middle are more likely.

I use this to determine whether I should expect to be in a trade for a short time (measured in bars) or a long time.


Code:
####################################################
#
#  FOURIER TRANSFORM DECOMPOSITION
#  RMS ENERGY FOR 1st, 3rd, 5th, and 7th Harmonics
#
#  A guage of market instability and flutter
#
#  by mashume for the usethinkscript.com community
#
#  2022.03.28
#
#  Released the MIT License as open source
#  (c) mashume 2022
#
####################################################

declare lower;
declare once_per_bar;

def pi = Double.Pi;
input n = 64;

script ReX_k {
    input k = 0;
    input n = 64;
    def return_value = fold i = 0 to n - 1 with value = 0 do value + close[i] * Cos(2 * pi * k * i / n);
    plot ReX_k = return_value;
};

script ImX_k {
    input k = 0;
    input n = 64;
    def return_value = fold j = 0 to n - 1 with value = 0 do value + close[j] * Sin(2 * pi * k * j / n);
    plot ImX_k = -return_value;
};

script ReX {
    input k = 0;
    input n = 64;
    def return_value =
        if (k != 0 and k != (n / 2))
            then 2 * ReX_k(k, n) / n
        else if k == 0
            then ReX_k(k, n) / n
        else if k == n / 2
            then ReX_k(k, n) / n
        else 0;
    plot ReX = return_value;
};

script ImX {
    input k = 0;
    input n = 64;
    plot ImX_value = -2 * ImX_k(k, n) / n;
};

script x {
    input i = 1;
    input k = 0;
    input n = 64;
    def sum1 = fold a = 0 to n / 2 with value = 0.0 do value + ReX(k, n) * Cos(2 * pi * k * (n - a) / n);
    def sum2 = fold b = 0 to n / 2 with value2 = 0.0 do value2 + ImX(k, n) * Sin(2 * pi * k * (n - b)/ n);
    plot x = sum1;
};

def curve_1 = x(i = 0, k = 1, n = n);
def curve_2 = x(i = 0, k = 3, n = n);
def curve_3 = x(i = 0, k = 5, n = n);
def curve_4 = x(i = 0, k = 7, n = n);

def d = 2 * n;

def c1_mean = Average(curve_1, d);
def c1_rms = sqrt(fold i1 = 0 to d with ms1 = 0 do ms1 + sqr(curve_1[i1] - c1_mean));

def c2_mean = Average(curve_2, floor(d / 2));
def c2_rms = sqrt(fold i2 = 0 to floor(d / 2) with ms2 = 0 do ms2 + sqr(curve_2[i2] - c2_mean));

def c3_mean = Average(curve_3, floor(d / 4));
def c3_rms = sqrt(fold i3 = 0 to floor(d / 4) with ms3 = 0 do ms3 + sqr(curve_3[i3] - c3_mean));

def c4_mean = Average(curve_4, floor(d / 6));
def c4_rms = sqrt(fold i4 = 0 to floor(d / 6) with ms4 = 0 do ms4 + sqr(curve_4[i4] - c4_mean));

def bar = barNumber();
AddVerticalLine(visible = bar == highestAll(bar) - d, "2n", color.red);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 2), 0), "2n / 3", color.orange);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 4), 0), "2n / 4", color.green);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 6), 0), "2n / 6", color.cyan);

def dist_sum = c1_rms + c2_rms * 4 + c3_rms * 8 + c4_rms * 16;

plot FirstHarmonicPercent = c1_rms / dist_sum;
plot ThirdHarmonicPercent = (c2_rms / dist_sum) * 4;
plot FifthHarmonicPercent = (c3_rms / dist_sum) * 8;
plot SeventhHarmonicPercent = (c4_rms / dist_sum) * 16;

FirstHarmonicPercent.setDefaultColor(color.red);
ThirdHarmonicPercent.setDefaultColor(color.orange);
FifthHarmonicPercent.setDefaultColor(color.green);
SeventhHarmonicPercent.setDefaultColor(color.cyan);



EYE CANDY AND DESCRIPTION

This is not investment advice.
npSPztw.png



Several new indicators are included in this screen shot. But I'm lazy and only did one write up. You can find the other threads somewhere on usethinkscript.com


A
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a clear enter signal which lasts nicely through the bulk of the upward movement.

B
The PRICE ACTION within LINEAR REGRESSION CHANNEL indicator shows a squeeze and a bounce off the lower line which corresponds nicely with a move upward in the price chart.

C
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a good short signal, though the signal does not last as long as the downward trend.

D
Fourier RMS shows an increase in short term energy as a proportion of the total energy (the blue line rises and the red falls).

E
Fourier RMS shows a dramatic decrease in the short term (blue) line and a distinct rise in the long term (red).
@mashume great job putting this system together. can you please share this chart above for us? if you can awesome if you cant its okay. i just saw a great arrow signal on the chart. keep up the good job and thank you an advance
 
@mashume great job putting this system together. can you please share this chart above for us? if you can awesome if you cant its okay. i just saw a great arrow signal on the chart. keep up the good job and thank you an advance
Those arrows are another thing I've been working on. I may release it a bit later on. 🙃 The signals look pretty good so far, and the trade targets are getting solid, but I've been thinking about a way to make them more generalizable. They are best on tick charts for futures so far.

-mashume
 
I love this system, but this code isn't working in TOS. The other two work well.
Well, for whatever reason, my declaration of
Code:
def pi = Double.pi;
doesn't work as intended.

I've update the code above, but not the link script...
please replace any instances of "pi" with "Double.pi" in the code and it will run just fine.

The most frustrating kind of bug. The kind that look right and aren't.

Thank you for pointing out that it wasn't running. Should now.

-mashume
 
May be pointed into various scanned stocks. Great higher level math here. Will kill.

Analysis; tighten some parameters, adjust sequence, and color it up.

Linear Squeeze: link

Linear Squeeze: Run to resistance sample

This chart is an example of a short. Channel tightens from week and half past, eventual PPS drops Thursday, run Friday with bounce!

Indicator changes:
VWAP to move from simple price to more indicative of a trend following,
Narrow the channel (70) throw off the quick and quadrillion false sell/buys,
full range to see over the mountains and prairies,
and length (20), for shorter turn back-around to see who's chasing as you run again
 
Last edited:
Well, for whatever reason, my declaration of
Code:
def pi = Double.pi;
doesn't work as intended.

I've update the code above, but not the link script...
please replace any instances of "pi" with "Double.pi" in the code and it will run just fine.

The most frustrating kind of bug. The kind that look right and aren't.

Thank you for pointing out that it wasn't running. Should now.

-mashume
Reference the last Line Squeeze chart, is it possible to have the yellow line from the bottom indicator overlay the second chart? I like the slow trend, so that any cross over the blue line looked like leading indicator to me
 
Reference the last Line Squeeze chart, is it possible to have the yellow line from the bottom indicator overlay the second chart? I like the slow trend, so that any cross over the blue line looked like leading indicator to me
That might get a bit complicated. The Fourier code is pretty lengthy already. It might be possible, but scaling becomes an issue as all four lines in the Fourier indicator sum to 1 (so that each is necessarily less than 1) and the others are scaled to whatever the width of the linear regression channel is and so are dependent on price / value of the asset being charted. I'm sure there is some way to do it, but I can't think of a nice one at the moment.

-mashume
 

FOURIER TRANSFORM RMS ENERGY

link: http://tos.mx/1Wkl4Ht
DESCRIPTION
This indicator is an attempt to look at the energy present in the market's price action by looking at the RMS (root mean squared) energy shared between four harmonic fourier transformations of the CLOSE price series.

It does this by calculating the Fourier transform approximation of the 1st harmonic (the length parameter defines half a wavelength, so that the default value of 64 is actually looking at a wave 128 bars in length) along with the 3rd, 5th, and 7th harmonics. The RMS energy in these waves is then calculated for lengths of L, L/2, L/4, and L/6. These lengths are shown as vertical dashed lines on the chart for ease of reference. The RMS energy of the four waves is summed, and the portion of that energy possessed by each of the waves is plotted.

In keeping with my love of physics, the longest wavelengths are red, followed by orange, green, and the shortest is blue. This is really the only way the colors make any sense to my poor head.

USAGE
when reading this indicator, note when the red line has the highest position. That indicates that the long-term wave (1st harmonic) has the bulk of the energy in the Fourier decomposition. Conversely if the blue line has the greatest value, the price movements have generally been short term but dramatic. If either of the other lines, orange or green are showing energy, fluctuations in the middle are more likely.

I use this to determine whether I should expect to be in a trade for a short time (measured in bars) or a long time.


Code:
####################################################
#
#  FOURIER TRANSFORM DECOMPOSITION
#  RMS ENERGY FOR 1st, 3rd, 5th, and 7th Harmonics
#
#  A guage of market instability and flutter
#
#  by mashume for the usethinkscript.com community
#
#  2022.03.28
#
#  Released the MIT License as open source
#  (c) mashume 2022
#
####################################################

declare lower;
declare once_per_bar;

def pi = Double.Pi;
input n = 64;

script ReX_k {
    input k = 0;
    input n = 64;
    def return_value = fold i = 0 to n - 1 with value = 0 do value + close[i] * Cos(2 * Double.Pi * k * i / n);
    plot ReX_k = return_value;
};

script ImX_k {
    input k = 0;
    input n = 64;
    def return_value = fold j = 0 to n - 1 with value = 0 do value + close[j] * Sin(2 * Double.Pi * k * j / n);
    plot ImX_k = -return_value;
};

script ReX {
    input k = 0;
    input n = 64;
    def return_value =
        if (k != 0 and k != (n / 2))
            then 2 * ReX_k(k, n) / n
        else if k == 0
            then ReX_k(k, n) / n
        else if k == n / 2
            then ReX_k(k, n) / n
        else 0;
    plot ReX = return_value;
};

script ImX {
    input k = 0;
    input n = 64;
    plot ImX_value = -2 * ImX_k(k, n) / n;
};

script x {
    input i = 1;
    input k = 0;
    input n = 64;
    def sum1 = fold a = 0 to n / 2 with value = 0.0 do value + ReX(k, n) * Cos(2 * Double.Pi * k * (n - a) / n);
    def sum2 = fold b = 0 to n / 2 with value2 = 0.0 do value2 + ImX(k, n) * Sin(2 * Double.Pi * k * (n - b)/ n);
    plot x = sum1;
};

def curve_1 = x(i = 0, k = 1, n = n);
def curve_2 = x(i = 0, k = 3, n = n);
def curve_3 = x(i = 0, k = 5, n = n);
def curve_4 = x(i = 0, k = 7, n = n);

def d = 2 * n;

def c1_mean = Average(curve_1, d);
def c1_rms = sqrt(fold i1 = 0 to d with ms1 = 0 do ms1 + sqr(curve_1[i1] - c1_mean));

def c2_mean = Average(curve_2, floor(d / 2));
def c2_rms = sqrt(fold i2 = 0 to floor(d / 2) with ms2 = 0 do ms2 + sqr(curve_2[i2] - c2_mean));

def c3_mean = Average(curve_3, floor(d / 4));
def c3_rms = sqrt(fold i3 = 0 to floor(d / 4) with ms3 = 0 do ms3 + sqr(curve_3[i3] - c3_mean));

def c4_mean = Average(curve_4, floor(d / 6));
def c4_rms = sqrt(fold i4 = 0 to floor(d / 6) with ms4 = 0 do ms4 + sqr(curve_4[i4] - c4_mean));

def bar = barNumber();
AddVerticalLine(visible = bar == highestAll(bar) - d, "2n", color.red);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 2), 0), "2n / 3", color.orange);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 4), 0), "2n / 4", color.green);
AddVerticalLine(visible = bar == round(highestAll(bar) - (d / 6), 0), "2n / 6", color.cyan);

def dist_sum = c1_rms + c2_rms * 4 + c3_rms * 8 + c4_rms * 16;

plot FirstHarmonicPercent = c1_rms / dist_sum;
plot ThirdHarmonicPercent = (c2_rms / dist_sum) * 4;
plot FifthHarmonicPercent = (c3_rms / dist_sum) * 8;
plot SeventhHarmonicPercent = (c4_rms / dist_sum) * 16;

FirstHarmonicPercent.setDefaultColor(color.red);
ThirdHarmonicPercent.setDefaultColor(color.orange);
FifthHarmonicPercent.setDefaultColor(color.green);
SeventhHarmonicPercent.setDefaultColor(color.cyan);



EYE CANDY AND DESCRIPTION

This is not investment advice.
npSPztw.png



Several new indicators are included in this screen shot. But I'm lazy and only did one write up. You can find the other threads somewhere on usethinkscript.com


A
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a clear enter signal which lasts nicely through the bulk of the upward movement.

B
The PRICE ACTION within LINEAR REGRESSION CHANNEL indicator shows a squeeze and a bounce off the lower line which corresponds nicely with a move upward in the price chart.

C
The LINEAR REGRESSION CENTERLINE EXCURSION indicator shows a good short signal, though the signal does not last as long as the downward trend.

D
Fourier RMS shows an increase in short term energy as a proportion of the total energy (the blue line rises and the red falls).

E
Fourier RMS shows a dramatic decrease in the short term (blue) line and a distinct rise in the long term (red).

Hi mashume, I'm a big fan of your Fourier RMS. However, I use a 1min chart for scalping and find that the signals work best on a 2min chart. I'm currently solving this by having the Fourier RMS set to a two minute period in a separate cell that is below my main 1min cell, but it's difficult to manage the time zoom frequently becoming de-synched. I looked at trying to make the Fourier RMS use a higher aggregation period on a lower period chart, but plugging "period=two_minutes" or the like into the subscripts doesn't seem to work, and since it uses subscripts I'm at a loss. Is it possible to make a "higher time frame on lower chart" version of this indicator?
 
Hi mashume, I'm a big fan of your Fourier RMS. However, I use a 1min chart for scalping and find that the signals work best on a 2min chart. I'm currently solving this by having the Fourier RMS set to a two minute period in a separate cell that is below my main 1min cell, but it's difficult to manage the time zoom frequently becoming de-synched. I looked at trying to make the Fourier RMS use a higher aggregation period on a lower period chart, but plugging "period=two_minutes" or the like into the subscripts doesn't seem to work, and since it uses subscripts I'm at a loss. Is it possible to make a "higher time frame on lower chart" version of this indicator?
I believe this should work:
Code:
####################################################
#
#  FOURIER TRANSFORM DECOMPOSITION
#  RMS ENERGY FOR 1st, 3rd, 5th, and 7th Harmonics
#
#  A guage of market instability and flutter
#
#  by mashume for the usethinkscript.com community
#
#  2022.03.28
#
#  Released the MIT License as open source
#  (c) mashume 2022
#
####################################################

declare lower;
declare once_per_bar;

def pi = Double.Pi;
input n = 64;


script ReX_k {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value = fold i = 0 to n - 1 with value = 0 do value + close(period = agg)[i] * Cos(2 * Double.Pi * k * i / n);
    plot ReX_k = return_value;
}
;

script ImX_k {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value = fold j = 0 to n - 1 with value = 0 do value + close(period = agg)[j] * Sin(2 * Double.Pi * k * j / n);
    plot ImX_k = -return_value;
}
;

script ReX {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value =
        if (k != 0 and k != (n / 2))
            then 2 * ReX_k(k, n, agg) / n
        else if k == 0
            then ReX_k(k, n, agg) / n
        else if k == n / 2
            then ReX_k(k, n, agg) / n
        else 0;
    plot ReX = return_value;
}
;

script ImX {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    plot ImX_value = -2 * ImX_k(k, n, agg) / n;
}
;

script x {
    input i = 1;
    input k = 0;
    input n = 64;

    def sum1 = fold a = 0 to n / 2 with value = 0.0 do value + ReX(k, n) * Cos(2 * Double.Pi * k * (n - a) / n);
    def sum2 = fold b = 0 to n / 2 with value2 = 0.0 do value2 + ImX(k, n) * Sin(2 * Double.Pi * k * (n - b) / n);
    plot x = sum1;
}
;

def curve_1 = x(i = 0, k = 1, n = n);
def curve_2 = x(i = 0, k = 3, n = n);
def curve_3 = x(i = 0, k = 5, n = n);
def curve_4 = x(i = 0, k = 7, n = n);

def d = 2 * n;

def c1_mean = Average(curve_1, d);
def c1_rms = Sqrt(fold i1 = 0 to d with ms1 = 0 do ms1 + Sqr(curve_1[i1] - c1_mean));

def c2_mean = Average(curve_2, Floor(d / 2));
def c2_rms = Sqrt(fold i2 = 0 to Floor(d / 2) with ms2 = 0 do ms2 + Sqr(curve_2[i2] - c2_mean));

def c3_mean = Average(curve_3, Floor(d / 4));
def c3_rms = Sqrt(fold i3 = 0 to Floor(d / 4) with ms3 = 0 do ms3 + Sqr(curve_3[i3] - c3_mean));

def c4_mean = Average(curve_4, Floor(d / 6));
def c4_rms = Sqrt(fold i4 = 0 to Floor(d / 6) with ms4 = 0 do ms4 + Sqr(curve_4[i4] - c4_mean));

def bar = if !IsNaN(close) then barNumber() else double.nan;
AddVerticalLine(visible = bar == HighestAll(bar) - d, "2n", Color.RED);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 2), 0), "2n / 3", Color.ORANGE);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 4), 0), "2n / 4", Color.GREEN);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 6), 0), "2n / 6", Color.CYAN);

def dist_sum = c1_rms + c2_rms * 4 + c3_rms * 8 + c4_rms * 16;

plot FirstHarmonicPercent = c1_rms / dist_sum;
plot ThirdHarmonicPercent = (c2_rms / dist_sum) * 4;
plot FifthHarmonicPercent = (c3_rms / dist_sum) * 8;
plot SeventhHarmonicPercent = (c4_rms / dist_sum) * 16;

FirstHarmonicPercent.SetDefaultColor(Color.RED);
ThirdHarmonicPercent.SetDefaultColor(Color.ORANGE);
FifthHarmonicPercent.SetDefaultColor(Color.GREEN);
SeventhHarmonicPercent.SetDefaultColor(Color.CYAN);

Notes:
  • You may have to double the length of the indicator( value of n ) to make it look like you expect.
  • The value for 2m is hard coded in the script. I couldn't easily get it to work as an input to the functions.
  • You should compare values to a 2m chart for a while to see if it is behaving as you have come to know it should.

Thanks for the input and feedback. Nice to see people using some of the things I dream up and code.

-mashume
 
Last edited:
I believe this should work:
Code:
####################################################
#
#  FOURIER TRANSFORM DECOMPOSITION
#  RMS ENERGY FOR 1st, 3rd, 5th, and 7th Harmonics
#
#  A guage of market instability and flutter
#
#  by mashume for the usethinkscript.com community
#
#  2022.03.28
#
#  Released the MIT License as open source
#  (c) mashume 2022
#
####################################################

declare lower;
declare once_per_bar;

def pi = Double.Pi;
input n = 64;


script ReX_k {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value = fold i = 0 to n - 1 with value = 0 do value + close(period = agg)[i] * Cos(2 * Double.Pi * k * i / n);
    plot ReX_k = return_value;
}
;

script ImX_k {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value = fold j = 0 to n - 1 with value = 0 do value + close(period = agg)[j] * Sin(2 * Double.Pi * k * j / n);
    plot ImX_k = -return_value;
}
;

script ReX {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    def return_value =
        if (k != 0 and k != (n / 2))
            then 2 * ReX_k(k, n, agg) / n
        else if k == 0
            then ReX_k(k, n, agg) / n
        else if k == n / 2
            then ReX_k(k, n, agg) / n
        else 0;
    plot ReX = return_value;
}
;

script ImX {
    input k = 0;
    input n = 64;
    input agg = AggregationPeriod.TWO_MIN;
    plot ImX_value = -2 * ImX_k(k, n, agg) / n;
}
;

script x {
    input i = 1;
    input k = 0;
    input n = 64;

    def sum1 = fold a = 0 to n / 2 with value = 0.0 do value + ReX(k, n) * Cos(2 * Double.Pi * k * (n - a) / n);
    def sum2 = fold b = 0 to n / 2 with value2 = 0.0 do value2 + ImX(k, n) * Sin(2 * Double.Pi * k * (n - b) / n);
    plot x = sum1;
}
;

def curve_1 = x(i = 0, k = 1, n = n);
def curve_2 = x(i = 0, k = 3, n = n);
def curve_3 = x(i = 0, k = 5, n = n);
def curve_4 = x(i = 0, k = 7, n = n);

def d = 2 * n;

def c1_mean = Average(curve_1, d);
def c1_rms = Sqrt(fold i1 = 0 to d with ms1 = 0 do ms1 + Sqr(curve_1[i1] - c1_mean));

def c2_mean = Average(curve_2, Floor(d / 2));
def c2_rms = Sqrt(fold i2 = 0 to Floor(d / 2) with ms2 = 0 do ms2 + Sqr(curve_2[i2] - c2_mean));

def c3_mean = Average(curve_3, Floor(d / 4));
def c3_rms = Sqrt(fold i3 = 0 to Floor(d / 4) with ms3 = 0 do ms3 + Sqr(curve_3[i3] - c3_mean));

def c4_mean = Average(curve_4, Floor(d / 6));
def c4_rms = Sqrt(fold i4 = 0 to Floor(d / 6) with ms4 = 0 do ms4 + Sqr(curve_4[i4] - c4_mean));

def bar = BarNumber();
AddVerticalLine(visible = bar == HighestAll(bar) - d, "2n", Color.RED);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 2), 0), "2n / 3", Color.ORANGE);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 4), 0), "2n / 4", Color.GREEN);
AddVerticalLine(visible = bar == Round(HighestAll(bar) - (d / 6), 0), "2n / 6", Color.CYAN);

def dist_sum = c1_rms + c2_rms * 4 + c3_rms * 8 + c4_rms * 16;

plot FirstHarmonicPercent = c1_rms / dist_sum;
plot ThirdHarmonicPercent = (c2_rms / dist_sum) * 4;
plot FifthHarmonicPercent = (c3_rms / dist_sum) * 8;
plot SeventhHarmonicPercent = (c4_rms / dist_sum) * 16;

FirstHarmonicPercent.SetDefaultColor(Color.RED);
ThirdHarmonicPercent.SetDefaultColor(Color.ORANGE);
FifthHarmonicPercent.SetDefaultColor(Color.GREEN);
SeventhHarmonicPercent.SetDefaultColor(Color.CYAN);

Notes:
  • You may have to double the length of the indicator( value of n ) to make it look like you expect.
  • The value for 2m is hard coded in the script. I couldn't easily get it to work as an input to the functions.
  • You should compare values to a 2m chart for a while to see if it is behaving as you have come to know it should.

Thanks for the input and feedback. Nice to see people using some of the things I dream up and code.

-mashume

Thanks for your effort, and such a quick reply. Really appreciate it. I tried this new code (note that I changed the third and fifth wave colors) and to make sure that the same number of bars was being used, I did a bar count for each chart (1min period 2 days, and 2min period 2 days). On the 1min chart I used 114 bars to make the length to bar count ratio, for testing purposes, the same as the 2min chart with length set to 64.

The result interestingly has the vertical lines appearing in identical places, but the wave lines are very different. I've tried playing around with the settings further but I think it's clear that in some way the line plots are not being calculated the same. Do you have any ideas about how it's possible that the vertical lines are appearing identically but the wave line plots are not?

ADfeD5Y.png
 
Thanks for your effort, and such a quick reply. Really appreciate it. I tried this new code (note that I changed the third and fifth wave colors) and to make sure that the same number of bars was being used, I did a bar count for each chart (1min period 2 days, and 2min period 2 days). On the 1min chart I used 114 bars to make the length to bar count ratio, for testing purposes, the same as the 2min chart with length set to 64.

The result interestingly has the vertical lines appearing in identical places, but the wave lines are very different. I've tried playing around with the settings further but I think it's clear that in some way the line plots are not being calculated the same. Do you have any ideas about how it's possible that the vertical lines are appearing identically but the wave line plots are not?

ADfeD5Y.png
The secondary aggregation Version uses 2m data, but doesn't use twice as long a series. So the vertical lines will be the same places. If you set n for the 2m to be twice the value of n for your 1m chart, you will see the verticals twice as far out and the length of time the indicator will calculate over in bars will be the same... Maybe. It's a bit late and my brain is tired.

Mashume
 
The secondary aggregation Version uses 2m data, but doesn't use twice as long a series. So the vertical lines will be the same places. If you set n for the 2m to be twice the value of n for your 1m chart, you will see the verticals twice as far out and the length of time the indicator will calculate over in bars will be the same... Maybe. It's a bit late and my brain is tired.

Mashume

Ah OK. I kept trying, but I cannot get the plots of the original and the hard-coded 2M version to be very close, no matter what lengths I've tried. Intuitively this makes me think that the math is not working the same way. It's particularly apparent e.g. for the 1m TSLA chart if looking at the past two days - the original lines up beautifully with the price action waves that occurred whereas the 2M hard-coded version doesn't. So using the original in a separate cell is a better solution. I wasn't sure if it was a difficult modification to attempt when I asked. Again, really appreciate that you tried.
 
Mashume, following how I interpret and see use while in the 2 minute mode. (may be modify periods perhaps?).

First harmonic, Red line spikes 0.5, the big buyers are finished, reaction buying and selling, consolidation and distribution, weak bottoms, sellers dice up the cheese.

Nothing surprises more than sleepy sellers. Blue line moves to the beat. And BAM! Buyers! Blue line (blue line has the greatest value), crosses above Green (Squeezed panic sellers), & Green is above Yellow (the reactions buyers). Ideal when the lines are stacked Blue, Green, Yellow, Red, And the point where green cross above yellow

(disregard bottom study. just won't filter at lower intervals).



image
 
Mashume, following how I interpret and see use while in the 2 minute mode. (may be modify periods perhaps?).

First harmonic, Red line spikes 0.5, the big buyers are finished, reaction buying and selling, consolidation and distribution, weak bottoms, sellers dice up the cheese.

Nothing surprises more than sleepy sellers. Blue line moves to the beat. And BAM! Buyers! Blue line (blue line has the greatest value), crosses above Green (Squeezed panic sellers), & Green is above Yellow (the reactions buyers). Ideal when the lines are stacked Blue, Green, Yellow, Red, And the point where green cross above yellow

(disregard bottom study. just won't filter at lower intervals).



image
Interesting...

Thanks for the feedback on how you use this, It's really neat to see how other people use the ideas I try to code up.

-mashume
 
Today,a light sword was all this needed. Small but true effect, not cut too deep

Indicated yesterday after hours.
Yellow cross green @ 0800, news release too! Support at open. Red peak at 1130, and there they go dicing up the cheese.

Fast forward, 2:08 Harmonic change, but blue line harmonic runs strong, yellow harmonic line (reaction buys) crosses green to squeeze seller, and runs to the close


image
 
I noticed the vertical lines move depending on how much expansion space you have to the right of the chart. If you change the way you define bar to use the code below, then your vertical lines won't move as you grow your expansion space to the right of the chart. Line 85.

Code:
def bar = if !IsNaN(close) then barNumber() else double.nan;
 
Here's a nice run. Use of the DComp in the 2 min range will help monitor where the trade is going . beware if any crosses near. See red move up and it could be the bigger seller.

image link here
 
4-Day pennant, higher highs, higher lows. RMSFourDecomp possible continuation break-out. The colors are lining up with a strong second wave, perhaps a cross green over red, and the positioning yellow (reaction buyers) for support. Recall the Green wave - (short sells).
shared chart link: https://tos.mx/kAK38Nb
5v79Bix.png


#Post 15: Ideal lines stack Blue, Green, Yellow, Red, and the place green cross above yellow
#Not investment advice! Never. posted as to test indicator; however, many other variables may precede actual pps move
 
Last edited by a moderator:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
476 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top