Standard Power Option [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("Standard Power Option [Loxx]", 
     shorttitle ="SPO [Loxx]",
     overlay = true, 
     max_lines_count = 500, precision = 4)

if not timeframe.isdaily
    runtime.error("Error: Invald timeframe. Indicator only works on daily timeframe.") 

import loxx/loxxexpandedsourcetypes/4
import loxx/cnd/1

color darkGreenColor = #1B7E02 
string callString = "Call"
string putString = "Put"

string Continuous = "Continuous"
string PeriodRate = "Period Rate"
string Annual = "Annual"
string SemiAnnual = "Semi-Annual"
string Quaterly = "Quaterly"
string Monthly = "Monthly"

string rogersatch = "Roger-Satchell"
string parkinson = "Parkinson"
string c2c = "Close-to-Close"
string gkvol = "Garman-Klass"
string gkzhvol = "Garman-Klass-Yang-Zhang"
string ewmavolstr = "Exponential Weighted Moving Average"

string timtoolbar= "Time Now = Current time in UNIX format. It is the number of milliseconds that have elapsed since 00:00:00 UTC, 1 January 1970."
string timtoolnow = "Time Bar = The time function returns the UNIX time of the current bar for the specified timeframe and session or NaN if the time point is out of session."
string timetooltrade = "Trading Day = The beginning time of the trading day the current bar belongs to, in UNIX format (the number of milliseconds that have elapsed since 00:00:00 UTC, 1 January 1970)."

ewmavol(float src, int per) => 
    float lambda = (per - 1) / (per + 1)
    float temp = na
    temp := lambda * nz(temp[1], math.pow(src, 2)) + (1.0 - lambda) * math.pow(src, 2)
    out = math.sqrt(temp)
    out
    
rogerssatchel(int per) =>
    float sum = math.sum(math.log(high/ close) * math.log(high / open)
         + math.log(low / close) * math.log(low / open), per) / per
    float out = math.sqrt(sum) 
    out

closetoclose(float src, int per) => 
    float avg = ta.sma(src, per)
    array<float> sarr = array.new<float>(per, 0)
    for i = 0 to per - 1 
        array.set(sarr, i,  math.pow(nz(src[i]) - avg, 2))
    float out = math.sqrt(array.sum(sarr) / (per - 1))
    out 

parkinsonvol(int per)=>
    float volConst = 1.0 / (4.0 * per * math.log(2))
    float sum = volConst * math.sum(math.pow(math.log(high / low), 2), per)
    float out = math.sqrt(sum) 
    out

garmanKlass(int per)=>
    float hllog = math.log(high / low)
    float oplog = math.log(close / open)
    float garmult = (2 * math.log(2) - 1)
    float parkinsonsum = 1 / (2 * per) * math.sum(math.pow(hllog, 2), per)
    float garmansum = garmult / per * math.sum(math.pow(oplog, 2), per)
    float sum = parkinsonsum - garmansum
    float devpercent = math.sqrt(sum)  
    devpercent

gkyzvol(int per)=>
    float gzkylog = math.log(open / nz(close[1]))
    float pklog = math.log(high / low)
    float gklog = math.log(close / open)
    float garmult = (2 * math.log(2) - 1)
    float gkyzsum = 1 / per * math.sum(math.pow(gzkylog, 2), per)
    float parkinsonsum = 1 / (2 * per) * math.sum(math.pow(pklog, 2), per)
    float garmansum = garmult / per * math.sum(math.pow(gklog, 2), per)
    float sum = gkyzsum + parkinsonsum - garmansum
    float devpercent = math.sqrt(sum)  
    devpercent

convertingToCCRate(float r, float Compoundings)=>
    float ConvertingToCCRate = 0
    if Compoundings == 0 
        ConvertingToCCRate := r
    else
        ConvertingToCCRate := Compoundings * math.log(1 + r / Compoundings)
    ConvertingToCCRate

ND(float x)=> 
    float out = math.exp(-x * x * 0.5) / math.sqrt(2 * math.pi)
    out 

PowerOptionAsymmetric(string CallPutFlag, float S, float X, float T, float r, float b, float v, float i)=>
    float PowerOptionAsymmetric = 0
    float d1 = (math.log(S / math.pow(X, (1 / i))) + (b + (i - 1 / 2) * v * v) * T) / (v * math.sqrt(T))
    float d2 = d1 - i * v * math.sqrt(T)
    if CallPutFlag == callString
        PowerOptionAsymmetric := math.pow(S, i) * math.exp(((i - 1) * (r + i * v * v / 2) - i * (r - b)) * T) * cnd.CND1(d1) - X * math.exp(-r * T) * cnd.CND1(d2)
    else 
        PowerOptionAsymmetric := X * math.exp(-r * T) * cnd.CND1(-d2) - math.pow(S, i) * math.exp(((i - 1) * (r + i * v * v / 2) - i * (r - b)) * T) * cnd.CND1(-d1)
    PowerOptionAsymmetric
    
EPowerOptionAsymmetric(string OutPutFlag, string CallPutFlag, float S, float X, float T, float r, float b, float v, float i, float dSin)=>
    float dS = dSin
    if na(dS) 
        dS := 0.01
    float EPowerOptionAsymmetric = 0
    if OutPutFlag == "p"  // Value
        EPowerOptionAsymmetric := PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i)

    else if OutPutFlag == "d"  //Delta
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v, i)) / (2 * dS)

    else if OutPutFlag == "e"  //Elasticity
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v, i)) 
             / (2 * dS) * S / PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i)

    else if OutPutFlag == "g"  //Gamma
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v, i)) / math.pow(dS, 2)

    else if OutPutFlag == "gv"  //DGammaDVol
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v + 0.01, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v + 0.01, i) 
             + PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v + 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v - 0.01, i) 
             + 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v - 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v - 0.01, i)) / (2 * 0.01 * math.pow(dS, 2)) / 100

    else if OutPutFlag == "gp"  //GammaP
        EPowerOptionAsymmetric := S / 100 * (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v, i)) / math.pow(dS, 2)

    else if OutPutFlag == "tg"  //time Gamma
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T + 1 / 365, r, b, v, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S, X, T - 1 / 365, r, b, v, i)) / math.pow(1 / 365, 2)

    else if OutPutFlag == "dddv"  //DDeltaDvol
        EPowerOptionAsymmetric := 1 / (4 * dS * 0.01) 
             * (PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v + 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v - 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v + 0.01, i) 
             + PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v - 0.01, i)) / 100

    else if OutPutFlag == "v"  //Vega
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v + 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v - 0.01, i)) / 2
             
    else if OutPutFlag == "vv"  //DvegaDvol/vomma
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v + 0.01, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v - 0.01, i)) / math.pow(0.01, 2) / 10000

    else if OutPutFlag == "vp"  //VegaP
        EPowerOptionAsymmetric := v / 0.1 
             * (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v + 0.01, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v - 0.01, i)) / 2

    else if OutPutFlag == "dvdv"  //DvegaDvol
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v + 0.01, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v - 0.01, i))

    else if OutPutFlag == "t"  //Theta
        if T <= 1 / 365 
            EPowerOptionAsymmetric := PowerOptionAsymmetric(CallPutFlag, S, X, 1E-05, r, b, v, i) 
                 - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i)
        else
            EPowerOptionAsymmetric := PowerOptionAsymmetric(CallPutFlag, S, X, T - 1 / 365, r, b, v, i) 
                 - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i)

    else if OutPutFlag == "r"  //Rho
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r + 0.01, b + 0.01, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r - 0.01, b - 0.01, v, i)) / 2

    else if OutPutFlag == "fr"  //Futures options rho
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r + 0.01, b, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r - 0.01, b, v, i)) / 2

    else if OutPutFlag == "f"  //Rho2
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b - 0.01, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b + 0.01, v, i)) / 2

    else if OutPutFlag == "b"  //Carry
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b + 0.01, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b - 0.01, v, i)) / 2

    else if OutPutFlag == "s"  //Speed
        EPowerOptionAsymmetric := 1 / math.pow(dS, 3) * (PowerOptionAsymmetric(CallPutFlag, S + 2 * dS, X, T, r, b, v, i) 
             - 3 * PowerOptionAsymmetric(CallPutFlag, S + dS, X, T, r, b, v, i) 
             + 3 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S - dS, X, T, r, b, v, i))

    else if OutPutFlag == "dx"  //Strike Delta
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X + dS, T, r, b, v, i) 
             - PowerOptionAsymmetric(CallPutFlag, S, X - dS, T, r, b, v, i)) / (2 * dS)

    else if OutPutFlag == "dxdx"  //Strike Gamma
        EPowerOptionAsymmetric := (PowerOptionAsymmetric(CallPutFlag, S, X + dS, T, r, b, v, i) 
             - 2 * PowerOptionAsymmetric(CallPutFlag, S, X, T, r, b, v, i) 
             + PowerOptionAsymmetric(CallPutFlag, S, X - dS, T, r, b, v, i)) / math.pow(dS, 2)
    EPowerOptionAsymmetric


