Firetron’s Hedged DCA

4 217 Views 3 Comments 2 months ago
  • 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

    • This topic was modified 1 month, 3 weeks ago by Firetron. Reason: Changed default settings
    • This topic was modified 1 month, 3 weeks ago by Firetron. Reason: Added more commands to the dependency list
    • This topic was modified 1 month, 3 weeks ago by Firetron. Reason: Broke up Exit function into smaller functions. Added Verbose Interval input to control frequency of verbose logging
    • This topic was modified 1 month, 3 weeks ago by Firetron. Reason: Added hyperlinks to commands
    HaasScript Code
    --  ============================================================================
    --    Firetron's Hedged DCA
    --
    --    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
    --    BTC Tips: 14WLDZsrhshcP6qvBarKW8ABACv3iUXEro
    --    ETH Tips: 0xfaaac99fbf11f8f4abc4b3bf079cb2c7a43b5f87
    --  ============================================================================
    
    --  ========================================================
    --    Configuration
    --  ========================================================
    
    EnableHighSpeedUpdates()
    HideOrderSettings()
    HideTradeAmountSettings()
    
    --  ========================================================
    --    Variables
    --  ========================================================
    
    local logHRule = '------------------------------------------------------------';
    
    --  ------------------------------------
    --    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)
    
    --  ------------------------------------
    --    Main
    --  ------------------------------------
    
    local expandBy      = MinimumTradeAmount()
    local interval      = 1440
    local profitTrigger = 10
    
    group = 'Main'
    
    label    = 'Expand By'
    tooltip  = 'Number of contracts to expand by each interval.'
    expandBy = Input(label, expandBy, tooltip, group)
    
    label    = 'Interval'
    tooltip  = 'Time between position expansions.'
    interval = InputInterval(label, interval, tooltip, group)
    
    label         = 'Profit Trigger'
    tooltip       = 'Percent profit that will trigger an exit.'
    profitTrigger = Input(label, profitTrigger, tooltip, group)
    
    --  ========================================================
    --    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 = 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 = 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);
      Save('longPositionId', '')
    
    end
    
    --  ----------------
    
    function ExitShort ()
    
      local parameters = {
        positionId = shortPositionId,
        type = MarketOrderType,
      }
    
      Log(logHRule)
      LogWarning('Taking profit on short.')
      PlaceExitPositionOrder(parameters);
      Save('shortPositionId', '')
    
    end
    
    --  ------------------------------------
    --    Going
    --  ------------------------------------
    
    function Go ()
    
      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(0, expandBy, parameters)
    
    end
    
    --  ----------------
    
    function GoShort ()
    
      local parameters = {
        type = MarketOrderType,
        positionId = shortPositionId,
      }
    
      PlaceGoShortOrder(0, expandBy, parameters)
    
    end
    
    --  ========================================================
    --    Execution
    --  ========================================================
    
    SetFee(fee)
    
    CC_ReportOpenPositions()
    CC_ReportMaxRiskPoint()
    
    Exit()
    OptimizedForInterval(interval, Go)
    • #1133
      pshai
      Admin
      Up
      1
      Down

      MAN! You got some elegant code going on with this one. Beautiful! Great work!

    • #1134
      Up
      1
      Down

      Additional Dependencies Required
      Firetron’s ReportMaxRiskPoint
      Firetron’s ReportOpenPositions

    • #1135
      Firetron
      Basic
      Up
      0
      Down

      Thanks Rusty I will add that to the description.

Login or Register to Comment

Unlock your crypto trading potential

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

Join for Free