Firetron's Quarterly Spread Hedger
stableDescription
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.
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.