labels of options near the ATM option

crscrs85

Member
Can you take a look at this and see if you can make four labels that have put and call strike prices for the dollar amount closest to the above and below price of the current SPY market price. Ideally one for the daily's and one for the weekly's. so 8 labels total and have it update automatically as the SPY price crosses whole dollar amounts. TIA
input symbol = "SPY";

# Get the SPY market price
def spyMarketPrice = close(symbol = symbol);

# Find the nearest call strike below the SPY market price
def nearestCallStrike = HighestAll(if close(symbol = symbol, optionType = OptionType.CALL, strike = spyMarketPrice) > 0 then close(symbol = symbol, optionType = OptionType.CALL, strike = spyMarketPrice) else Double.NaN);

# Find the nearest put strike above the SPY market price
def nearestPutStrike = HighestAll(if close(symbol = symbol, optionType = OptionType.PUT, strike = spyMarketPrice) > 0 then close(symbol = symbol, optionType = OptionType.PUT, strike = spyMarketPrice) else Double.NaN);

# Determine if nearest call and put prices are increasing
def isIncreasingCall = nearestCallStrike > GetValue(nearestCallStrike, 1);
def isIncreasingPut = nearestPutStrike > GetValue(nearestPutStrike, 1);

# Add labels for call and put prices
AddLabel(yes, "CALL: " + Round(nearestCallStrike, 2), if isIncreasingCall then Color.GREEN else Color.RED);
AddLabel(yes, "PUT: " + Round(nearestPutStrike, 2), if isIncreasingPut then Color.GREEN else Color.RED);
 
Last edited by a moderator:
Can you take a look at this and see if you can make four labels that have put and call strike prices for the dollar amount closest to the above and below price of the current SPY market price. Ideally one for the daily's and one for the weekly's. so 8 labels total and have it update automatically as the SPY price crosses whole dollar amounts. TIA
input symbol = "SPY";

# Get the SPY market price
def spyMarketPrice = close(symbol = symbol);

# Find the nearest call strike below the SPY market price
def nearestCallStrike = HighestAll(if close(symbol = symbol, optionType = OptionType.CALL, strike = spyMarketPrice) > 0 then close(symbol = symbol, optionType = OptionType.CALL, strike = spyMarketPrice) else Double.NaN);

# Find the nearest put strike above the SPY market price
def nearestPutStrike = HighestAll(if close(symbol = symbol, optionType = OptionType.PUT, strike = spyMarketPrice) > 0 then close(symbol = symbol, optionType = OptionType.PUT, strike = spyMarketPrice) else Double.NaN);

# Determine if nearest call and put prices are increasing
def isIncreasingCall = nearestCallStrike > GetValue(nearestCallStrike, 1);
def isIncreasingPut = nearestPutStrike > GetValue(nearestPutStrike, 1);

# Add labels for call and put prices
AddLabel(yes, "CALL: " + Round(nearestCallStrike, 2), if isIncreasingCall then Color.GREEN else Color.RED);
AddLabel(yes, "PUT: " + Round(nearestPutStrike, 2), if isIncreasingPut then Color.GREEN else Color.RED);


i am not sure what you are asking for.
you mention prices, but the variable names have 'strike' in them.

here is a basic study to display 6 option prices, to start with.
3 calls and 3 puts, OTM(purple) ATM(yellow) ITM(cyan)

look at this and come up with new statements/questions.

it doesn't do anything with rounding to dollars.
it just displays option prices, for the symbol on the chart.


Code:
#chat205_near_callput_labels_00d

#https://usethinkscript.com/threads/chatgpt-bard-other-ai-scripts-which-cant-be-used-in-thinkorswim.13822/page-11#post-136835
# post #205

#input symbol = "SPY";
# Get the SPY market price
#def spyMarketPrice = close(symbol = symbol);

#call (ITM) strike price < price
#put  (ITM) strike price > price

#call (OTM) strike price > price
#put  (OTM) strike price < price


#otm_options
input expirationDate = 20240217;

addlabel(1, "  ", color.black);
#-------------------
addlabel(1, "ITM call", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.cyan);
def itm1call = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, itm1call, color.cyan);


addlabel(1, "ATM call", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL), color.yellow);
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
addlabel(1, atmcall, color.yellow);


addlabel(1, "OTM call", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.magenta);
def otm1call = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, otm1call, color.magenta);

#-------------------
addlabel(1, "  ", color.black);
#-------------------

addlabel(1, "OTM put", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.magenta);
def otm1put = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, otm1put, color.magenta);


addlabel(1, "ATM put", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put), color.yellow);
def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put));
addlabel(1, atmput, color.yellow);


addlabel(1, "ITM put", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.cyan);
def itm1put = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, itm1put, color.cyan);
#-------------------

addlabel(1, "  ", color.black);
#

0bD747U.jpg
 
Last edited:
reply to 205
i am not sure what you are asking for.
you mention prices, but the variable names have 'strike' in them.

