Firetron's Basis Hedger

stable
By Firetron in Trading Bots Published August 2020 👁 2,152 views 💬 4 comments

Description

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
HaasScript
--  ============================================================================
--    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
--  ============================================================================

--  ========================================================
--    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()

4 Comments

Sign in to leave a comment.

F
Firetron almost 6 years ago

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

F
Firetron almost 6 years ago

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

S
SerumScalperStale over 2 years ago

It really works arbitrage. But when I'm in plus 0,5 % or more why bot doesn't close the 2 positions and start a new 2 orders?

F
Firetron over 2 years ago

The bot closes positions the same way it opens them. It is all about how close or far apart the two markets are. By default, positions are opened when the markets have a delta of 2 and closed when the markets have a delta of 1.