smthtype = input.string("Kaufman", "Heikin-Ashi Better Caculation Type", options = ["AMA", "T3", "Kaufman"], group = "Spot Price Settings")
srcin = input.string("Close", "Spot Price", group= "Spot Price Settings", 
     options = 
     ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
     "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
     "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"])

float K = input.float(450, "Strike Price", group = "Basic Settings")   
string side = input.string("Long", "Side", options = ["Long", "Short"], group = "Basic Settings")   
string OpType = input.string(callString, "Option type", options = [callString, putString], group = "Basic Settings")   

float r = input.float(8., "% Risk-free Rate", group = "Rates Settings") / 100
string rcmp = input.string(Continuous, "% Risk-free Rate Compounding Type", options = [Continuous, PeriodRate, Annual, SemiAnnual, Quaterly, Monthly], group = "Rates Settings")

float b = input.float(6., "% Cost of Carry", group = "Rates Settings") / 100
string bcmp = input.string(Continuous, "% Cost of Carry Compounding Type", options = [Continuous, PeriodRate, Annual, SemiAnnual, Quaterly, Monthly], group = "Rates Settings")

float v = input.float(25., "% Volatility", group = "Rates Settings") / 100
float i = input.float(2, "Power", group = "Rates Settings")

int histvolper = input.int(22, "Historical Volatility Period", group = "Historical Volatility Settings", tooltip =  "Not used in calculation. This is here for comparison to implied volatility")
string hvoltype = input.string(c2c, "Historical Volatility Type", options = [c2c, gkvol, gkzhvol, rogersatch, ewmavolstr, parkinson], group = "Historical Volatility Settings")