here is a basic study to display 6 option prices, to start with.
3 calls and 3 puts, OTM(purple) ATM(yellow) ITM(cyan)

look at this and come up with new statements/questions.

it doesn't do anything with rounding to dollars.
it just displays option prices, for the symbol on the chart.


Code:
#chat205_near_callput_labels_00d

#https://usethinkscript.com/threads/chatgpt-bard-other-ai-scripts-which-cant-be-used-in-thinkorswim.13822/page-11#post-136835
# post #205

#input symbol = "SPY";
# Get the SPY market price
#def spyMarketPrice = close(symbol = symbol);

#call (ITM) strike price < price
#put  (ITM) strike price > price

#call (OTM) strike price > price
#put  (OTM) strike price < price


#otm_options
input expirationDate = 20240217;

addlabel(1, "  ", color.black);
#-------------------
addlabel(1, "ITM call", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.cyan);
def itm1call = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, itm1call, color.cyan);


addlabel(1, "ATM call", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL), color.yellow);
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
addlabel(1, atmcall, color.yellow);


addlabel(1, "OTM call", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.magenta);
def otm1call = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, otm1call, color.magenta);

#-------------------
addlabel(1, "  ", color.black);
#-------------------

addlabel(1, "OTM put", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.magenta);
def otm1put = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, otm1put, color.magenta);


addlabel(1, "ATM put", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put), color.yellow);
def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put));
addlabel(1, atmput, color.yellow);


addlabel(1, "ITM put", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.cyan);
def itm1put = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, itm1put, color.cyan);
#-------------------

addlabel(1, "  ", color.black);
#

