Put/Call Ratio (PCR) Indicator for ThinkorSwim

fishstick1229

New member
VIP
I'm currently looking for Put-Call Ratio indicator for ThinkorSwim chart. I want to display the data to understand the current market condition.
 
Last edited:

BenTen

Administrative
Staff member
Staff
VIP
Lifetime
Try this one

Rich (BB code):
# Put Call Ratio
# Mobius
 
declare lower;
 
    def series = 1;
    def CurrentYear = GetYear();
    def CurrentMonth = GetMonth();
    def CurrentDOM = GetDayOfMonth(GetYYYYMMDD());
    def Day1DOW1 = GetDayOfWeek(CurrentYear * 10000 + CurrentMonth * 100 + 1);
    def FirstFridayDOM1 = if Day1DOW1 < 6
                          then 6 - Day1DOW1
                          else if Day1DOW1 == 6
                          then 7
                          else 6;
    def RollDOM = FirstFridayDOM1 + 14;
    def ExpMonth1 = if RollDOM > CurrentDOM
                    then CurrentMonth + series - 1
                    else CurrentMonth + series;
    def ExpMonth2 = if ExpMonth1 > 12
                    then ExpMonth1 - 12
                    else ExpMonth1;
    def ExpYear = if ExpMonth1 > 12
                  then CurrentYear + 1
                  else CurrentYear;
    def Day1DOW = GetDayOfWeek(ExpYear * 10000 + ExpMonth2 * 100 + 1);
    def FirstFridayDOM = if Day1DOW < 6
                         then 6 - Day1DOW
                         else if Day1DOW == 6
                         then 7
                         else 6;
    def ExpDOM = FirstFridayDOM + 14;
    def date = ExpYear * 10000 + ExpMonth2 * 100 + ExpDOM + 1;
    def PutVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.PUT)))
                        then PutVolume_SPY[1]
                        else volume(symbol = GetATMOption("SPY", date, OptionClass.PUT));
    def PutVolume_QQQ = if isNaN(volume(symbol = GetATMOption("QQQ", date, OptionClass.PUT)))
                        then PutVolume_QQQ[1]
                        else volume(symbol = GetATMOption("QQQ", date, OptionClass.PUT));
    def PutVolume_DIA = if isNaN(volume(symbol = GetATMOption("DIA", date, OptionClass.PUT)))
                        then PutVolume_DIA[1]
                        else volume(symbol = GetATMOption("DIA", date, OptionClass.PUT));;
    def CallVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.CALL)))
                         then CallVolume_SPY[1]
                         else volume(symbol = GetATMOption("SPY", date, OptionClass.CALL));
    def CallVolume_QQQ = if isNaN(volume(symbol = GetATMOption("QQQ", date, OptionClass.CALL)))
                         then CallVolume_QQQ[1]
                         else volume(symbol = GetATMOption("QQQ", date, OptionClass.CALL));
    def CallVolume_DIA = if isNaN(volume(symbol = GetATMOption("DIA", date, OptionClass.CALL)))
                         then CallVolume_DIA[1]
                         else volume(symbol = GetATMOption("DIA", date, OptionClass.CALL));
    def PutTotal = PutVolume_SPY + PutVolume_QQQ + PutVolume_DIA;
    def CallTotal = CallVolume_SPY + CallVolume_QQQ + CallVolume_DIA;
AddLabel(yes,(concat("Ex date: ",
              concat(ExpMonth2, 
              concat("/",
              concat(ExpDOM, 
              concat("/", 
              concat(AsPrice(ExpYear),""))))))), color.white);
   def Strike_SPY = Round(close(symbol = "SPY") / .5, 0) * .5;
   def Strike_QQQ = Round(close(symbol = "QQQ") / .5, 0) * .5;
   def Strike_DIA = Round(close(symbol = "DIA") / .5, 0) * .5;
AddLabel(1, "Strikes SPY: $" + Strike_SPY + " QQQ: $" + Strike_QQQ + " DIA: $" + Strike_DIA, Color.White);
AddLabel(yes, Concat("ATM Put/Call Ratio ", Round(PutTotal / CallTotal, 2)) + " / 1", Color.White);
   def PV = if IsNaN(PutTotal) 
            then PV[1] 
            else PutTotal;
   def CV = if IsNaN(CallTotal) 
            then CV[1] 
            else CallTotal;
 
plot ChangeRatio = if isNaN(close) then Double.NaN else PV / CV;
     ChangeRatio.AssignValueColor(if ChangeRatio > 1
                 then color.green
                 else color.red);
plot AvgCR = if isNaN(close) then Double.NaN else Average(ChangeRatio, 5);
     AvgCR.SetDefaultColor(Color.Yellow);
plot Neutral = if isNaN(close) then Double.NaN else 1;
     Neutral.SetDefaultColor(Color.Gray);
 
