Firetron’s Basis Hedger

1 295 Views 2 Comments 2 months ago
  • Hedges a quarterly and perpetual market of the same pair, profiting on the basis.

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

    • This topic was modified 1 month, 2 weeks ago by Firetron. Reason: Added inputs for contracts and usdPerContract
    • This topic was modified 1 month, 2 weeks ago by Firetron. Reason: Reverted contracts and usdPerContracts inputs
    HaasScript Code
    --  ============================================================================
    --    Firetron's Basis Hedger
    --
    --    Hedges a quarterly and perpetual market of the same pair, profiting on the
    --    basis.
    --
    --    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)
    
    --  ------------------------------------
    --    Perpetual Market
    --  ------------------------------------
    
    local marketA
    
    group = 'Perpetual Market'
    
    label   = 'Perpetual Market'
    tooltip = 'One market should be perpetual the other quarterly, of the same pair.'
    marketA = InputAccountMarket(label, tooltip, group)
    
    --  ------------------------------------
    --    Quarterly Market
    --  ------------------------------------
    
    local marketB
    
    group = 'Quarterly Market'
    
    label   = 'Quarterly Market'
    tooltip = 'One market should be perpetual the other quarterly, of the same pair.'
    marketB = InputAccountMarket(label, tooltip, group)
    
    --  ------------------------------------
    --    Basis Triggers
    --  ------------------------------------
    
    local enteringBasis = 2
    local exitingBasis  = 1
    
    group = 'Basis Triggers'
    
    label         = 'Enter Basis'
    tooltip       = 'Enter at this price basis. Should be the larger number. (positive only)'
    enteringBasis = Input(label, enteringBasis, tooltip, group)
    
    label        = 'Exit Basis'
    tooltip      = 'Exit at this price basis. Should be the smaller number. (positive only)'
    exitingBasis = Input(label, exitingBasis, 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 basis
    
      if averageA < averageB then
        basis = Delta(averageA, averageB)
      else
        basis = Delta(averageB, averageA)
      end
    
      if longPositionId != '' and basis <= exitingBasis then
    
        Log(hRule)
        Log('Basis is '..basis)
        Exit()
        Log(hRule)
    
      elseif longPositionId == '' and basis >= enteringBasis then
    
        Log(hRule)
        Log('Basis is '..basis)
        Go(averageA, averageB, currentA, currentB)
        Log(hRule)
    
      elseif isVerbose == booleanOption.yes and CC_TrueOnInterval(verbosityInterval) then
    
        Log('Basis is '..basis)
    
      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()
    • #1189
      Firetron
      Basic
      Up
      0
      Down

      I added inputs for contracts and usdPerContract to convert between how the contracts work.

      • This reply was modified 1 month, 2 weeks ago by Firetron.
    • #1198
      Firetron
      Basic
      Up
      0
      Down

      I reverted the contracts and usdPerContracts inputs, because you should only be using this on the exact same base currency.

Login or Register to Comment

Unlock your crypto trading potential

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

Join for Free