def outer_split(expression, sep='()'):
    """ Splits given ``expression`` by outer most separators.

        >>> outer_split('123')
        ['123']
        >>> outer_split('123(45(67)89)123(45)67')
        ['123', '45(67)89', '123', '45', '67']

        If expression is not balanced raises ``ValueError``.

        >>> outer_split('123(') # doctest: +ELLIPSIS
        Traceback (most recent call last):
            ...
        ValueError: ...
    """
    assert 2 == len(sep)
    start_sep, end_sep = sep
    start_count = end_count = 0
    parts = []
    part = ''
    for token in expression:
        if token == start_sep:
            if start_count == end_count:
                parts.append(part)
                part = ''
                start_count += 1
                continue
            start_count += 1
        elif token == end_sep:
            end_count += 1
            if start_count == end_count:
                parts.append(part)
                part = ''
                continue
        part += token
    if start_count != end_count:
        raise ValueError('Expression is not balanced')
    parts.append(part)
    return parts