Last edited:

fishstick1229

New member
VIP
Really cool, thanks. Is there a way to update below line to dynamically select the current ticker symbol instead of the hard coded value of "SPY"?

Code:
def PutVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.PUT)))
 
Last edited:

markos

Well-known member
VIP
@fishstick1229 Look up GetSymbol in the manual. That might be of help!

My belief is that the study was created using those 3 tickers because they cover "The Market" as well as have volume.

 
Last edited:

markos

Well-known member
VIP
Really cool, thanks. Is there a way to update below line to dynamically select the current ticker symbol instead of the hard coded value of "SPY"?

def PutVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.PUT)))
I have seen several lying around. Please type the word UNIVERSE in the search box and look in there.
 

Bill

New member
2019 Donor
@fishstick1229 Were you able to get this to work for symbols other than indexes? I like that you can do this on Tradestation but I use TOS 99% of the time.
 

cherif

Member
Hi to all. Is there any way to create a label or an indicator that tracks pull/call ratio for any specific stock. I know that $PCALL can be shown on the chart. Thank you
 

drdarshil16

New member
2019 Donor
Code:
declare lower;



    def series = 1;



    def CurrentYear = GetYear();



    def CurrentMonth = GetMonth();



    def CurrentDOM = GetDayOfMonth(GetYYYYMMDD());



    def Day1DOW1 = GetDayOfWeek(CurrentYear * 10000 + CurrentMonth * 100 + 1);



    def FirstFridayDOM1 = if Day1DOW1 < 6



                          then 6 - Day1DOW1



                          else if Day1DOW1 == 6



                          then 7



                          else 6;



    def RollDOM = FirstFridayDOM1 + 14;



    def ExpMonth1 = if RollDOM > CurrentDOM



                    then CurrentMonth + series - 1



                    else CurrentMonth + series;



    def ExpMonth2 = if ExpMonth1 > 12



                    then ExpMonth1 - 12



                    else ExpMonth1;



    def ExpYear = if ExpMonth1 > 12



                  then CurrentYear + 1



                  else CurrentYear;



    def Day1DOW = GetDayOfWeek(ExpYear * 10000 + ExpMonth2 * 100 + 1);



    def FirstFridayDOM = if Day1DOW < 6



                         then 6 - Day1DOW



                         else if Day1DOW == 6



                         then 7



                         else 6;



    def ExpDOM = FirstFridayDOM + 14;



    def date = ExpYear * 10000 + ExpMonth2 * 100 + ExpDOM + 1;



    def PutVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.PUT)))



                        then PutVolume_SPY[1]



                        else volume(symbol = GetATMOption("SPY", date, OptionClass.PUT));



    def PutVolume_QQQ = if isNaN(volume(symbol = GetATMOption("QQQ", date, OptionClass.PUT)))



                        then PutVolume_QQQ[1]



                        else volume(symbol = GetATMOption("QQQ", date, OptionClass.PUT));



    def PutVolume_DIA = if isNaN(volume(symbol = GetATMOption("DIA", date, OptionClass.PUT)))



                        then PutVolume_DIA[1]



                        else volume(symbol = GetATMOption("DIA", date, OptionClass.PUT));;



    def CallVolume_SPY = if isNaN(volume(symbol = GetATMOption("SPY", date, OptionClass.CALL)))



                         then CallVolume_SPY[1]



                         else volume(symbol = GetATMOption("SPY", date, OptionClass.CALL));



    def CallVolume_QQQ = if isNaN(volume(symbol = GetATMOption("QQQ", date, OptionClass.CALL)))



                         then CallVolume_QQQ[1]



                         else volume(symbol = GetATMOption("QQQ", date, OptionClass.CALL));



    def CallVolume_DIA = if isNaN(volume(symbol = GetATMOption("DIA", date, OptionClass.CALL)))



                         then CallVolume_DIA[1]



                         else volume(symbol = GetATMOption("DIA", date, OptionClass.CALL));



    def PutTotal = PutVolume_SPY + PutVolume_QQQ + PutVolume_DIA;



    def CallTotal = CallVolume_SPY + CallVolume_QQQ + CallVolume_DIA;



AddLabel(yes,(concat("Ex date: ",



              concat(ExpMonth2,



              concat("/",



              concat(ExpDOM,



              concat("/",



              concat(AsPrice(ExpYear),""))))))), color.white);



   def Strike_SPY = Round(close(symbol = "SPY") / .5, 0) * .5;



   def Strike_QQQ = Round(close(symbol = "QQQ") / .5, 0) * .5;



   def Strike_DIA = Round(close(symbol = "DIA") / .5, 0) * .5;



AddLabel(1, "Strikes SPY: $" + Strike_SPY + " QQQ: $" + Strike_QQQ + " DIA: $" + Strike_DIA, Color.White);



