Firetron's Quarterly Spread Hedger

stable
By Firetron in Trading Bots Published August 2020 👁 1,682 views 💬 1 comments

Description

Hedges two quarterly markets of the same pair, profiting on their spread. Custom Command Dependencies: Firetron’s ReportMaxRiskPoint Firetron’s ReportOpenPositions Firetron’s TrueOnInterval
HaasScript
--  ============================================================================
--    Firetron's Quarterly Spread Hedger
--
--    Hedges two quarterly markets of the same pair, profiting on their spread.
--
--    Custom Command Dependencies:
--    Firetron's ReportMaxRiskPoint
--    Firetron's ReportOpenPositions
--    Firetron's TrueOnInterval
--
--    Discord:  @FiretronP75
--  ============================================================================

--  ========================================================
--    Configuration
--  ========================================================

EnableHighSpeedUpdates()
HideOrderSettings()

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

local hRule = '---------------------------------------------------------------';

--  ------------------------------------
--    Enumerations
--  ------------------------------------

local booleanOption = {
  no  = 'No',
  yes = 'Yes',
}

--  ------------------------------------
--    Positions
--  ------------------------------------

local longPositionId  = Load('longPositionId',  '')
local shortPositionId = Load('shortPositionId', '')

--  ========================================================
--    Inputs
--  ========================================================

local group   = ''
local label   = ''
local tooltip = ''

--  ------------------------------------
--    Testing
--  ------------------------------------

local fee               = Fee()
local isVerbose         = booleanOption.no
local verbosityInterval = 60

group = ' Testing'

label   = 'Fee Percentage'
tooltip = 'For backtests and simulated trading.'
fee     = Input(label, fee, tooltip, group)

label     = 'Verbose Logging'
tooltip   = 'Log extra details. Will run slower.'
isVerbose = InputOptions(label, isVerbose, booleanOption, tooltip, group)

label             = 'Verbose Logging Interval'
tooltip           = 'Time between verbose logging.'
verbosityInterval = InputInterval(label, verbosityInterval, tooltip, group)

--  ------------------------------------
--    Quarterly Market
--  ------------------------------------

local marketA

group = 'Quarterly Market'

label   = 'Quarterly Market'
tooltip = 'One market should be quarterly the other biquarterly, of the same pair.'
marketA = InputAccountMarket(label, tooltip, group)

--  ------------------------------------
--    Biquarterly Market
--  ------------------------------------

local marketB

group = 'Biquarterly Market'

label   = 'Biquarterly Market'
tooltip = 'One market should be quarterly the other biquarterly, of the same pair.'
marketB = InputAccountMarket(label, tooltip, group)

--  ------------------------------------
--    Spread Triggers
--  ------------------------------------

local enteringDelta = 4
local exitingDelta  = 2

group = 'Spread Triggers'

label         = 'Enter Delta'
tooltip       = 'Enter at this price delta. Should be the larger number.'
enteringDelta = Input(label, enteringDelta, tooltip, group)

label        = 'Exit Delta'
tooltip      = 'Exit at this price delta. Should be the smaller number.'
exitingDelta = Input(label, exitingDelta, tooltip, group)

--  ========================================================
--    Functions
--  ========================================================

--  ------------------------------------
--    Main
--  ------------------------------------

function Main ()

  local currentA = CurrentPrice(marketA)
  local currentB = CurrentPrice(marketB)

  local averageA = Average(currentA.ask, currentA.bid)
  local averageB = Average(currentB.ask, currentB.bid)

  local delta

  if averageA < averageB then
    delta = Delta(averageA, averageB)
  else
    delta = Delta(averageB, averageA)
  end

  if longPositionId != '' and delta <= exitingDelta then

    Log(hRule)
    Log('Delta is '..delta)
    Exit()
    Log(hRule)

  elseif longPositionId == '' and delta >= enteringDelta then

    Log(hRule)
    Log('Delta is '..delta)
    Go(averageA, averageB, currentA, currentB)
    Log(hRule)

  elseif isVerbose == booleanOption.yes and CC_TrueOnInterval(verbosityInterval) then

    Log('Delta is '..delta)

  end

end

--  ------------------------------------
--    Exiting
--  ------------------------------------

function Exit ()

  local parameters = {
    type = MarketOrderType,
  }

  PlaceExitPositionOrder(longPositionId,  parameters)
  PlaceExitPositionOrder(shortPositionId, parameters)

  longPositionId  = ''
  shortPositionId = ''

  Save('longPositionId',  longPositionId)
  Save('shortPositionId', shortPositionId)

end

--  ------------------------------------
--    Going
--  ------------------------------------

function Go (averageA, averageB, currentA, currentB)

  local amount = TradeAmount()

  if averageA > averageB then

    GoShort(currentA, amount, marketA)
    GoLong( currentB, amount, marketB)

  else

    GoLong( currentA, amount, marketA)
    GoShort(currentB, amount, marketB)

  end

end

--  ----------------

function GoLong (current, amount, market)

  longPositionId = NewGuid()
  Save('longPositionId', longPositionId)

  local parameters = {
    type = MarketOrderType,
    positionId = longPositionId,
  }

  Log('Going long on '..market)
  PlaceGoLongOrder(current.ask, amount, market, parameters)

end

--  ----------------

function GoShort (current, amount, market)

  shortPositionId = NewGuid()
  Save('shortPositionId', shortPositionId)

  local parameters = {
    type = MarketOrderType,
    positionId = shortPositionId,
  }

  Log('Going short on '..market)
  PlaceGoShortOrder(current.bid, amount, market, parameters)

end

--  ========================================================
--    Execution
--  ========================================================

SetFee(fee)

CC_ReportOpenPositions()
CC_ReportMaxRiskPoint()

Main()

1 Comment

Sign in to leave a comment.

F
Firetron almost 6 years ago

Won't be able to give it a good test until there is 2 full quarters worth of history on an exchange for 2 different quarterly contracts on the same pair.