Confirm trade of QQQ with stochastic of SPY

msammons

Member
If I am going long QQQ (based on moving average cross), I would like to confirm with a StochasticFull for SPY above 50.

How would I bring into the thinkscript strategy for trading QQQ the addition of StochasticFull for SPY?
 

msammons

Member
Code:
### Stochastic for current chart symbol (QQQ)

def x = ExpAverage(close, 28);
def s = StochasticFull(14,3,3);

### Stochastic for comparison symbol (SPY)

def SPYstoch = stochasticFull("SPY",14,3,3);

The last line (trying to reference SPY) gives an error. I do not see anything in https://usethinkscript.com/threads/reference-to-study-or-study-within-study.3558/post-42861 which explains how to bring in stochasticFull calculations for second symbol (here "SPY"). Did I miss something in the thread you suggest?
 

msammons

Member
While the answer turns out to be very simple, it seems difficult to get an answer here. For those wanting the answer:

In the thinkscript code on a QQQ chart, once you add:

Code:
input ticker = "SPY";     (or any second ticker symbol)

any calculations in thinkscript after that apparently will use the second ticker (here SPY).

For example:

Code:
### Stochastic for current chart symbol (QQQ)

def x = ExpAverage(close, 28);
def s = StochasticFull();

### Stochastic for comparison symbol (SPY)

input ticker = "SPY";

def x2 = ExpAverage(close, 28);
def s2 = StochasticFull();

Now you can use x, x2, s, and s2 in a single strategy.
 

Pensar

Well-known member
VIP
@msammons - Creating an input that takes a symbol does not automatically affect the code that is written after it. So coding like below only uses the current chart symbol's open/high/low/close, regardless whether or not a different symbol input is created -

Code:
#test code 1 - does NOT use the price of SPY, even though an input is created
input ticker = "SPY";
def h = high;
def l = low;
def c = close;
plot x2 = StochasticFull();

Instead, each pricetype needs to be separately assigned to the input ticker symbol. Once that it done, then use the defined pricetypes to replace the default pricetypes of the referenced indicator, as below -

Code:
#test code 2 - DOES use the price of SPY
input ticker = "SPY";
def h = high(ticker);
def l = low(ticker);
def c = close(ticker);
plot x2 = StochasticFull(priceH = h, priceL = l, priceC = c);

And to do the same with the exponential average -

Code:
#test code 3
input ticker = "SPY";
def c = close(ticker);
plot x2 = ExpAverage(c,28);

You can also do it another way, such as -

Code:
#test code 4
plot x2 = ExpAverage(close("SPY"),28);

Hopefully that will help you and anyone else that reads this. Also, to verify what is written above, you can easily create 4 separate new studies with the test codes above and visually compare the output by switching between QQQ and SPY.

Good trading to you! ;)
 
Last edited:

msammons

Member
Pensar: that was very very kind of you! Thank you!