AddLabel(yes, Concat("ATM Put/Call Ratio ", Round(PutTotal / CallTotal, 2)) + " / 1", Color.White);



   def PV = if IsNaN(PutTotal)



            then PV[1]



            else PutTotal;



   def CV = if IsNaN(CallTotal)



            then CV[1]



            else CallTotal;



plot ChangeRatio = if isNaN(close) then Double.NaN else PV / CV;



     ChangeRatio.AssignValueColor(if ChangeRatio > 1



                 then color.green



                 else color.red);



plot AvgCR = if isNaN(close) then Double.NaN else Average(ChangeRatio, 5);



     AvgCR.SetDefaultColor(Color.Yellow);



plot Neutral = if isNaN(close) then Double.NaN else 1;



     Neutral.SetDefaultColor(Color.Gray);
 
Last edited by a moderator:

drdarshil16

New member
2019 Donor
This one is for DIA, SPY QQQ etc, although if it can be modified to have input of particular stock..

AMZN specific:

Code:
declare lower;

    def series = 1;



    def CurrentYear = GetYear();



    def CurrentMonth = GetMonth();



    def CurrentDOM = GetDayOfMonth(GetYYYYMMDD());



    def Day1DOW1 = GetDayOfWeek(CurrentYear * 10000 + CurrentMonth * 100 + 1);



    def FirstFridayDOM1 = if Day1DOW1 < 6



                          then 6 - Day1DOW1



                          else if Day1DOW1 == 6



                          then 7



                          else 6;



    def RollDOM = FirstFridayDOM1 + 14;



    def ExpMonth1 = if RollDOM > CurrentDOM



                    then CurrentMonth + series - 1



                    else CurrentMonth + series;



    def ExpMonth2 = if ExpMonth1 > 12



                    then ExpMonth1 - 12



                    else ExpMonth1;



    def ExpYear = if ExpMonth1 > 12



                  then CurrentYear + 1



                  else CurrentYear;



    def Day1DOW = GetDayOfWeek(ExpYear * 10000 + ExpMonth2 * 100 + 1);



    def FirstFridayDOM = if Day1DOW < 6



                         then 6 - Day1DOW



                         else if Day1DOW == 6



                         then 7



                         else 6;



    def ExpDOM = FirstFridayDOM + 14;



    def date = ExpYear * 10000 + ExpMonth2 * 100 + ExpDOM + 1;



    def PutVolume_AMZN = if isNaN(volume(symbol = GetATMOption("AMZN", date, OptionClass.PUT)))



                        then PutVolume_AMZN[1]



                        else volume(symbol = GetATMOption("AMZN", date, OptionClass.PUT));





    def CallVolume_AMZN = if isNaN(volume(symbol = GetATMOption("AMZN", date, OptionClass.CALL)))



                         then CallVolume_AMZN[1]



                         else volume(symbol = GetATMOption("AMZN", date, OptionClass.CALL));





    def PutTotal = PutVolume_AMZN;



    def CallTotal = CallVolume_AMZN;



AddLabel(yes,(concat("Ex date: ",



              concat(ExpMonth2,



              concat("/",



              concat(ExpDOM,



              concat("/",



              concat(AsPrice(ExpYear),""))))))), color.white);



   def Strike_AMZN = Round(close(symbol = "AMZN") / .5, 0) * .5;



AddLabel(1, "Strikes AMZN: $" + Strike_AMZN, Color.White);



AddLabel(yes, Concat("ATM Put/Call Ratio ", Round(PutTotal / CallTotal, 2)) + " / 1", Color.White);



   def PV = if IsNaN(PutTotal)



            then PV[1]



            else PutTotal;



   def CV = if IsNaN(CallTotal)



            then CV[1]



            else CallTotal;







plot ChangeRatio = if isNaN(close) then Double.NaN else PV / CV;



     ChangeRatio.AssignValueColor(if ChangeRatio > 1



                 then color.green



                 else color.red);



plot AvgCR = if isNaN(close) then Double.NaN else Average(ChangeRatio, 5);



     AvgCR.SetDefaultColor(Color.Yellow);



plot Neutral = if isNaN(close) then Double.NaN else 1;



     Neutral.SetDefaultColor(Color.Gray);
 
Last edited by a moderator:

2sureshk

Member
How to use PUT CALL ratio? What can be determined ? Will it give any additional indication to buy or sell call/put

Thx
Suresh
 

YungTraderFromMontana

Well-known member
It can be used to get a general idea around where the market thinks a stock is headed, P/C ratio of 4 and plenty of people are betting on a stock going down. P/C ration of .05 and the market is very confident in that stock. It is also important to consider the option chain when making a predictions. Are most of these puts or calls being bought for a strike in the near term or farther out? This gives you an idea of the time frame of the expected move. But be warned it can be effective but is not the holy grail, these assumptions fail to account for things like hedging.
 