string timein = input.string("Time Now", title = "Time Now Type", options = ["Time Now", "Time Bar", "Trading Day"], group = "Time Intrevals", tooltip = timtoolnow + "; " + timtoolbar + "; " + timetooltrade)
int daysinyear = input.int(252, title = "Days in Year", minval = 1, maxval = 365, group = "Time Intrevals", tooltip = "Typically 252 or 365")
float hoursinday = input.float(24, title = "Hours Per Day", minval = 1, maxval = 24, group = "Time Intrevals", tooltip = "Typically 6.5, 8, or 24")

int thruMonth = input.int(3, title = "Expiry Month", minval = 1, maxval = 12, group = "Expiry Date/Time")
int thruDay = input.int(31, title = "Expiry Day", minval = 1, maxval = 31, group = "Expiry Date/Time")
int thruYear = input.int(2023, title = "Expiry Year", minval = 1970, group = "Expiry Date/Time")
int mins = input.int(0, title = "Expiry Minute", minval = 0, maxval = 60, group = "Expiry Date/Time")
int hours = input.int(9, title = "Expiry Hour", minval = 0, maxval = 24, group = "Expiry Date/Time")
int secs = input.int(0, title = "Expiry Second", minval = 0, maxval = 60, group = "Expiry Date/Time")

string txtsize = input.string("Auto", title = "Expiry Second", options = ["Small", "Normal", "Tiny", "Auto", "Large"], group = "UI Options")

string outsize = switch txtsize
    "Small"=> size.small
    "Normal"=> size.normal
    "Tiny"=> size.tiny
    "Auto"=> size.auto
    "Large"=> size.large

// seconds per year given inputs above
int spyr = math.round(daysinyear * hoursinday * 60 * 60)

// precision calculation miliseconds in time intreval from time equals now
start = timein == "Time Now" ? timenow : timein == "Time Bar" ? time : time_tradingday
finish = timestamp(thruYear, thruMonth, thruDay, hours, mins, secs) 
temp = (finish - start) 
float T = (finish - start) / spyr / 1000

kfl=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

float rcmpval = switch rcmp
    Continuous=> 0
    PeriodRate=> math.max(1 / T, 1)
    Annual=> 1
    SemiAnnual=> 2
    Quaterly=> 4
    Monthly=> 12
    => 0

float bcmpval = switch bcmp
    Continuous=> 0
    PeriodRate=> math.max(1 / T, 1)
    Annual=> 1
    SemiAnnual=> 2
    Quaterly=> 4
    Monthly=> 12
    => 0

float S = switch srcin
	"Close" => loxxexpandedsourcetypes.rclose()
	"Open" => loxxexpandedsourcetypes.ropen()
	"High" => loxxexpandedsourcetypes.rhigh()
	"Low" => loxxexpandedsourcetypes.rlow()
	"Median" => loxxexpandedsourcetypes.rmedian()
	"Typical" => loxxexpandedsourcetypes.rtypical()
	"Weighted" => loxxexpandedsourcetypes.rweighted()
	"Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
	"Trend Biased" => loxxexpandedsourcetypes.rtrendb()
	"Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
	"HA Close" => loxxexpandedsourcetypes.haclose(haclose)
	"HA Open" => loxxexpandedsourcetypes.haopen(haopen)
	"HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
	"HA Low" => loxxexpandedsourcetypes.halow(halow)
	"HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
	"HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
	"HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
	"HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
    "HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
	"HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
	"HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
	"HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
	"HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
	"HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
	"HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
	"HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
    "HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
	"HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
	"HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
	=> haclose

