To trust or not to trust – the benefits of a discretionary (family) trust for minimising CGT

Discretionary or family trust is a trust where the income generated in the trust can be distributed to the beneficiaries at the discretion of the trustee, or simply the income can be divided up however one pleases.

It is commonly known that a discretionary trust can be used as a form of tax minimisation, but to what extent is a trust beneficial.

In this example I will look at a simple case, a married couple with an investment property that has had a capital gains tax trigger. One person works with a salary of $100,000 a year while the other doesn’t. Logical sense would suggest that a trust would be beneficial in this situation since the capital gain can be distributed to the person with the lowest income, the person not working.

For the below charts I have calculated the tax of a 50-50 split and the tax of a discretionary trust from a capital gain from zero to $1,000,000 incremented by $10,000. One of the persons has a salary of $100,000.

First a direct comparison, it can be observed that up to around $400,000 that the 50-50 split pays slightly more tax, after $400,000 the tax is exactly the same. The reasons for this is the upper limit of the maximum tax threshold for an individual is $180,000, for two people it is $360,000, therefore when this is reached, it doesn’t matter whether it is a direct 50-50 split or a discretionary trust, the capital gains tax will be exactly the same.

Trust vs 50-50 split and CGT

Zoomed in to the zero to $400,000 range, it looks like there are some definite benefits to a discretionary trust.

Trust vs 50-50 split and CGT

Let’s look at the difference between the two scenarios in tax paid, a positive value is how much a discretionary trust minimises tax compared to a 50-50 split. It can be observed that a maximum of $4000 is saved when the capital gain is $260,000, not much of a saving. Further, as per above, at capital gain greater than $360,000 there is no difference.

Trust vs 50-50 split difference

Now one of the problems with a discretionary trust is the yearly management and compliance costs, let’s assume this is $1,000. Let’s add this to the differences chart. As expected this shifts everything down by $1,000.

Trust vs 50-50 split difference with management fees

And what this does is makes a trust scenario a bad choice for any capital gains greater than $360,000.

So what does this mean, simply, in the above situation a discretionary trust does not provide any significant benefits for capital gains tax minimisation compared to a 50-50 split.

One also needs to take into consideration the cumulative costs associated with a trust. If a property is held in a trust for four years, this is $4,000 of cumulative yearly costs which negates any benefits of a discretionary trust.

Further, if both parties are not working, there will be a disadvantage with a discretionary trust due to the yearly costs.

A discretionary trust may be beneficial for positively geared investment properties, and I will discuss this later on. But when asked the question, should I purchase an investment property into a discretionary trust to minimise future capital gains tax, it makes no difference as the CGT is relatively the same.

I will also add, what about a married couple with children, surely I can distribute the capital gains within my family, yes you can, but minors (children under the age of eighteen) are taxed at the highest tax bracket, so it is beneficial only when the beneficiaries are adults.

Next I will investigate the benefits of a discretionary trust for minimising annual income tax.

SplitExtended – improved VB split function with group characters

Based on SplitEx by Chip Pearson, SplitExtended is optimised to be over double the speed, with fixes and additional features;

Features over the standard VB Split are;

  • grouping characters, no longer split strings in quotes,
  • ignore consecutive delimiters, while preserving those in  grouping characters,
  • option to remove grouping characters, start and end quotes can be removed, and
  • double grouping characters inside a grouping character is converted to single grouping characters, double quotes inside quotes are converted to single quotes.

Download modSplitExtended.bas

Code here;

Option Explicit

