Firetron’s Quarterly Spread Hedger

2 290 Views 1 Comment 3 months ago
  • Hedges two quarterly markets of the same pair, profiting on their spread.

    Custom Command Dependencies:
    Firetron’s ReportMaxRiskPoint
    Firetron’s ReportOpenPositions
    Firetron’s TrueOnInterval

    • This topic was modified 3 months, 1 week ago by Firetron. Reason: Added dependency hyperlinks
    • This topic was modified 3 months, 1 week ago by Firetron. Reason: Changed InputMarket to InputAccountMarket
    • This topic was modified 3 months, 1 week ago by Firetron. Reason: Changed market inputs to be self-documenting
    • This topic was modified 3 months, 1 week ago by Firetron. Reason: Changed market inputs to be self-documenting
    HaasScript Code
    --  ============================================================================
    --    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
    --    BTC Tips: 14WLDZsrhshcP6qvBarKW8ABACv3iUXEro
    --    ETH Tips: 0xfaaac99fbf11f8f4abc4b3bf079cb2c7a43b5f87
    --  ============================================================================
    
    --  ========================================================
    --    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()
    • #1186
      Firetron
      Basic
      Up
      0
      Down

      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.

Login or Register to Comment

Unlock your crypto trading potential

Create a free account and enjoy everything we have to offer.

Join for Free