Monday, July 22, 2013

thinkscript included: sdi_ivp - iv percentile in a chart label

i have been following tastytrade's usage of iv percentile but it is a little awkward to use. usually you have to go the trade tab then open up the option statistics and wait for all that to populate. i think i have a better solution - just put that number in a chart label and keep it handy on the chart. here's my solution:

sdi_ivp on netflix - not a trade recommendation
this is a short and sweet solution. there is just one caveat - if you change the aggregation period higher than day then the tos platform will complain and the chart label will disappear.

here's the code: (how to install)
release 1.3 description here.


################################
input period = AggregationPeriod.DAY ;
# sdi_ivp: Display Implied Volatility Percent Range as a label
#hint: Displays the Implied Volatility Percent Range (aka rank, aka pecentile) as a chart label and as a chart indicator. the chart indicator plots as color-coded dots along the chart high and indicates when the iv%r was high/mid/low in the past. the chart label shows the curent numerical value and has the same color coding as the indicator. sdi_ivp rev: 1.31 http://www.smallDogInvestor.com
# author: allen everhart
# date: 19jul2013
# revision 1.3.1 3/9/2014
#    a. eliminate use of takeValueColor which doesn't seem to be reliable.
# revision 1.3 3/2/2014
#    a. ivr indicator enhancement to show when the ivp was high/mid/low in the past
#    b. tie the label color to the ivr color
#    c. made label text an input parameter.
#    d. use double.POSITIVE_INFINITY AND double.NEGATIVE_INFINITY for gap filtering instead of +/-999999999 (just for code correctness)
# revision 1.2 9/18/2013
#    enhancement to permit user to select label color
# revision 1.1 9/13/2013
#    previously sdi_ivp printed N/A if there were gaps in the imp_volatility data. now gaps are ignored.
# copylefts reserved. This is free software. That means you are free
# to use or modify it for your own usage but not for resale.
# Help me get the word out about my blog by keeping this header
# in place.
declare upper;
#hint period: time period to use for aggregating implied volatility. sdi_ivp rev: 1.31 http://www.smallDogInvestor.com
input length =252 ;
#hint length: #bars used to determine the high/low range of implied volatility
input highPct = 50 ;
#hint highPct: threshold for changing ivr indicator to high color.
input lowPct = 50 ;
#hint lowPct: threshold for changing ivr indicator to low color. note: if lowPct >= highPct then midrange color is suppressed.
input ivprPlacement = {default chartHigh, chartLow};
#hint ivprPlacement: macro control of ivr indicator placement.
input ivprOffsetFactor = .02;
#hint ivprOffsetFactor: fine control of ivr indicator placement.
input labelText = "IV%R";
#hint labelText: default text means: implied volatility percent range.

def ivGapHi = if isnan(imp_volatility(period=period)) then double.POSITIVE_INFINITY else imp_volatility(period=period);
def ivGapLo = if isnan(imp_volatility(period=period)) then double.NEGATIVE_INFINITY else imp_volatility(period=period);
def periodHigh = highest( ivGapLo,length=length);
def periodLow = lowest( ivGapHi, length=length);
def ivRange = periodHigh - periodLow ;
def ivp = round( 100*(imp_volatility(period=period) - periodLow)/ivRange, 0);


plot ivpr;
switch(ivprPlacement) {
    case chartHigh:
        ivpr = if isnan(close) then double.NaN else highestAll(high)*(1+ivprOffsetFactor);
    case chartLow:
        ivpr= if isnan(close) then double.NaN else lowestAll(low)*(1-ivprOffsetFactor);
}
ivpr.defineColor("high", color.GREEN);
ivpr.defineColor("mid", color.YELLOW);
ivpr.defineColor("low", color.RED);
ivpr.setPaintingStrategy(paintingStrategy.POINTS);
ivpr.assignValueColor(
  if ivp>=highPct then ivpr.color("high")
  else if lowPct<highPct && ivp>lowPct then ivpr.color("mid")
  else ivpr.color("low")
);
ivpr.setLineWeight(2);
ivpr.hidebubble();
ivpr.hidetitle();
AddLabel(1, Concat(labelText,Concat(": ", ivp)),
  if ivp>=highPct then ivpr.color("high")
  else if lowPct<highPct && ivp>lowPct then ivpr.color("mid")
  else ivpr.color("low")
);
####################################
 


