Firetron HedgedDCADipper - Blazing mod with Grid mode
stableDescription
A mod of FireTron's DCADipper script. Added a minimum price delta option, so the bot will only buy if the price has moved more than the minimum delta. Also added a Grid Mode option, which is a shortcut to setting the interval to 1 minute, and the profit trigger to match the minimum price delta. Grid mode loosely resembles a hedged grid strategy.
HaasScript
-- ============================================================================
-- Firetron's Hedged DCA - Blazing mod with Grid mode
--
-- Runs a long and a short each doing dollar cost averaging strategy.
-- Expands positions on an interval and exits whenever there is a profit.
--
-- Custom Command Dependencies:
-- Firetron's CurrentVsEntry
-- Firetron's FormatRoundedPercent
-- Firetron's FormatRoundedQuoteCurrency
-- Firetron's ReportMaxRiskPoint
-- Firetron's ReportOpenPositions
-- Firetron's TrueOnInterval
--
-- Discord: @FiretronP75
-- ============================================================================
-- ========================================================
-- Configuration
-- ========================================================
EnableHighSpeedUpdates()
HideOrderSettings()
HideTradeAmountSettings()
-- ========================================================
-- Variables
-- ========================================================
local logHRule = '------------------------------------------------------------';
-- ------------------------------------
-- Enumerations
-- ------------------------------------
local booleanOption = {
no = 'No',
yes = 'Yes',
}
local ProfitType = {
marketChange = 'Market Change',
positionROI = 'Position ROI',
}
-- ------------------------------------
-- 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)
-- ------------------------------------
-- Main
-- ------------------------------------
local expandBy = MinimumTradeAmount()
local interval = 1440
local profitTrigger = 10
local profitType = ProfitType.positionROI
local minPriceDelta = 0
local gridMode = false
group = 'Main'
label = '1. Expand By'
tooltip = 'Number of contracts to expand by each interval.'
expandBy = Input(label, expandBy, tooltip, group)
label = '2. Minimum Price Delta (%)'
tooltip = 'Minimum price difference to allow an expansion. 0 to disable'
minPriceDelta = Input(label, minPriceDelta, tooltip, group)
label = '3. Grid Mode'
tooltip = 'Min Price Delta must be set (> 0). Profit Trigger will be automatically set to MinPriceDelta. Interval is ignored'
gridMode = Input(label, gridMode, tooltip, group)
label = '4. Interval'
tooltip = 'Time between position expansions.'
interval = InputInterval(label, interval, tooltip, group)
label = '5. Profit Trigger'
tooltip = 'Percent profit that will trigger an exit.'
profitTrigger = Input(label, profitTrigger, tooltip, group)
label = '6. Profit Type'
tooltip = 'Calculate profit using either position ROI or simple change in market price. In other words, you are specifying whether or not your profit trigger is taking leverage into account or not.'
profitType = InputOptions(label, profitType, ProfitType, tooltip, group)
if gridMode then
if minPriceDelta <= 0 then
LogError('Minimum Price Delta needs to be greater than 0 for Grid Mode')
return
end
profitTrigger = minPriceDelta
profitType = ProfitType.marketChange
interval = 1
end
-- ========================================================
-- Functions
-- ========================================================
-- ------------------------------------
-- Debug
-- ------------------------------------
function GetDebugInfo ()
if isVerbose == booleanOption.no then
return {
isVerbose = false,
}
end
if not CC_TrueOnInterval(verbosityInterval) then
return {
isVerbose = false,
}
end
local currentPrice = CurrentPrice()
return {
baseCurrency = BaseCurrency(),
currentAsk = CC_FormatRoundedQuoteCurrency(currentPrice.ask),
currentBid = CC_FormatRoundedQuoteCurrency(currentPrice.bid),
isVerbose = true,
}
end
-- ------------------------------------
-- Exiting
-- ------------------------------------
function Exit ()
local debugInfo = GetDebugInfo()
ExitCheckLong( debugInfo)
ExitCheckShort(debugInfo)
end
-- ----------------
function ExitCheckLong (debugInfo)
local longProfit
if longPositionId != '' then
longProfit = profitType == ProfitType.positionROI and GetPositionROI(longPositionId) or CC_CurrentVsEntry(longPositionId)
end
if longPositionId == '' then
if debugInfo.isVerbose then
Log(logHRule)
Log('No long position.')
end
elseif longProfit >= profitTrigger then
ExitLong()
elseif debugInfo.isVerbose then
Log(logHRule)
Log('Long profit is '..CC_FormatRoundedPercent(longProfit))
Log(debugInfo.baseCurrency..' bid is @ '..debugInfo.currentBid)
end
end
-- ----------------
function ExitCheckShort (debugInfo)
local shortProfit
if shortPositionId != '' then
shortProfit = profitType == ProfitType.positionROI and GetPositionROI(shortPositionId) or CC_CurrentVsEntry(shortPositionId)
end
if shortPositionId == '' then
if debugInfo.isVerbose then
Log(logHRule)
Log('No short position.')
end
elseif shortProfit >= profitTrigger then
ExitShort()
elseif debugInfo.isVerbose then
Log(logHRule)
Log('Short profit is '..CC_FormatRoundedPercent(shortProfit))
Log(debugInfo.baseCurrency..' ask is @ '..debugInfo.currentAsk)
end
end
-- ----------------
function ExitLong ()
local parameters = {
positionId = longPositionId,
type = MarketOrderType,
}
Log(logHRule)
LogWarning('Taking profit on long.')
PlaceExitPositionOrder(parameters);
longPositionId = ''
Save('longPositionId', '')
end
-- ----------------
function ExitShort ()
local parameters = {
positionId = shortPositionId,
type = MarketOrderType,
}
Log(logHRule)
LogWarning('Taking profit on short.')
PlaceExitPositionOrder(parameters);
shortPositionId = ''
Save('shortPositionId', '')
end
function notEnoughPriceDelta(isVerbose)
local cp = CurrentPrice().close
local lastPrice = Load('LastPrice', 0)
local priceDelta = Abs(Delta(lastPrice, cp))
if lastPrice != 0 and minPriceDelta > 0 and priceDelta < minPriceDelta then
if isVerbose == booleanOption.yes then
Log('Skipping expansion. Last Price: '..lastPrice
..', Current Price: '..cp..', delta: '..CC_FormatRoundedPercent(priceDelta,2,'%'))
end
return true
end
Save('LastPrice', cp)
return false
end
-- ------------------------------------
-- Going
-- ------------------------------------
function Go ()
if notEnoughPriceDelta(isVerbose) then
return
end
if longPositionId == '' then
longPositionId = NewGuid()
Save('longPositionId', longPositionId)
end
Log(logHRule)
GoLong()
if shortPositionId == '' then
shortPositionId = NewGuid()
Save('shortPositionId', shortPositionId)
end
GoShort()
end
-- ----------------
function GoLong ()
local parameters = {
type = MarketOrderType,
positionId = longPositionId,
}
PlaceGoLongOrder(CurrentPrice().bid, expandBy, parameters)
end
-- ----------------
function GoShort ()
local parameters = {
type = MarketOrderType,
positionId = shortPositionId,
}
PlaceGoShortOrder(CurrentPrice().ask, expandBy, parameters)
end
-- ========================================================
-- Execution
-- ========================================================
SetFee(fee)
CC_ReportOpenPositions()
CC_ReportMaxRiskPoint()
Exit()
if gridMode or interval == 1 then
Go()
else
OptimizedForInterval(interval, Go)
end
0 Comments
Sign in to leave a comment.
No comments yet. Be the first!