markos

Well-known member
VIP
@YungTraderFromMontana , That was a very good answer. Feel encouraged to keep answering where you feel appropriate. The more voices we have, the better the community! Don't think your answer may be wrong, if you're out of line or the answer is debatable, that's good. That way we all learn what we think we know. Markos
 
Last edited:

2sureshk

Member
Thank you , I am performing the validation and I have observed the same 7/1 ratio forAMZN 9-20-2019 7 am pst. Then amzn dropped 15 $ . Appreciate the input. Is it possible to show the current weekly on chart rather than 3 weeks away . If you point out the code line I will try to adjust
 
Last edited by a moderator:

markos

Well-known member
VIP
Can I just place ROKU instead of SPY into this?
Hey you! You've been out a bit lately. That's ok, just teasing. (Actually I say a lot of silly stuff 🤪 )
Take the code in post #4 and change all of the instances of "AMZN" to "ROKU", copy paste. That should be all.
 

tomsk

Well-known member
VIP
Folks, given the recent interest in this thread, rather than hardcode symbols into the study, I have modified the study to take an input ticker, e.g. AAPL, or FB, or GS, etc and it will display the info requested. All you got to do is to change the symbol of your preference in the UI. Hence from symbol to symbol, not much work is required other than changing the value of the input symbol in the user interface. Hope this helps

Code:
# Put/Call
# 11.9.2019

declare lower;
    input symbol = "AMZN";
    def series = 1;
    def CurrentYear = GetYear();
    def CurrentMonth = GetMonth();
    def CurrentDOM = GetDayOfMonth(GetYYYYMMDD());
    def Day1DOW1 = GetDayOfWeek(CurrentYear * 10000 + CurrentMonth * 100 + 1);
    def FirstFridayDOM1 = if Day1DOW1 < 6
                          then 6 - Day1DOW1
                          else if Day1DOW1 == 6
                          then 7
                          else 6;
    def RollDOM = FirstFridayDOM1 + 14;
    def ExpMonth1 = if RollDOM > CurrentDOM
                    then CurrentMonth + series - 1
                    else CurrentMonth + series;
    def ExpMonth2 = if ExpMonth1 > 12
                    then ExpMonth1 - 12
                    else ExpMonth1;
    def ExpYear = if ExpMonth1 > 12
                  then CurrentYear + 1
                  else CurrentYear;
    def Day1DOW = GetDayOfWeek(ExpYear * 10000 + ExpMonth2 * 100 + 1);
    def FirstFridayDOM = if Day1DOW < 6
                         then 6 - Day1DOW
                         else if Day1DOW == 6
                         then 7
                         else 6;
    def ExpDOM = FirstFridayDOM + 14;
    def date = ExpYear * 10000 + ExpMonth2 * 100 + ExpDOM + 1;
    def PutVolume = if isNaN(volume(symbol = GetATMOption(symbol, date, OptionClass.PUT)))
                    then PutVolume[1]
                    else volume(symbol = GetATMOption(symbol, date, OptionClass.PUT));
    def CallVolume = if isNaN(volume(symbol = GetATMOption(symbol, date, OptionClass.CALL)))
                     then CallVolume[1]
                     else volume(symbol = GetATMOption(symbol, date, OptionClass.CALL));
    def PutTotal = PutVolume;
    def CallTotal = CallVolume;
AddLabel(yes,(concat("Ex date: ",
              concat(ExpMonth2,
              concat("/",
              concat(ExpDOM,
              concat("/",
              concat(AsPrice(ExpYear),""))))))), color.white);
   def Strike = Round(close(symbol = symbol) / .5, 0) * .5;
AddLabel(1, "Strikes " + symbol + ": $" + Strike, Color.White);
AddLabel(yes, Concat("ATM Put/Call Ratio ", Round(PutTotal / CallTotal, 2)) + " / 1", Color.White);
   def PV = if IsNaN(PutTotal)
            then PV[1]
            else PutTotal;
   def CV = if IsNaN(CallTotal)
            then CV[1]
            else CallTotal;
plot ChangeRatio = if isNaN(close) then Double.NaN else PV / CV;
     ChangeRatio.AssignValueColor(if ChangeRatio > 1
                 then color.green
                 else color.red);
plot AvgCR = if isNaN(close) then Double.NaN else Average(ChangeRatio, 5);
     AvgCR.SetDefaultColor(Color.Yellow);
plot Neutral = if isNaN(close) then Double.NaN else 1;
     Neutral.SetDefaultColor(Color.Gray);
# End Study
 
Last edited:

Playstation

Active member
VIP
@tomsk Could I trouble you to explain how to use this indicator? I don't know how to interpret the code.
Sometimes on the chart, I see a huge spike upwards, Changeratio at 300, and AvgCR is at 60. What does this mean?
 

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.
Top