... but I am not sure that is the correct formula for StochasticFull (aren't there three values inside the stochastic( ), kperiod, dperiod, and slowing? - not your high, low, close) - I think I can find the formula somewhere to calculate the StochasticFull value from back 14 (or however) many high, low, and closes are involved but ExpAverage(close("SPY"),28) looks right and is a big help.
 
Last edited:

Pensar

Well-known member
VIP
Pensar: that was very very kind of you! Thank you!

... but I am not sure that is the correct formula for StochasticFull (aren't there three values inside the stochastic( ), kperiod, dperiod, and slowing? - not your high, low, close) - I think I can find the formula somewhere to calculate the StochasticFull value from back 14 (or however) many high, low, and closes are involved but ExpAverage(close("SPY"),28) looks right and is a big help.

@msammons Referencing the StochasticFull() indicator with a simple set of "()" afterwards uses all the default settings and only displays the FullD plot. To change the default settings, you could change the values of the default inputs after placing them between the parentheses -
Code:
plot sf = StochasticFull(priceH = high, priceL = low, priceC = close, over_bought = 80, over_sold = 20, Kperiod = 10, Dperiod = 10, slowing_period = 3, averagetype = AverageType.SIMPLE);

To reference individual plots of the stochastic indicator rather than just the default "FullD" plot, the plot name can be added after the parentheses. For example -
Code:
plot x = StochasticFull().FullK;
plot y = StochasticFull().FullD;
plot os = StochasticFull().OverSold;
plot ob = StochasticFull().OverBought;

Another way is to right-click on the built-in StochasticFull study, duplicate it, and modify the code - then the inputs can be directly changed from the properties settings. Here is a duplicated StochasticFull study with a user adjustable symbol input -
Code:
# StochasticFull with user-adjustable symbol input

declare lower;

input symbol = "SPY";
input over_bought = 80;
input over_sold = 20;
input KPeriod = 10;
input DPeriod = 10;
input slowing_period = 3;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK & FullD"};

def priceH = high(symbol);  
def priceL = low(symbol);    
def priceC = close(symbol);  

def lowest_k = Lowest(priceL, KPeriod);
def c1 = priceC - lowest_k;
def c2 = Highest(priceH, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot FullK = MovingAverage(averageType, FastK, slowing_period);
plot FullD = MovingAverage(averageType, FullK, DPeriod);

plot OverBought = over_bought;
plot OverSold = over_sold;

def upK = FullK crosses above OverSold;
def upD = FullD crosses above OverSold;
def downK = FullK crosses below OverBought;
def downD = FullD crosses below OverBought;

plot UpSignal;
plot DownSignal;
switch (showBreakoutSignals) {
case "No":
    UpSignal = Double.NaN;
    DownSignal = Double.NaN;
case "On FullK":
    UpSignal = if upK then OverSold else Double.NaN;
    DownSignal = if downK then OverBought else Double.NaN;
case "On FullD":
    UpSignal = if upD then OverSold else Double.NaN;
    DownSignal = if downD then OverBought else Double.NaN;
case "On FullK & FullD":
    UpSignal = if upK or upD then OverSold else Double.NaN;
    DownSignal = if downK or downD then OverBought else Double.NaN;
}

UpSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");
DownSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");

FullK.SetDefaultColor(GetColor(5));
FullD.SetDefaultColor(GetColor(0));
OverBought.SetDefaultColor(GetColor(1));
OverSold.SetDefaultColor(GetColor(1));
UpSignal.SetDefaultColor(Color.UPTICK);
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
DownSignal.SetDefaultColor(Color.DOWNTICK);
DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

# End Code
 

msammons

Member
So to compare the current chart/symbol (QQQ) stochastic with the stochastic for a second symbol (SPY) the full code would be:

Code:
# Stochastic for current chart symbol

declare lower;

input symbol = "QQQ";
input over_bought = 80;
input over_sold = 20;
input KPeriod = 10;
input DPeriod = 10;
input slowing_period = 3;
input averageType = AverageType.SIMPLE;

def priceH = high(symbol);
def priceL = low(symbol);   
def priceC = close(symbol);

def lowest_k = Lowest(priceL, KPeriod);
def c1 = priceC - lowest_k;
def c2 = Highest(priceH, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot FullK = MovingAverage(averageType, FastK, slowing_period);
plot FullD = MovingAverage(averageType, FullK, DPeriod);

# Stochastic comparison for second symbol (not on chart)

input symbol2 = "SPY";
input over_bought2 = 80;
input over_sold2 = 20;
input KPeriod2 = 10;
input DPeriod2 = 10;
input slowing_period2 = 3;
input averageType2 = AverageType.SIMPLE;

def priceH2 = high(symbol2);
def priceL2 = low(symbol2);   
def priceC2 = close(symbol2);

def lowest_k2 = Lowest(priceL2, KPeriod2);
def c1.2 = priceC2 - lowest_k2;
def c2.2 = Highest(priceH2, KPeriod2) - lowest_k2;
def FastK2 = if c2.2 != 0 then c1.2 / c2.2 * 100 else 0;

plot FullK2 = MovingAverage(averageType2, FastK2, slowing_period2);
plot FullD2 = MovingAverage(averageType2, FullK2, DPeriod2);

Here I just added a "2" (or .2 after a number) to each input/def to distinguish between the chart symbol (QQQ) and the second symbol (SPY).

Is this correct?
 
Last edited:

Pensar

Well-known member
VIP
@msammons That looks good - a few things you may want to change are
1) the over_sold and over_bought inputs are not being used anywhere in the code, so they can be removed,
2) the thinkscript editor will not accept the defs "c1.2" and "c2.2" - remove the periods and it works great.
 

msammons

Member
Fantastic - I really appreciate the clarification.

I do a lot of pairs trading, and being able to compare symbols in a thinkorswim study or strategy opens up all kind of possibilities.

Again - thank you so much for taking the time to explain these concepts. I know it will help many others as well.
 

ahibbitts

New member
VIP
Wanted to find out if its possible to add a criteria to an indicator from another ticker? To explain I am working on and adding to an indicator that creates an up arrow when the stock moves above or below a MA. What I wanted to find out if possible to add confirmation like SPY and QQQ are ascending or descending to confirm before the arrows are drawn on the chart. I will paste the code I currently have thanks to rad14733. The idea would be with the code below that two candles close above my 9 Day MA, SPY is ascending, QQQ is also going up and maybe volume is more then last x amount of candles then it draws an Up Arrow or Down Arrow. I hope I explained enough.

Code:
#Plot Two Candle Fills Above MA
plot twoUp = close is greater than MovAvgExponential()."AvgExp" and close[1] is greater than MovAvgExponential()."AvgExp"[1] and close crosses above MovAvgExponential()."AvgExp" within 2 bars;
twoUp.SetPaintingStrategy(PaintingStrategy.Boolean_Arrow_Up);
twoUp.SetLineWeight(3);
twoUp.SetDefaultColor(Color.GREEN);

#Plot Two Candle Fills Below MA
plot twoDn = close is less than MovAvgExponential()."AvgExp" within 1 bar and close[1] is less than MovAvgExponential()."AvgExp"[1] and close crosses below MovAvgExponential()."AvgExp"  within 2 bars;
twoDn.SetPaintingStrategy(PaintingStrategy.Boolean_Arrow_Down);
twoDn.SetLineWeight(3);
twoDn.SetDefaultColor(Color.RED);

# Alerts
Alert(twoUp, " ", Alert.Bar, Sound.Chimes);
Alert(twoDn, " ", Alert.Bar, Sound.Chimes);
 

Similar threads

Top