Put/Call Ratio (PCR) Indicator for ThinkorSwim

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.

@Playstation Read this information captioned above from @YungTraderFromMontana - his response helps newcomers understand.
 

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

@Playstation As an example, run that study on a daily chart of AMZN, the P/C Ratio is 7.05/1.
And on AAPL the P/C Ratio is 0.45/1. What are the odds? AMZN has bearish odds while AAPL has bullish odds
This of course does not mean you need to run off and buy/sell these stocks, but do monitor the P/C Ratio

Have fun!
 
@tomsk, First I would like to thanks for your contribution on this form. I have couple of question.
1. in Post #11 "All you got to do is to change the symbol of your preference in the UI. "instead of , is it way to pick automatically from main chart. :unsure:
2. Call/Put ratio value shows based on ATM , am i correct.?
3.Call/Put ration value calculated based on Weekly or Monthly chain.? or this will change based on our chart time frame.
 
Actually I was in the midst of modifying this study when @San posted his query. With the revised mods, you now no longer need to mess with input of ticker from the user interface.

Version 1.1 of the code will load the symbol from whatever chart you happen to be on, e.g. FB, TSLA, AMZN, etc
This study should best be viewed on a daily aggregation chart although it works on lower timeframe as well.
Since the market is closed, the results may not be consistent so you might like to run this during RTH.

The original author of the base script was Mobius, I essentially made some enhancements based on a contribution by another reader in this forum.

Here then is version 1.1 of the code.

Code:
# Put Call Ratio
# tomsk
# 11.16.2019

# V1.0 - 11.09.2019 - tomsk - Modified Mobius study to enable input of symbol from UI
# V1.1 - 11.16.2019 - tomsk - Fixed it to automatically load symbol from the chart

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 = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT)))
                    then PutVolume[1]
                    else volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT));
    def CallVolume = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.CALL)))
                     then CallVolume[1]
                     else volume(symbol = GetATMOption(GetSymbol(), 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 = GetSymbol()) / .5, 0) * .5;
AddLabel(1, "Strikes " + GetSymbol() + ": $" + 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 Code
 
@tomsk, Cool thanks for your quick response. . When time permit, Can you clarify below doubts.

2. Call/Put ratio value shows based on ATM , am i correct.?
3.Call/Put ratio value calculated based on Weekly or Monthly chain.? or this will change based on our chart time frame.
 
@San

If you examine the code, you can see that the P/C ratio lcertainly ooks at the ATM option. If in doubt check out the following snippet.

def PutVolume = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT)))
then PutVolume[1]
else volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT));
def CallVolume = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.CALL)))
then CallVolume[1]
else volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.CALL));

Regarding the second question, these days most options series are of the weekly variety
For a definitive answer, you'll need to ask Mobius (original code author) directly although I suspect it may very well work, but I can't be 100% certain.

Hope that helps
 
@tomsk The label looks like it works intraday and it shows different numbers compared to greater time frames. Are the intraday numbers accurate and do they represent what's going on at the moment during that intraday time frame? Sorry if it sounds redundant but just want to make sure.
 
@tomsk The label looks like it works intraday and it shows different numbers compared to greater time frames. Are the intraday numbers accurate and do they represent what's going on at the moment during that intraday time frame? Sorry if it sounds redundant but just want to make sure.
About as close as you're going to get. If you want to track things over a longer term, you can use the symbols $pcall, $pcnd, and $pcsp
 
Here is another version

