Firetron's GetKeltnerSpread

stable
By Firetron in Miscellaneous Published June 2021 👁 1,302 views 💬 0 comments

Description

Creates a spread of prices based on Keltner channels. Custom Command Dependencies: Firetron’s XTR Test Code:
local LogList = function (list)

  local text = ''

  for i = 1, #list do

    if i ~= 1 then
      text = text..', '
    end

    text = text..list[i]

  end

  Log(text)

end

local PlotOne = function (value, color, id, name)

  local lineOptions = LineOptions(
    color,     -- color
    Smooth,    -- style
    Solid,     -- deco
    1,         -- width
    0,         -- offset
    RightAxis, -- side
    id,        -- id
    true,      -- behind
    false      -- ignoreOnAxis
  )

  Plot(0, name, value, lineOptions)

end

local PlotAll = function (list, color, id, name)

  for i = 1, #list do

    PlotOne(list[i], color, id..i, name..i)

  end

end

local Execute = function ()

  local omni           = false
  local maType         = EmaType
  local maPeriod       = 20
  local trType         = 'average'
  local trPeriod       = 50
  local multiplierList = {2, 3, 4, 5}
  local interval       = 60
  local fullCandles    = true
  local market         = PriceMarket()
  local hlcStyle       = false
  local index          = 1
  local total          = 1
  local isPercent      = false

  Log(' ')

  local spread = CC_GetKeltnerSpread(omni, maType, maPeriod, trType, trPeriod, multiplierList, interval, fullCandles, market, hlcStyle, index, total, isPercent)

  LogList(spread.lowerList)
  Log('Lower Spread:')
  Log(' ')

  Log(spread.middle)
  Log('Middle:')
  Log(' ')

  LogList(spread.upperList)
  Log('Upper Spread:')
  Log(' ')

  PlotAll(spread.upperList, Red,    'upper',  'Upper ')
  PlotOne(spread.middle,    Yellow, 'middle', 'Middle')
  PlotAll(spread.lowerList, Green,  'lower',  'Lower ')

end

OptimizedForInterval(60, Execute)
HaasScript
--  ============================================================================
--    Firetron's GetKeltnerSpread
--
--    Creates a spread of prices based on Keltner channels.
--
--    Custom Command Dependencies:
--    Firetron's XTR
--
--    Discord: @FiretronP75
--  ============================================================================

--  ========================================================
--    Variables
--  ========================================================

--  ------------------------------------
--    Definition
--  ------------------------------------

local dDefault
local dDescription
local dIndex
local dName
local dOutput
local dRequired
local dSuggestions
local dType

--  ------------------------------------
--    Enumeration
--  ------------------------------------

local TrueRange = {
  average = 'average',
  maximum = 'maximum',
  median  = 'median',
  minimum = 'minimum',
}

--  ------------------------------------
--    Parameter
--  ------------------------------------

local pFullCandles
local pHlcStyle
local pIndex
local pInterval
local pIsPercent
local pMaPeriod
local pMaType
local pMarket
local pMultiplierList
local pOmni
local pTotal
local pTrPeriod
local pTrType

--  ========================================================
--    Command Definition
--  ========================================================

dName        = 'GetKeltnerSpread'
dDescription = 'Creates a spread of prices based on Keltner channels.'
DefineCommand(dName, dDescription)

--  ========================================================
--    Parameter Definitions
--  ========================================================

dType        = ListDynamicType
dName        = 'omni'
dDescription = 'Set this to the ListDynamicType returned by InputKeltnerSpread. '
             ..'All other parameters will be ignored. '
             ..'Set this to false to use the other parameters.'