0bD747U.jpg
Assuming the ITM, ATM, and OTM options update automatically when price moves from one whole dollar amount to another then this should be perfect. Ill give you an example of what i was attempting to ask for. If SPY is priced at 470.40 then the ITM call is 470 and the ITM put is 471 which would display in my labels. But if SPY price drops to 469.30 the new ITM call is 469 and new ITM put is 470. In my current set up i have to manually change the option strike price from 470 to 469 for the calls and then 471 to 470 for the puts. From what I can tell this does automatically update the strike prices. Im not going to pretend to be a coder but i attempted a few changes. 1st off my pc runs pitiful so i dropped the 2 OTM prices off so less data has to be calculated. Secondly i added dynamic colors to the labels, green if price is up on calls and down on puts, so essentially you want to see 4 green for long scalps or 4 red for short scalps. And lastly i added a relative volume threshhold of 1.5 based off of a 20 bar average. Dark green and dark red for volume spikes. Based off the coding in some scenerios the volume spike color may flash the wrong color. For instance if the RVOL threshhold is met and price is increasing but lower than the previous bar close at the time of the threshhold hold being met price would flash dark red until price moved above the previous bar close. Should be evident which way price is moving live trading if it occurs and the important piece of info(the RVOL spike) doesnt get overlooked. As i was typing this I was thinking to add a feature to where the three black boxes change color if SPY hits a RVOL threshhold. So my question to you now is one, does the way a script is coded effect its performance, So could 2 coders have the same output such as the average of 10 stocks but one script perform quicker and more efficient due to how the script was coded. If thats true can you consolidate the "averageVolume" and "relativeVolume" "0-3" declarations so it runs smoother. 2nd question is pertaining to the relative volume function. Can you make it not calculate a relative volume bar in the next bars calculation? so on a one minute chart, if at 12:21 there is a RVOL bar, the calculation for the next bar(12:22) will still be based on the average of 12:00-12:20(since we are using a 20 bar average). And have it reset once there is not at least 2 RVOL bars in a row. The idea of this is to not miss sustained volume because of a RVOL bar running the average too high. Lastly whats your opinion?(by that i mean change or add whatever if you think it will make it more efficient. Thanks for the help. Here is the code:

input expirationDate = 20240217;
input length = 20;

AddLabel(1, " ", Color.BLACK);
#-------------------


def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", Color.BLACK);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------

AddLabel(1, " ", Color.BLACK);
 
Assuming the ITM, ATM, and OTM options update automatically when price moves from one whole dollar amount to another then this should be perfect. Ill give you an example of what i was attempting to ask for. If SPY is priced at 470.40 then the ITM call is 470 and the ITM put is 471 which would display in my labels. But if SPY price drops to 469.30 the new ITM call is 469 and new ITM put is 470. In my current set up i have to manually change the option strike price from 470 to 469 for the calls and then 471 to 470 for the puts. From what I can tell this does automatically update the strike prices. Im not going to pretend to be a coder but i attempted a few changes. 1st off my pc runs pitiful so i dropped the 2 OTM prices off so less data has to be calculated. Secondly i added dynamic colors to the labels, green if price is up on calls and down on puts, so essentially you want to see 4 green for long scalps or 4 red for short scalps. And lastly i added a relative volume threshhold of 1.5 based off of a 20 bar average. Dark green and dark red for volume spikes. Based off the coding in some scenerios the volume spike color may flash the wrong color. For instance if the RVOL threshhold is met and price is increasing but lower than the previous bar close at the time of the threshhold hold being met price would flash dark red until price moved above the previous bar close. Should be evident which way price is moving live trading if it occurs and the important piece of info(the RVOL spike) doesnt get overlooked. As i was typing this I was thinking to add a feature to where the three black boxes change color if SPY hits a RVOL threshhold. So my question to you now is one, does the way a script is coded effect its performance, So could 2 coders have the same output such as the average of 10 stocks but one script perform quicker and more efficient due to how the script was coded. If thats true can you consolidate the "averageVolume" and "relativeVolume" "0-3" declarations so it runs smoother. 2nd question is pertaining to the relative volume function. Can you make it not calculate a relative volume bar in the next bars calculation? so on a one minute chart, if at 12:21 there is a RVOL bar, the calculation for the next bar(12:22) will still be based on the average of 12:00-12:20(since we are using a 20 bar average). And have it reset once there is not at least 2 RVOL bars in a row. The idea of this is to not miss sustained volume because of a RVOL bar running the average too high. Lastly whats your opinion?(by that i mean change or add whatever if you think it will make it more efficient. Thanks for the help. Here is the code:

input expirationDate = 20240217;
input length = 20;

AddLabel(1, " ", Color.BLACK);
#-------------------


def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", Color.BLACK);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------

AddLabel(1, " ", Color.BLACK);

i am looking this over

in the future, post code in a code window.
in the header , click on </> and paste code in the popup window.
i usually ignore posts with long codes that are not in a code window.

your labels are black, because they contain values of N/A.
verified with a bubble
Code:
addchartbubble(1, low, volume(symbol = "ATMcall") , color.yellow, no);

you can't put a variable name in quotes, in a function , "ATMcall"
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def v = volume(symbol = "ATMcall");
everything that is within the close( ) , will have to be pasted within the volume( )
 
Last edited by a moderator:
i am looking this over

in the future, post code in a code window.
in the header , click on </> and paste code in the popup window.
i usually ignore posts with long codes that are not in a code window.

your labels are black, because they contain values of N/A.
verified with a bubble
Code:
addchartbubble(1, low, volume(symbol = "ATMcall") , color.yellow, no);

you can't put a variable name in quotes, in a function , "ATMcall"
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def v = volume(symbol = "ATMcall");
everything that is within the close( ) , will have to be pasted within the volume( )
I'm getting NA black labels also. Is that what is supposed to happen? Did I copy the script incorrectly?
 
optionsindicator1.png

I didnt get to look it over until after hours, this is what it showed once i made the changes(above pic). Im thinking it will work during regular hours since its showing the last price in the black boxes. I changed the default date in the coding and from the edit studies tab. It seems to be working fine but wont know until tomorrow during regular trading hours. I posted the new coding in a </> box. Let me know if you received it correctly. I fumbled around with it and it may be posted 3 times in the box

Also these indicators(below pic) sometimes take up to 15 seconds to reset every time a new candle forms(Pic below). Can you take a looksy and see if there a better way to code these to have them run more efficiently. And can you post more than one code in a </> box? Or multiple </> boxes within one reply? What are the details to these bad boys. When i copy and pasted the ITMATMOptions code in the box it didnt look right. I left the code option on "General Code" because ThinkScript wasnt listed. Again let me know if you recieved it correctly. Thanks!!!
Code:
#otm_options
input expirationDate = 20240124;
input length = 20;
def averageVolume4 = MovingAverage(AverageType.SIMPLE, volume(symbol = "SPY"), length);
def relativeVolume4 = volume(symbol = "SPY") / averageVolume4;
addlabel(1, "  ", CreateColor(102, 102, 0));
AddLabel(1, "  ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------
#CreateColor(153, 153, 0)

def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), length);
def relativeVolume = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)) / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
    if Up then
            if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
        else   
            if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(), length);
def relativeVolume1 = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)) / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
    if Up1 then
            if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
        else   
            if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, "  ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT))), length);
def relativeVolume3 = volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT))) / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
    if Up3 then
            if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
        else   
            if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)), length);
def relativeVolume2 = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)) / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
    if Up2 then
            if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
        else   
            if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------