Code:
# TS_PutCallLower
# http://www.thinkscripter.com
# [email protected]
# Last Update 26 JAN 2015
declare lower;
input period = 10;
input INDICATOR = { default "$PCALL" ,"$PCI" ,"$PCRL" ,"$PCSP","$PCND" };
input type =ChartType.CANDLE;
AddChart(high = high(INDICATOR), low = low(INDICATOR), open = open(INDICATOR), close = close(INDICATOR), type = type , growColor = color.green, fallColor = color.white, neutralColor = color.white);
plot PCAve = average(close(INDICATOR), period);
PCAve.setDefaultColor(color.magenta);
#plot scalingHigh = highestAll(high(INDICATOR));
#plot scalingLow = lowestAll(low(INDICATOR));
#scalingHigh.setDefaultColor(color.green);
#scalingLow.setDefaultColor(color.red);
 
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
THIS IS REALLY WONDERFUL!!! This is calculating monthly expiry, I was wondering if you could easily have it do the same for the next expiry...spy a couple of days.. stocks most weekly now but some still only monthly. the label could say expiry date.
thanks so much for your reply.
As it is it is quite helpful, think this could make it even more valueable. I'm not much of a coder but have modified some much simpler scripts, this one is waaay above my level/paygrade at 75 yrs old. LOL
thanks,
Jim
 
THIS IS REALLY WONDERFUL!!! This is calculating monthly expiry, I was wondering if you could easily have it do the same for the next expiry...spy a couple of days.. stocks most weekly now but some still only monthly. the label could say expiry date.
thanks so much for your reply.
As it is it is quite helpful, think this could make it even more valueable. I'm not much of a coder but have modified some much simpler scripts, this one is waaay above my level/paygrade at 75 yrs old. LOL
thanks,
Jim
That would be a significant undertaking and is not currently available :(
 
Thanks so much for sharing this. I have a question about how the Neutral line is meant to be interpreted.

PROG has been squeezing lately. When we look at PROG with this indicator on a 6H chart, we see this:

0chJHTU.png


The portion of the code relevant to my question is this:

Code:
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);

Why is the Neutral line at the value of "1" when this causes the "ChangeRatio" to paint a bearish color while the stock has run 100% over the last week? I mean, what is the logic behind using "1" for the Neutral line? And how should the Average Change Ratio ("AvgCR") line be interpreted in relationship to the ChangeRatio line? I guess I really don't understand how the indicator is meant to be interpreted. Naively, I would have expected that the plot would be bullish (i.e. the ChangeRatio line would be green instead of red) if the stock makes a 100% run up.
 
Thanks so much for sharing this. I have a question about how the Neutral line is meant to be interpreted.

PROG has been squeezing lately. When we look at PROG with this indicator on a 6H chart, we see this:

The portion of the code relevant to my question is this:

Code:
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);

Why is the Neutral line at the value of "1" when this causes the "ChangeRatio" to paint a bearish color while the stock has run 100% over the last week? I mean, what is the logic behind using "1" for the Neutral line? And how should the Average Change Ratio ("AvgCR") line be interpreted in relationship to the ChangeRatio line? I guess I really don't understand how the indicator is meant to be interpreted. Naively, I would have expected that the plot would be bullish (i.e. the ChangeRatio line would be green instead of red) if the stock makes a 100% run up.
It works on the daily chart
 
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);
can it be done automatically when selecting any symbol? Thanks!
 
So this looks at the NEXT WEEK expiration ratio?
Versus the TOS display in the "Todays's Options Statistics" window that shows for ALL dates?
 
Last edited:
So this looks at the NEXT WEEK experation ratio? Versus the CURRENT DAY ratio that TOS displays in the "Todays's Options Statistics" window.
@San

If you examine the code, you can see that the P/C ratio lcertainly ooks at the ATM option. If in doubt check out the following snippet.

def PutVolume = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT)))
then PutVolume[1]
else volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.PUT));
def CallVolume = if isNaN(volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.CALL)))
then CallVolume[1]
else volume(symbol = GetATMOption(GetSymbol(), date, OptionClass.CALL));

Regarding the second question, these days most options series are of the weekly variety
For a definitive answer, you'll need to ask Mobius (original code author) directly although I suspect it may very well work, but I can't be 100% certain.

Hope that helps
Yep
 
Hi, I was wondering if there is any way to take the top 3 weekly calls and top 3 weekly puts based on open interest and automatically have those levels plotted on the chart.
 
Thread starter Similar threads Forum Replies Date
chewie76 HOT ZONE - RSI with IV Percentile: Buy Stock or Sell Put Options Signal For ThinkOrSwim Indicators 106

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
403 Online
Create Post

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