'====================================================================================
' SplitExtended
' By Travis Hydzik
'
' Based on SplitEx by Chip Pearson http://www.cpearson.com/Excel/Split.aspx
'
' Improvements include;
' - over double the speed of SplitEx
' - doesn't remove double Delimiters in groups
' - double GroupChar in groups treated as escaped and converted to single
'====================================================================================
Public Function SplitExtended(ByRef InString As String, _
    ByVal Delimiter As String, _
    Optional ByVal GroupChar As String = vbNullString, _
    Optional ByVal IgnoreConsecutiveDelimiters As Boolean = False, _
    Optional ByVal DeleteGroupCharacters As Boolean = False) As String()

    Dim arr() As String

    Dim InGroupReplace As String
    Dim consectGroupReplace As String

    Dim S As String

    S = InString
    Dim i As Long, j As Long

    If LenB(S) = 0 Then
        'string is empty so return an unbound array (similar to original Split)
    ElseIf LenB(Delimiter) = 0 Then
        'Delimiter is empty so return an array with the first element the string
        ReDim arr(0)
        arr(0) = S
    ElseIf InStrB(1, S, Delimiter, vbBinaryCompare) = 0 Then
        'Delimiter is not found in the string, return an array with the first element of the string
        ReDim arr(0)
        arr(0) = S
    Else

        'find a unique character in string s, that isn't the Delimiter
        'it can be unique AND the group character as this means there won't be any grouping
        i = -1
        Do While LenB(InGroupReplace) = 0
            i = i + 1
            'the character is unique
            If InStrB(1, S, ChrW$(i), vbBinaryCompare) = 0 Then
                'the character is not the delimiter
                If StrComp(ChrW$(i), Delimiter, vbBinaryCompare) <> 0 Then
                    InGroupReplace = ChrW$(i)
                End If
            End If
        Loop

        'if DeleteGroupCharacters is enabled, it is common to double the GroupChar if that character is needed
        'replace all consecutive group characters with consectGroupReplace
        If DeleteGroupCharacters Then
            'only if there are consecutive GroupChar
            If InStrB(1, S, GroupChar & GroupChar, vbBinaryCompare) > 0 Then
                'find a unique character in string s, that isn't the Delimiter and isn't inGroupReplace
                Do While LenB(consectGroupReplace) = 0
                    i = i + 1
                    'the character is unique
                    If InStrB(1, S, ChrW$(i), vbBinaryCompare) = 0 Then
                        'the character is not the delimiter
                        If StrComp(ChrW$(i), Delimiter, vbBinaryCompare) <> 0 Then
                            'the character is not the GroupChar
                            If StrComp(ChrW$(i), GroupChar, vbBinaryCompare) <> 0 Then
                                consectGroupReplace = ChrW$(i)
                            End If
                        End If
                    End If
                Loop

                'once the character is found, replace all double GroupChar
                S = Replace(S, GroupChar & GroupChar, consectGroupReplace, 1, -1)
            End If
        End If

        'replace any Delimiter occuring in a group with inGroupReplace
        i = InStr(1, S, GroupChar, vbBinaryCompare)
        j = InStr(i + Len(GroupChar), S, GroupChar, vbBinaryCompare)
        Do While i > 0 And j > 0
            If j > i Then
                'mid$(s, 1, i) = Replace(mid$(s, 1, i), Delimiter, inGroupReplace, 1, -1, vbBinaryCompare)
                'mid$(s, j) = Replace(mid$(s, j), Delimiter, inGroupReplace, 1, -1, vbBinaryCompare)
                Mid$(S, i, j - i) = Replace(Mid$(S, i, j - i), Delimiter, InGroupReplace, 1, -1, vbBinaryCompare)
            Else
                S = Replace(S, Delimiter, InGroupReplace, 1, -1, vbBinaryCompare)
            End If

            i = InStr(j + Len(GroupChar), S, GroupChar, vbBinaryCompare)
            j = InStr(i + Len(GroupChar), S, GroupChar, vbBinaryCompare)
        Loop

        'remove any consecutive delimiters, iteratively
        If IgnoreConsecutiveDelimiters Then
            Do While InStrB(1, S, Delimiter & Delimiter, vbBinaryCompare) > 0
                S = Replace(S, Delimiter & Delimiter, Delimiter, 1, -1, vbBinaryCompare)
            Loop
        End If

        'perform the split
        arr = Split(S, Delimiter, -1, vbBinaryCompare)

        'loop through the array and restore the special characters
        For i = 0 To UBound(arr)
            If InStrB(1, arr(i), InGroupReplace, vbBinaryCompare) > 0 Then
                arr(i) = Replace(arr(i), InGroupReplace, Delimiter, 1, -1, vbBinaryCompare)
            End If
            If DeleteGroupCharacters Then
                If InStrB(1, arr(i), GroupChar, vbBinaryCompare) > 0 Then
                    arr(i) = Replace(arr(i), GroupChar, vbNullString, 1, -1, vbBinaryCompare)
                End If
                If InStrB(1, arr(i), consectGroupReplace, vbBinaryCompare) > 0 Then
                    arr(i) = Replace(arr(i), consectGroupReplace, GroupChar, 1, -1, vbBinaryCompare)
                End If
            End If
        Next i
    End If

    SplitExtended = arr

End Function