float hvolout = switch hvoltype
    parkinson => parkinsonvol(histvolper)
    rogersatch => rogerssatchel(histvolper) 
    c2c => closetoclose(math.log(S / nz(S[1])), histvolper) 
    gkvol => garmanKlass(histvolper) 
    gkzhvol => gkyzvol(histvolper) 
    ewmavolstr => ewmavol(math.log(S / nz(S[1])), histvolper) 

if barstate.islast

    sideout = side == "Long" ? 1 : -1

    kouta = convertingToCCRate(r, rcmpval)
    koutb = convertingToCCRate(b, bcmpval)

    amaproxprice        = EPowerOptionAsymmetric("p", OpType, S, K, T, kouta, koutb, v, i, na)
    Delta               = EPowerOptionAsymmetric("d", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Elasticity          = EPowerOptionAsymmetric("e", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Gamma               = EPowerOptionAsymmetric("g", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    DGammaDvol          = EPowerOptionAsymmetric("gv", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    GammaP              = EPowerOptionAsymmetric("gp", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Vega                = EPowerOptionAsymmetric("v", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    DvegaDvol           = EPowerOptionAsymmetric("dvdv", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    VegaP               = EPowerOptionAsymmetric("vp", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Theta               = EPowerOptionAsymmetric("t", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Rho                 = EPowerOptionAsymmetric("r", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    RhoFuturesOption    = EPowerOptionAsymmetric("fr", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    PhiRho2             = EPowerOptionAsymmetric("f", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Carry               = EPowerOptionAsymmetric("b", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    DDeltaDvol          = EPowerOptionAsymmetric("dddv", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    Speed               = EPowerOptionAsymmetric("s", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    StrikeDelta         = EPowerOptionAsymmetric("dx", OpType, S,K, T, kouta, koutb, v, i, na) * sideout
    StrikeGamma         = EPowerOptionAsymmetric("dxdx", OpType, S,K, T, kouta, koutb, v, i, na) * sideout

    var testTable = table.new(position = position.middle_right, columns = 2, rows = 20, bgcolor = color.gray, border_width = 1)

    table.cell(table_id = testTable, column = 0, row = 0, text = "Standard Power Option", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 1, text = "Option Type: " + OpType, bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 2, text = "Side: " + side , bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 3, text = "Spot Price: " + str.tostring(S, format.mintick) , bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 4, text = "Strike Price: " + str.tostring(K, format.mintick), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 5, text = "% Risk-free Rate: " + str.tostring(r * 100, "##.##") + "%\n" + "Compounding Type: " + rcmp + "\nCC Rate: " + str.tostring(kouta * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 6, text = "% Cost of Carry: " + str.tostring(b * 100, "##.##") + "%\n" + "Compounding Type: " + bcmp + "\nCC Carry: " + str.tostring(koutb * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 7, text = "% Volatility (annual): " + str.tostring(v * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 8, text = "Power: " + str.tostring(i, "##.##"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 9, text = "Time Now: " + str.format("{0,date,MMMM dd, yyyy - HH:mm:ss}", timenow), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 10, text = "Expiry Date: " + str.format("{0,date,MMMM dd, yyyy - HH:mm:ss}", finish), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 11, text = "Calculated Values", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 12, text = "Hist. Volatility Type: " + hvoltype, bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 13, text = "Hist. Daily Volatility: " + str.tostring(hvolout * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 14, text = "Hist. Annualized Volatility: " + str.tostring(hvolout * math.sqrt(daysinyear) * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)

    table.cell(table_id = testTable, column = 1, row = 0, text = "Option Ouputs", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 1, text = "Power Contract Value: " + str.tostring(amaproxprice, format.mintick), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 2, text = "Option Sensitivities", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 3, text = "Delta Δ: " + str.tostring(Delta, "##.#####"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 4, text = "Elasticity Λ: " + str.tostring(Elasticity, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 5, text = "Gamma Γ: " + str.tostring(Gamma, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 6, text = "DGammaDvol: " + str.tostring(DGammaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 7, text = "GammaP Γ: " + str.tostring(GammaP, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 8, text = "Vega: " + str.tostring(Vega, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 9, text = "DVegaDvol: " + str.tostring(DvegaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 10, text = "VegaP: " + str.tostring(VegaP, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 11, text = "Theta Θ (1 day): " + str.tostring(Theta, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 12, text = "Rho ρ: " + str.tostring(Rho, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 13, text = "Rho Futures 0ption ρ: " + str.tostring(RhoFuturesOption, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 14, text = "Phi/Rho2: " + str.tostring(PhiRho2, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 15, text = "Carry: " + str.tostring(Carry, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 16, text = "DDeltaDvol: " + str.tostring(DDeltaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 17, text = "Speed: " + str.tostring(Speed, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 18, text = "Strike Delta: " + str.tostring(StrikeDelta, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 19, text = "Strike Gamma: " + str.tostring(StrikeGamma, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