AddLabel(1, "  ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);

addlabel(1, "  ", CreateColor(102, 102, 0));
#addlabel(1, "  ", CreateColor(102, 102, 0));
#AddLabel(yes, "MSFT: " + MSFTPrice, if isIncreasing then Color.RED else Color.GREEN);
#input length = 20;
#def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = symbol), length);
#def relativeVolume = volume(symbol = symbol) / averageVolume;
#AddLabel(yes, "Relative Volume (" + symbol + "): " + Round(relativeVolume, 2), color = if relativeVolume >= 1.5 then Color.GREEN else Color.YELLOW);
#AddLabel(yes, "META: " + METAPrice,
# if isAbovePdc6 then
#        if isIncreasing6 then Color.GREEN else Color.RED
#    else
#        if isIncreasing6 then Color.DARK_GREEN else Color.DARK_RED);
#AddLabel(yes, "Relative Volume (" + symbol + "): " + Round(relativeVolume, 2), color = if relativeVolume >= 1.5 then Color.GREEN else Color.YELLOW);
SPYSPYSPY.png


MAG7 labels. descriptions above coding.
http://tos.mx/dtWM87e

SPY Internals
http://tos.mx/xdhOiEa

I'm getting NA black labels also. Is that what is supposed to happen? Did I copy the script incorrectly?

i am looking this over

in the future, post code in a code window.
in the header , click on </> and paste code in the popup window.
i usually ignore posts with long codes that are not in a code window.

your labels are black, because they contain values of N/A.
verified with a bubble
Code:
addchartbubble(1, low, volume(symbol = "ATMcall") , color.yellow, no);

you can't put a variable name in quotes, in a function , "ATMcall"
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def v = volume(symbol = "ATMcall");
everything that is within the close( ) , will have to be pasted within the volume( )
Also should mention when i first loaded the study with the original expire date of feb. 17 2024 it showed me the opposite with "ITMCALL" being black with a N/A and the three other boxes displaying color. Again since its now displaying a price for each Option i think once the Market opens it should funtion correctly
 
Last edited by a moderator:
Assuming the ITM, ATM, and OTM options update automatically when price moves from one whole dollar amount to another then this should be perfect. Ill give you an example of what i was attempting to ask for. If SPY is priced at 470.40 then the ITM call is 470 and the ITM put is 471 which would display in my labels. But if SPY price drops to 469.30 the new ITM call is 469 and new ITM put is 470. In my current set up i have to manually change the option strike price from 470 to 469 for the calls and then 471 to 470 for the puts. From what I can tell this does automatically update the strike prices. Im not going to pretend to be a coder but i attempted a few changes. 1st off my pc runs pitiful so i dropped the 2 OTM prices off so less data has to be calculated. Secondly i added dynamic colors to the labels, green if price is up on calls and down on puts, so essentially you want to see 4 green for long scalps or 4 red for short scalps. And lastly i added a relative volume threshhold of 1.5 based off of a 20 bar average. Dark green and dark red for volume spikes. Based off the coding in some scenerios the volume spike color may flash the wrong color. For instance if the RVOL threshhold is met and price is increasing but lower than the previous bar close at the time of the threshhold hold being met price would flash dark red until price moved above the previous bar close. Should be evident which way price is moving live trading if it occurs and the important piece of info(the RVOL spike) doesnt get overlooked. As i was typing this I was thinking to add a feature to where the three black boxes change color if SPY hits a RVOL threshhold. So my question to you now is one, does the way a script is coded effect its performance, So could 2 coders have the same output such as the average of 10 stocks but one script perform quicker and more efficient due to how the script was coded. If thats true can you consolidate the "averageVolume" and "relativeVolume" "0-3" declarations so it runs smoother. 2nd question is pertaining to the relative volume function. Can you make it not calculate a relative volume bar in the next bars calculation? so on a one minute chart, if at 12:21 there is a RVOL bar, the calculation for the next bar(12:22) will still be based on the average of 12:00-12:20(since we are using a 20 bar average). And have it reset once there is not at least 2 RVOL bars in a row. The idea of this is to not miss sustained volume because of a RVOL bar running the average too high. Lastly whats your opinion?(by that i mean change or add whatever if you think it will make it more efficient. Thanks for the help. Here is the code:

input expirationDate = 20240217;
input length = 20;

AddLabel(1, " ", Color.BLACK);
#-------------------


def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", Color.BLACK);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------

AddLabel(1, " ", Color.BLACK);

i started with the code in post 3

i fixed several things,

you are using an if then to choose color in a label. if the value is na, then the color is black.
if there is a bar for the stock, but not for the option, then the option price will be na and cause an error.
if an error, then use prev value.

sometimes the volume is 0 and the average will be 0. then will have a divide by 0 and an error for rvol. add if then to check if average is 0.

label color - 1st relativeVolume is >= 1.5.
the 2nd line with relativeVolume didn't have a comparison and a number (just the variable).
make them relativeVolume < 0.8 ( i just picked a random number)


Code:
#chat208_near_options

#https://usethinkscript.com/threads/labels-of-options-near-the-atm-option.17772/

input expirationDate = 20240217;
#input expirationDate = 20240216;
input length = 20;

AddLabel(1, " ", Color.BLACK);
#-------------------

# ATM CALL

# test if the option has a valid price. if not then use prev value
def ATMcall;
def atmcallvol;
if !IsNaN(close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)))
then {
    ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
    atmcallvol = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
} else {
    ATMcall = ATMcall[1];
    atmcallvol = atmcallvol[1];
}