36 comments:

  1. Hi Allen,

    Great code, but could you provide some hints on how to add this to the charts in tos? I asked tastytrade, but they gave me directions to add it as a column under the MarketWatch tab (and there is actually already a column set up for that in the platform). I searched and searched the charts tab, and I can't find anywhere to add a custom box like that. Any pointers would be greatly appreciated.

    ReplyDelete
  2. I'll answer my own question, because it was a lot easier than I thought.

    1. Go to Charts tab
    2. Click on Studies button in upper right
    3. Click on New... button in lower right of the Edit box
    4. Click on "thinkScript Editor" tab
    5. Delete everything on the page (usually plot Data = close;)
    6. Paste the script (above)
    7. Enter the name you want (no spaces) at the top of the box next to Study Name
    8. Click "OK"
    9. Confirm that your new study is listed under "Studies on Upper Subgraph"
    10. Click "OK"

    ReplyDelete
  3. sorry, the New... button is in the lower left, not right. You'd think I'd have gotten that figured out by my age.

    ReplyDelete
  4. hi michael, thanks for your efforts to document the install instuctions here-now. your reward is that you get first crack at the 1.1 revision which fixes a problem with tos's data feed on imp_volatility. btw i do have instructions on how to do a copy 'n paste install on my 'how to' tab.
    best.
    -allen

    ReplyDelete
    Replies
    1. How do you get back into and edit a custom column to fix the imp_volatility data feed problem?

      Delete
    2. I have two different versions of the column code. Both do not match the output of the 1.1 code.

      def vol = impVolatility();
      def hi = highest(vol,252);
      def lo = lowest(vol,252);
      plot perct = (vol - lo)*100/ (hi - lo);

      and

      def ivol = if !IsNAN(imp_volatility) then imp_volatility else 0;
      def lowvol = lowest(ivol,252);
      def highvol = highest(ivol,252);
      def currentvol = imp_volatility;
      plot data = ((currentvol-lowvol)/(highvol-lowvol)*100);

      Can anyone fix them?

      Thanks

      Delete
    3. My colunm was displaying IV percentile for a few days but now it only shows "loading" all the time.

      Delete
    4. kevin.myhre@kmmhldg.com
      Yes, its irritating. Also the column code displays differently for PM platform to real platform and the real plat is the wrong one..

      Delete
    5. kevin.myhre@kmmhldg.com
      I solved the problem for the columns..

      IV% For Column
      input period = AggregationPeriod.DAY ; # time period to use for aggregating implied volatility
      input length = 252 ; # bars to use in implied volatility calculation
      def ivGapHi = if IsNaN(imp_volatility(period = period)) then 99999999999 else imp_volatility(period = period);
      def ivGapLo = if IsNaN(imp_volatility(period = period)) then -99999999999 else imp_volatility(period = period);
      def periodHigh = Highest( ivGapLo, length = length);
      def periodLow = Lowest( ivGapHi, length = length);
      def ivRange = periodHigh - periodLow ;
      def ivp = Round( 100 * (imp_volatility(period = period) - periodLow) / ivRange, 1);
      plot data = ivp;

      Rng% For Column
      input period = AggregationPeriod.DAY ; # time period to use for aggregating range
      input length = 252 ; # bars to use in range calculation
      def rngGapHi = if IsNaN(close(period = period)) then 99999999999 else close(period = period);
      def rngGapLo = if IsNaN(close(period = period)) then -99999999999 else close(period = period);
      def periodHigh = Highest( rngGapLo, length = length);
      def periodLow = Lowest( rngGapHi, length = length);
      def priceRange = periodHigh - periodLow ;
      def rng = Round( 100 * (close(period = period) - periodLow) / priceRange, 1);
      plot data = rng;

      Delete
  5. This is an excellent code but there is an awesome code if we can get one SD(standard deviation) I know the SD changes based on number of days one for year(365) and/or till option expiry a variable date we can plug in number of days every day morning, hope you will give it to the community. Thanks in advance.

    Nagendra

    ReplyDelete
    Replies
    1. Hi Nagendra, after some emails exchanges with another reader about this very topic it was found that the study called Probability Of Expiring Cone was what he was looking for in terms of a standard deviation plot. See if that study doesn't fit what you are looking for.
      Best.
      -Allen

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Michael Gerity: Tks for the clarification, but I don't seem to duplicate your results for my system is saying "Invalid statment: at 1:8
    No such variable sdi_ivp at 1:1

    Any hints of what to do here?

    tks....Bob

    ReplyDelete
    Replies
    1. Bob, it sounds like you typed the name of the study in the body of the study instead of the name-entry text box.
      Best.
      -Allen

      Delete
  8. Allen: Good to hear your voice on TT today. Great you are giving back to the program...I tried to find the "name-entry" text box, but can't. I've done script before, but this one eludes me.

    I backed out all on the line 1 and put in your code..is there another way to tell me to get there?

    TY...Bob

    ReplyDelete
  9. Allen,

    Here's the color mod Bat referred to this morning:
    http://pastebin.com/jRDkHvXE

    Feel free to incorporate it if you like it.

    Chris

    ReplyDelete
  10. Chris: Bat was able to clean up my dilemma with the code!...Mike: no need to respond, now that this fixed my situation. Tks guys.

    ReplyDelete
  11. This one is for displaying Range Percentile..

    declare upper;
    input period = AggregationPeriod.DAY ; # time period to use for aggregating range
    input length = 252 ; # bars to use in range calculation
    def rngGapHi = if IsNaN(close(period = period)) then 99999999999 else close(period = period);
    def rngGapLo = if IsNaN(close(period = period)) then -99999999999 else close(period = period);
    def periodHigh = Highest( rngGapLo, length = length);
    def periodLow = Lowest( rngGapHi, length = length);
    def priceRange = periodHigh - periodLow ;
    def rng = Round( 100 * (close(period = period) - periodLow) / priceRange, 1);
    # Custom color mod by ChrisBaker97@gmail.com
    AddLabel(1, Concat("Rng%: ",Rng), color = CreateColor(255-(rng*2.55),rng*2.55,0));

    ReplyDelete
  12. This one displays uptick and downtick colors. Allows you to enter IV percent for uptick color.

    declare upper;
    input period = AggregationPeriod.DAY ;
    #hint period: time period to use for aggregating implied volatility.
    input length =252 ;
    #hint length: #bars to use in implied volatility calculation.
    input IV_Num = 51 ;
    #hint IV_Num: Number used to start displaying Uptick color.
    def ivGapHi = if isnan(imp_volatility(period=period)) then 99999999999 else imp_volatility(period=period);
    def ivGapLo = if isnan(imp_volatility(period=period)) then -99999999999 else imp_volatility(period=period);
    def periodHigh = highest( ivGapLo,length=length);
    def periodLow = lowest( ivGapHi, length=length);
    def ivRange = periodHigh - periodLow ;
    def ivp = round( 100*(imp_volatility(period=period) - periodLow)/ivRange, 0);
    plot labelColor = 0; # only to pull in color select widget
    labelColor.setHiding(1) ; #never want to show this
    labelColor.hideBubble();
    labelColor.hideTitle();
    labelColor.DefineColor("Up", Color.UPTICK);
    labelColor.DefineColor("Down", Color.DOWNTICK);
    AddLabel(1, Concat("IV%: ", ivp), if ivp >= IV_Num then labelColor.color("Up") else labelColor.color("Down"));
    # Modified by rlg_mail@yahoo.com

    ReplyDelete
    Replies
    1. yes, good. if you want a fixed color label must set IV_Num = -1

      Delete
  13. Allen,
    Thanks for the awesome code. I couldn't read the plum color either so I modified the code from Chris above to display a nice gradual color change from green (low %ile), to white (mid-range), to red (high %ile). This reflects the TOS color choice of green for debit orders and red for credits which helps as a signal when to go long or short.

    # label changes gradually from green at 0, through white at 50, to red at 100.
    AddLabel(1, Concat(“IV% : “, ivp), color = CreateColor(min(255, ivp*5.1), min(255, (100-ivp)*5.1), min(ivp*5.1, (100-ivp)*5.1)));

    # same as above but label reaches full green at 10, and full red at 90. (Middle is only slightly gray)
    AddLabel(1, Concat(“IV% : “, ivp), color = CreateColor(min(255, max(0, (ivp-10)*5.1)), min(255, max(0, (90-ivp)*5.1)), min(max(0, (ivp-10)*5.1), max(0, (90-ivp)*5.1))));

    The second code is the same as the first but reaches full color at 10% and 90%.

    Also, I use three labels by triplicating the code. That way I can have long, medium, and short time-frames.

    John

    ReplyDelete
  14. thanks everyone, all good mods. if you want the complications they are here in the comments. for my needs the number is the message and i try not to let the color get in the way.

    ReplyDelete
  15. OK, I like this. but Two things:
    Is there a way to display ATM option volatility?
    And can we change the code to set the aggregation period to 1 hour?

    ReplyDelete
    Replies
    1. 1.) On the Trade Tab there is a view selection that will display the implied vol of individual options. It would be difficult (ie needs funding) to replicate that calculation in a chart label as there does not appear to be thinkscript charting functions that perform that calculation for specific options thus requiring implementation of the Bjerksund-Stensland pricing model from scratch.
      2) You can set the agg-period to 1 hour in the edit-studies dialogue. However, when I do this the label displays N/A. I suspect that this is because implied volatility does not vary much over the course of a few hours.

      Delete
  16. Is there a way the IV %tile can be displayed for any given price bar? As you hold the cursor over a price bar, the IV %tile would show for that given day.
    Dennis

    ReplyDelete
    Replies
    1. Hi Dennis, the feature you refer to is called 'tool tip', the little pop-up text that appears when the mouse cursor hovers over an object in many applications. Unfortunately, thinkScript does not provide access to the toolTip object for any chart object. The Tool-tip on price bars is currently commandeered by the TOS data-box when operating in floating mode. However, with some minor modifications the ivp label can be plotted as a lower study, and then you would be able to see the value of it on any past date. Would that be of interest to you?
      Best.
      -Allen

      Delete
  17. Yes. I think that would be an interesting addition.

    Dennis

    ReplyDelete
  18. "Would that be of interest to you?" It would definetly be of interest to me. I have been looking for this solution. It's great to show the IV Percentile/Rank on the HRE but to see it dynamically (as the mouse cursors over each bar) would be very useful.

    Thank you,

    Don

    ReplyDelete
  19. Hi Allen,

    Nice code/tool. I just installed this and its displaying fine but right below it is a line of small green and orange dots that extend a little more than halfway across the chart right under IV%R. Is there a way to fix this?

    ReplyDelete
    Replies
    1. To not plot the dots go to edit studies, click the gear next to sdi_ivp and uncheck 'show plot' in the ivpr tab. The dot-plot was introduced in rev 1.3 to show when in the past iv%r was high enough for selling premium - refer to my post http://www.smalldoginvestor.com/2014/03/thinkscript-included-sdiivp-release-13.html

      Delete
  20. So, all is well, but I have some trouble reading the black text, and I'd like to make it white like they use on tastytrade. It seems like that would be an easy change, but I've searched and searched with no luck. Any suggestions?

    ReplyDelete
  21. The color of the label text is fixed to the color of the chart background. You can only adjust the label color by selecting different colors for HIGH/MID/LOW in the edit-studies dialogue.

    ReplyDelete
  22. Good day. Is there a code available that can be used within an alert that triggers on IV percentile? I see there are alert options for implied and historical, but cannot find anything for percentile.

    ReplyDelete
    Replies
    1. good day. i have confirmed that there is a missing link for alerts on this. i will soon blog-out a version of sdi_ivp that can be used in alerts, so stay tuned.
      best.
      -allen

      Delete
  23. Hello, does anyone know how to find the close price of a 30min. candle that corresponds to the high (or low) for the current week?

    ReplyDelete
    Replies
    1. hi skumar, try something like:

      plot Data = close(period = AggregationPeriod.THIRTY_MIN) == high(period = AggregationPeriod.WEEK);

      best.
      -allen

      Delete