Firetron's Basis Hedger
stableDescription
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.
I added inputs for contracts and usdPerContract to convert between how the contracts work.
I reverted the contracts and usdPerContracts inputs, because you should only be using this on the exact same base currency.
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?
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.