def Up = ATMcall > ATMcall[1];
input avgtype = AverageType.SIMPLE;
def averageVolume = MovingAverage(avgtype, atmcallvol, length);

# test for avg vol = 0
def relativeVolume;
if averageVolume == 0 then {
relativeVolume = 0;
} else {
relativeVolume = atmcallvol / averageVolume;
}

AddLabel(1, "ATMCALL: " + ATMcall + "  " + Round(relativeVolume, 2),
if Up then 
  if relativeVolume >= 1.5 then Color.DARK_GREEN
    else Color.GREEN
else 
  if relativeVolume <= .8 then Color.DARK_RED
    else Color.RED);



AddLabel(0,
GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)
, Color.YELLOW);

AddChartBubble(1, low,
 ATMcall + " $\n" +
 atmcallvol + " v\n" +
 averageVolume + " avgv\n" +
 relativeVolume + " rvol\n" 
, Color.YELLOW, no);


AddChartBubble(0, low,
volume(symbol = "ATMcall")
, Color.YELLOW, no);


#---------------------------------
AddLabel(1, " ", Color.BLACK);

def ITMcall;
def ITMcallvol;
if !isnan( close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)))) then {
 ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
 ITMcallvol = volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
} else {
 ITMcall = itmcall[1];
 ITMcallvol = itmcallvol[1];
}

def Up1 = ITMcall > ITMcall[1];
input avgtype1 = AverageType.SIMPLE;
def averageVolume1 = MovingAverage(avgtype1, itmcallvol, length);

#def relativeVolume1 = itmcallvol / averageVolume1;
def relativeVolume1;
if averageVolume1 == 0 then {
relativeVolume1 = 0;
} else {
relativeVolume1 = itmcallvol / averageVolume1;
}

AddLabel(1, "ITMCALL: " + ITMcall + "  " + Round(relativeVolume1, 2),
if Up1 then
  if relativeVolume1 >= 1.5 then Color.DARK_GREEN
  else Color.GREEN
else
  if relativeVolume1 < .8 then Color.DARK_RED
  else Color.RED);


#---------------------------------
AddLabel(1, " ", Color.BLACK);


def ITMput;
def ITMputvol;
if !isnan(close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)))) then {
  ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
  ITMputvol = volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
} else {
  ITMput = ITMput[1];
  ITMputvol = ITMputvol[1];
}

def Up3 = ITMput > ITMput[1];
input avgtype3 = AverageType.SIMPLE;
def averageVolume3 = MovingAverage(avgtype3, itmputvol, length);

#def relativeVolume3 = itmputvol / averageVolume3;
def relativeVolume3;
if averageVolume3 == 0 then {
relativeVolume3 = 0;
} else {
relativeVolume3 = itmputvol / averageVolume3;
}

AddLabel(1, "ITMCALL: " + ITMput + "  " + Round(relativeVolume3, 2),
if Up3 then
  if relativeVolume3 >= 1.5 then Color.DARK_RED
  else Color.RED
else
  if relativeVolume3 < .8 then Color.DARK_GREEN
  else Color.GREEN);


#---------------------------------
AddLabel(1, " ", Color.BLACK);


def ATMput;
def ATMputvol;
if !isnan( close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT))) then {
  ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
  atmputvol = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
} else {
  ATMput = ATMput[1];
  ATMputvol = ATMputvol[1];
}

def Up2 = ATMput > ATMput[1];
input avgtype2 = AverageType.SIMPLE;
def averageVolume2 = MovingAverage(avgtype2, atmputvol, length);

#def relativeVolume2 = atmputvol / averageVolume2;
def relativeVolume2;
if averageVolume2 == 0 then {
relativeVolume2 = 0;
} else {
relativeVolume2 = atmputvol / averageVolume2;
}

AddLabel(1, "ITMCALL: " + ATMput + "  " + Round(relativeVolume2, 2),
if Up2 then
  if relativeVolume2 >= 1.5 then Color.DARK_RED
  else Color.RED
else
  if relativeVolume2 < 0.8 then Color.DARK_GREEN
  else Color.GREEN);

#----------------------------------

AddLabel(1, " ", Color.BLACK);

#
 