dRequired    = false
dDefault     = false
dSuggestions = 'InputKeltnerSpread'
pOmni = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = EnumType
dName        = 'maType'
dDescription = 'The type of moving average to use for the middle.'
dRequired    = false
dDefault     = EmaType
dSuggestions = 'MAEnums'
pMaType = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = NumberType
dName        = 'maPeriod'
dDescription = 'How many intervals to go back for the moving average.'
dRequired    = false
dDefault     = 20
dSuggestions = 'Input'
pMaPeriod = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = StringType
dName        = 'trType'
dDescription = '"average" for average true range, "maximum" for maximum true range, "median" for median true range, "minimum" for minimum true range.'
dRequired    = false
dDefault     = TrueRange.average
dSuggestions = 'Input'
pTrType = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = NumberType
dName        = 'trPeriod'
dDescription = 'How many intervals to go back for the average true range.'
dRequired    = false
dDefault     = 10
dSuggestions = 'Input'
pTrPeriod = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = ListDynamicType
dName        = 'multiplierList'
dDescription = 'Each Keltner multiplier will create a price in the spread.'
dRequired    = false
dDefault     = {2, 3, 4, 5}
dSuggestions = 'Input'
pMultiplierList = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = NumberType
dName        = 'interval'
dDescription = 'Time of each candle in minutes.'
dRequired    = false
dDefault     = 60
dSuggestions = 'InputInterval'
pInterval = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = BooleanType
dName        = 'fullCandles'
dDescription = 'If false, the currently open candle will not be included.'
dRequired    = false
dDefault     = true
dSuggestions = 'Input'
pFullCandles = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = StringType
dName        = 'market'
dDescription = 'Which market to look at.'
dRequired    = false
dDefault     = PriceMarket()
dSuggestions = 'InputAccountMarket, InputMarket, PriceMarket'
pMarket = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = BooleanType
dName        = 'hlcStyle'
dDescription = 'When enabled, the data returned will be adjusted for HLC instead of OHLC. Meaning that the OHL data can change.'
dRequired    = false
dDefault     = false
dSuggestions = 'Input'
pHlcStyle = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = NumberType
dName        = 'index'
dDescription = 'Which part to grab. '
             ..'Unlike a fraction numerator, previous parts are not included. '
             ..'In a fraction, 2 would mean 1st and 2nd parts combined. '
             ..'But here, 2 would mean the 2nd part without the 1st.'
dRequired    = false
dDefault     = 1
dSuggestions = 'Input'
pIndex = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = NumberType
dName        = 'total'
dDescription = 'How many parts to divide into. '
             ..'This is just like a fraction denominator.'
dRequired    = false
dDefault     = 1
dSuggestions = 'Input'
pTotal = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = BooleanType
dName        = 'isPercent'
dDescription = 'If true, the true percent range will be used.'
dRequired    = false
dDefault     = false
dSuggestions = 'Input'
pIsPercent = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

--  ========================================================
--    Parameter Overrides
--  ========================================================

if pOmni ~= false then

  pFullCandles    = pOmni.fullCandles
  pHlcStyle       = pOmni.hlcStyle
  pIndex          = pOmni.index
  pInterval       = pOmni.interval
  pIsPercent      = pOmni.isPercent
  pMaPeriod       = pOmni.maPeriod
  pMarket         = pOmni.market
  pMaType         = pOmni.maType
  pMultiplierList = pOmni.multiplierList
  pTotal          = pOmni.total
  pTrPeriod       = pOmni.trPeriod
  pTrType         = pOmni.trType

end

--  ========================================================
--    Function
--  ========================================================

local GetKeltnerSpread = function ()

  local closeList = ClosePrices(pInterval, pFullCandles, pMarket, pHlcStyle)

  local ma = ArrayGet(MA(closeList, pMaPeriod, pMaType), 1)

  local tr = CC_XTR(pTrType, pTrPeriod, pInterval, pFullCandles, pMarket, pHlcStyle, pIndex, pTotal, pIsPercent)

  local lowerList = {}
  local upperList = {}

  for i = 1, #pMultiplierList do

    local channel = tr * pMultiplierList[i]

    if pIsPercent then

      lowerList[i] = SubPercentage(ma, channel * 100)
      upperList[i] = AddPercentage(ma, channel * 100)

    else

      lowerList[i] = ma - channel
      upperList[i] = ma + channel

    end

  end

  return {
    upperList = upperList,
    middle    = ma,
    lowerList = lowerList,
  }

end

--  ========================================================
--    Output Definition
--  ========================================================

DefineIntervalOptimization(pInterval)

dType        = ListDynamicType
dOutput      = GetKeltnerSpread()
dDescription = 'ListDynamic with named elements.'
dSuggestions = 'Trade'
DefineOutput(dType, dOutput, dDescription, dSuggestions)

dIndex       = 1
dType        = ListNumberType
dName        = 'upperList'
dDescription = 'List of channels above the moving average.'
DefineOutputIndex(dIndex, dType, dName, dDescription, dSuggestions)

dIndex       = 2
dType        = NumberType
dName        = 'middle'
dDescription = 'The moving average.'
DefineOutputIndex(dIndex, dType, dName, dDescription, dSuggestions)

dIndex       = 3
dType        = ListNumberType
dName        = 'lowerList'
dDescription = 'List of channels below the moving average.'
DefineOutputIndex(dIndex, dType, dName, dDescription, dSuggestions)

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!