Assuming the ITM, ATM, and OTM options update automatically when price moves from one whole dollar amount to another then this should be perfect. Ill give you an example of what i was attempting to ask for. If SPY is priced at 470.40 then the ITM call is 470 and the ITM put is 471 which would display in my labels. But if SPY price drops to 469.30 the new ITM call is 469 and new ITM put is 470. In my current set up i have to manually change the option strike price from 470 to 469 for the calls and then 471 to 470 for the puts. From what I can tell this does automatically update the strike prices. Im not going to pretend to be a coder but i attempted a few changes. 1st off my pc runs pitiful so i dropped the 2 OTM prices off so less data has to be calculated. Secondly i added dynamic colors to the labels, green if price is up on calls and down on puts, so essentially you want to see 4 green for long scalps or 4 red for short scalps. And lastly i added a relative volume threshhold of 1.5 based off of a 20 bar average. Dark green and dark red for volume spikes. Based off the coding in some scenerios the volume spike color may flash the wrong color. For instance if the RVOL threshhold is met and price is increasing but lower than the previous bar close at the time of the threshhold hold being met price would flash dark red until price moved above the previous bar close. Should be evident which way price is moving live trading if it occurs and the important piece of info(the RVOL spike) doesnt get overlooked. As i was typing this I was thinking to add a feature to where the three black boxes change color if SPY hits a RVOL threshhold. So my question to you now is one, does the way a script is coded effect its performance, So could 2 coders have the same output such as the average of 10 stocks but one script perform quicker and more efficient due to how the script was coded. If thats true can you consolidate the "averageVolume" and "relativeVolume" "0-3" declarations so it runs smoother. 2nd question is pertaining to the relative volume function. Can you make it not calculate a relative volume bar in the next bars calculation? so on a one minute chart, if at 12:21 there is a RVOL bar, the calculation for the next bar(12:22) will still be based on the average of 12:00-12:20(since we are using a 20 bar average). And have it reset once there is not at least 2 RVOL bars in a row. The idea of this is to not miss sustained volume because of a RVOL bar running the average too high. Lastly whats your opinion?(by that i mean change or add whatever if you think it will make it more efficient. Thanks for the help. Here is the code:

input expirationDate = 20240217;
input length = 20;

AddLabel(1, " ", Color.BLACK);
#-------------------


def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", Color.BLACK);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------

AddLabel(1, " ", Color.BLACK);


I changed the 3 black boxes to yellow and have them changing to dark yellow if a RVOL of 1.5 hits based of a 20 bar ma. We have the stop light package now!



#otm_options
input expirationDate = 20240217;
input length = 20;
def averageVolume4 = MovingAverage(AverageType.SIMPLE, volume(symbol = "SPY"), length);
def relativeVolume4 = volume(symbol = "SPY") / averageVolume4;

AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------
#CreateColor(153, 153, 0)

def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);

I changed the 3 black boxes to yellow and have them changing to dark yellow if a RVOL of 1.5 hits based of a 20 bar ma. We have the stop light package now!



#otm_options
input expirationDate = 20240217;
input length = 20;
def averageVolume4 = MovingAverage(AverageType.SIMPLE, volume(symbol = "SPY"), length);
def relativeVolume4 = volume(symbol = "SPY") / averageVolume4;

AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------
#CreateColor(153, 153, 0)

def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);


Added two dark yellow boxes on the outside to make it easier to tell when spy hits RVOL threshhold.



input expirationDate = 20240217;
input length = 20;
def averageVolume4 = MovingAverage(AverageType.SIMPLE, volume(symbol = "SPY"), length);
def relativeVolume4 = volume(symbol = "SPY") / averageVolume4;
addlabel(1, " ", CreateColor(102, 102, 0));
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------
#CreateColor(153, 153, 0)

def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
def Up = ATMcall > ATMcall[1];
def averageVolume = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMcall"), length);
def relativeVolume = volume(symbol = "ATMcall") / averageVolume;
AddLabel(1, "ATMCALL: " + ATMcall + Round(relativeVolume, 2),
if Up then
if relativeVolume >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume then Color.DARK_RED else Color.RED);



def ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
def Up1 = ITMcall > ITMcall[1];
def averageVolume1 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMcall"), length);
def relativeVolume1 = volume(symbol = "ITMcall") / averageVolume1;
AddLabel(1, "ITMCALL: " + ITMcall + Round(relativeVolume1, 2),
if Up1 then
if relativeVolume1 >= 1.5 then Color.DARK_GREEN else Color.GREEN
else
if relativeVolume1 then Color.DARK_RED else Color.RED);

#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);
#-------------------

def ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
def Up3 = ITMput > ITMput[1];
def averageVolume3 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ITMput"), length);
def relativeVolume3 = volume(symbol = "ITMput") / averageVolume3;
AddLabel(1, "ITMCALL: " + ITMput + Round(relativeVolume3, 2),
if Up3 then
if relativeVolume3 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume3 then Color.DARK_GREEN else Color.GREEN);

def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
def Up2 = ATMput > ATMput[1];
def averageVolume2 = MovingAverage(AverageType.SIMPLE, volume(symbol = "ATMput"), length);
def relativeVolume2 = volume(symbol = "ATMput") / averageVolume2;
AddLabel(1, "ITMCALL: " + ATMput + Round(relativeVolume2, 2),
if Up2 then
if relativeVolume2 >= 1.5 then Color.DARK_RED else Color.RED
else
if relativeVolume2 then Color.DARK_GREEN else Color.GREEN);
#-------------------
AddLabel(1, " ", if relativeVolume4 >= 1.5 then CreateColor(102, 102, 0) else Color.YELLOW);

addlabel(1, " ", CreateColor(102, 102, 0));

reply to 205
i am not sure what you are asking for.
you mention prices, but the variable names have 'strike' in them.

here is a basic study to display 6 option prices, to start with.
3 calls and 3 puts, OTM(purple) ATM(yellow) ITM(cyan)

look at this and come up with new statements/questions.

it doesn't do anything with rounding to dollars.
it just displays option prices, for the symbol on the chart.


Code:
#chat205_near_callput_labels_00d

#https://usethinkscript.com/threads/chatgpt-bard-other-ai-scripts-which-cant-be-used-in-thinkorswim.13822/page-11#post-136835
# post #205

#input symbol = "SPY";
# Get the SPY market price
#def spyMarketPrice = close(symbol = symbol);

#call (ITM) strike price < price
#put  (ITM) strike price > price

#call (OTM) strike price > price
#put  (OTM) strike price < price


#otm_options
input expirationDate = 20240217;

addlabel(1, "  ", color.black);
#-------------------
addlabel(1, "ITM call", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.cyan);
def itm1call = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, itm1call, color.cyan);


addlabel(1, "ATM call", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL), color.yellow);
def ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
addlabel(1, atmcall, color.yellow);


addlabel(1, "OTM call", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)), color.magenta);
def otm1call = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
addlabel(1, otm1call, color.magenta);

#-------------------
addlabel(1, "  ", color.black);
#-------------------

addlabel(1, "OTM put", color.magenta);
addlabel(1, GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.magenta);
def otm1put = close(GetNextOTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, otm1put, color.magenta);


addlabel(1, "ATM put", color.yellow);
addlabel(1, GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put), color.yellow);
def ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put));
addlabel(1, atmput, color.yellow);


addlabel(1, "ITM put", color.cyan);
addlabel(1, GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)), color.cyan);
def itm1put = close(GetNextiTMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.put)));
addlabel(1, itm1put, color.cyan);
#-------------------

addlabel(1, "  ", color.black);
#

0bD747U.jpg

I tried it out and it worked for a second then quit working. Couldnt get it to work properly after that. I dont think its the coding though i think someone may have hacked my TOS or its glitched to some degree because when i was making the modifications mentioned in the other replies the colors started changing on their own from yellow to dark yellow after i loaded it onto a chart to make sure the coding loaded properly. I saw it happen and thought i was seeing things(this is what gave me the idea to put two more dark yellow boxes on the outside to compare the colors. It did do it again, I thought it was weird but thought nothing of it until this morning when your coding only worked for a second then quit. Has this happened to you before or something similar?
 
Last edited by a moderator:
I had something come up at the end of the week and never got a chance to test it live. However I made some tweaks to it. Description in the code. Let me know if you see any errors.
Code:
# SPY and SPY Options volume and price indicator
# description: Dark yellow boxes(SPY box) will turn yellow to match the two outside yellow boxes when a relative volume threshold is crossed. CALL and PUT boxes are dark red and dark green depending on wether the price is above or below the previous bar close. Colors will change from dark red and dark green to red and green if the relative volume threshhold is crossed for option volume. A red and green box was added next to each dark colored option box simply for comparison to make spotting a relative volume spike signal easier.
# Rel. Vol. threshhold is 1.5(150%) of the average volume of a 20 SMA. If a Rel. Vol. threshhold is triggered the next bar will not use the rel. vol. spike bar in the next bar's calculation in order to keep the avg. at a normal level and better find sustained increased volume.
# I use this(if it works, havent got a chance to test it but i use this data) on a 1 minute chart as confirmation to stay in or get out of a scalp trade. I also use it is along side other indicators for entries.


#RV1-5 and AV1-5 are RELVOL and AvgVOL

input expirationDate = 20240129;
input length = 20;
input avgtype = AverageType.SIMPLE;
input avgtype1 = AverageType.SIMPLE;
input avgtype2 = AverageType.SIMPLE;
input avgtype3 = AverageType.SIMPLE;

#-----------------------------------------------
#spy volume/relvol
def AV4 = MovingAverage(AverageType.SIMPLE, volume(symbol = "SPY"), length);
def RV4 = volume(symbol = "SPY") / AV4;

AddLabel(1, "  ", Color.YELLOW);
AddLabel(1, "  ", if RV4 >= 1.5 then Color.YELLOW else CreateColor(102, 102, 0));
AddLabel(1, "  ", Color.GREEN);
#-------------------

##### ATM CALL
#####

def ATMcall;
def atmcallvol;
def AV5;
def RV5;
def Up = ATMcall >= ATMcall[1];

# test to make sure a value can be found (NAN-(not a number)) if not it defaults to prev. value to prevent error

if !IsNaN(close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL))) {
    ATMcall = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));
    atmcallvol = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL));

    if RV5[1] >= 1.5 {   
        AV5 = AV5[1];
    } else {
        AV5 = MovingAverage(avgtype, atmcallvol[1], length);
    }
    if AV5 == 0
    then {
        RV5 = 0;
    } else {
        RV5 = atmcallvol / AV5;
    }
} else {
    ATMcall = ATMcall[1];
    atmcallvol = atmcallvol[1];
    RV5 = RV5[1];
    AV5 = AV5[1];
}

AddLabel(1, "ATMCALL: " + ATMcall + "  " + Round(RV5, 2),
if Up then
  if RV5 >= 1.5 then Color.GREEN
    else Color.DARK_GREEN
else
  if RV5 >= 1.5 then Color.RED
    else Color.DARK_RED);

#---------------------------------
AddLabel(1, "  ", Color.RED);
AddLabel(1, "  ", if RV4 >= 1.5 then Color.YELLOW else CreateColor(102, 102, 0));
AddLabel(1, "  ", Color.GREEN);
#-------------------------------------------
##### ITM CALL
#####

def ITMcall;
def ITMcallvol;
def AV1;
def RV1;
def Up1 = ITMcall >= ITMcall[1];

if !IsNaN( close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)))) {
    ITMcall = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));
    ITMcallvol = volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.CALL)));

    if RV1[1] >= 1.5 {
        AV1 = AV1[1];
    } else {
        AV1 = MovingAverage(avgtype1, ITMcallvol, length);
    }

    if AV1 == 0
    then {
        RV1 = 0;
    } else {
        RV1 = ITMcallvol / AV1;
    }
} else {
    ITMcall = ITMcall[1];
    ITMcallvol = ITMcallvol[1];
    RV1 = RV1[1];
    AV1 = AV1[1];
}

AddLabel(1, "ITMCALL: " + ITMcall + "  " + Round(RV1, 2),
if Up1 then
  if RV1 >= 1.5 then Color.GREEN
  else Color.DARK_GREEN
else
  if RV1 >= 1.5 then Color.RED
  else Color.DARK_RED);


#---------------------------------
AddLabel(1, "  ", Color.RED);
AddLabel(1, "     SPY     ", if RV4 >= 1.5 then Color.YELLOW else CreateColor(102, 102, 0));
AddLabel(1, "  ", Color.GREEN);
#----------------------------
##### ITM PUT
#####

def ITMput;
def ITMputvol;
def AV3;
def RV3;
def Up3 = ITMput >= ITMput[1];

if !IsNaN(close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)))) {
    ITMput = close(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));
    ITMputvol = volume(GetNextITMOption(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT)));

    if RV3[1] >= 1.5 {

        AV3 = AV3[1];
    } else {
        # Otherwise, calculate AV using the volume of the previous bar
        AV3 = MovingAverage(avgtype2, ITMputvol, length);
    }

    if AV3 == 0
    then {
        RV3 = 0;
    } else {
        RV3 = ITMputvol / AV3;
    }
} else {
    ITMput = ITMput[1];
    ITMputvol = ITMputvol[1];
    RV3 = RV3[1];
    AV3 = AV3[1];
}


AddLabel(1, "ITMPUT: " + ITMput + "  " + Round(RV3, 2),
if Up3 then
  if RV3 >= 1.5 then Color.RED
  else Color.DARK_RED
else
  if RV3 >= 1.5 then Color.GREEN
  else Color.DARK_GREEN);


#---------------------------------
AddLabel(1, "  ", Color.RED);
AddLabel(1, "  ", if RV4 >= 1.5 then Color.YELLOW else CreateColor(102, 102, 0));
AddLabel(1, "  ", Color.GREEN);
#----------------------------------
#### ATM PUT
#####

def ATMput;
def ATMputvol;
def AV2;
def RV2;
def Up2 = ATMput >= ATMput[1];

if !IsNaN( close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT))) {
    ATMput = close(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));
    ATMputvol = volume(GetATMOption(GetUnderlyingSymbol(), expirationDate, OptionClass.PUT));


 if RV2[1] >= 1.5 {
        AV2 = AV2[1];
    } else {
        # Otherwise, calculate AV using the volume of the previous bar
        AV2 = MovingAverage(avgtype3, ATMputvol, length);
    }

    if AV2 == 0 then {
        RV2 = 0;
    } else {
        RV2 = atmcallvol / AV2;
    }
} else {
    ATMPUT = ATMPUT[1];
    ATMPUTvol = ATMPUTvol[1];
    RV2 = RV2[1];
    AV2 = AV2[1];
}
 
    AddLabel(1, "ATMPUT: " + ATMput + "  " + Round(RV2, 2),
if Up2 then
  if RV2 >= 1.5 then Color.RED
  else Color.DARK_RED
else
  if RV2 >= 1.5 then Color.GREEN
  else Color.DARK_GREEN);

#----------------------------------
    AddLabel(1, "  ", Color.RED);
    AddLabel(1, "  ", if RV4 >= 1.5 then Color.YELLOW else CreateColor(102, 102, 0));
    AddLabel(1, "  ", Color.YELLOW);
 

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
494 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