Exemple #1
0
def test_two_periods_realized_drawdown_v3():
    """Given multiple trades, creating one drawdown period, realized
    drawdown should be the drawdown of the entire period"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=6, high=6, low=6, close=6, volume=1, buy=1, sell=0) \
        .add_entry(open=6, high=6, low=4, close=4, volume=1, buy=0, sell=1) \
        .add_entry(open=4, high=4, low=4, close=4, volume=1, buy=1, sell=0) \
        .add_entry(open=4, high=5, low=4, close=5, volume=1, buy=0, sell=1) \
        .add_entry(open=5, high=5, low=5, close=5, volume=1, buy=1, sell=0) \
        .add_entry(open=5, high=5, low=2, close=2, volume=1, buy=0, sell=1) \

    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=6, high=6, low=6, close=6, volume=1, buy=1, sell=0) \
        .add_entry(open=6, high=6, low=4, close=4, volume=1, buy=0, sell=1) \
        .add_entry(open=4, high=4, low=4, close=4, volume=1, buy=1, sell=0) \
        .add_entry(open=4, high=5, low=4, close=5, volume=1, buy=0, sell=1) \
        .add_entry(open=5, high=5, low=5, close=5, volume=1, buy=1, sell=0) \
        .add_entry(open=5, high=5, low=2, close=2, volume=1, buy=0, sell=1) \

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.max_realised_drawdown, -68.617328354)
Exemple #2
0
def test_two_periods_realized_drawdown_v2():
    """Given multiple trades, creating two separate drawdown
    periods, realized drawdown should be the drawdown of the biggest drawdown
    period"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=4, high=4, low=4, close=4, volume=1, buy=1, sell=0) \
        .add_entry(open=4, high=4, low=1, close=1, volume=1, buy=0, sell=1) \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=5, low=1, close=5, volume=1, buy=0, sell=1) \
        .add_entry(open=5, high=5, low=5, close=5, volume=1, buy=1, sell=0) \
        .add_entry(open=5, high=5, low=3, close=3, volume=1, buy=0, sell=1) \
        .add_entry(open=3, high=3, low=3, close=3, volume=1, buy=1, sell=0) \
        .add_entry(open=3, high=6, low=3, close=6, volume=1, buy=0, sell=1)

    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=4, high=4, low=4, close=4, volume=1, buy=1, sell=0) \
        .add_entry(open=4, high=4, low=1, close=1, volume=1, buy=0, sell=1) \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=5, low=1, close=5, volume=1, buy=0, sell=1) \
        .add_entry(open=5, high=5, low=5, close=5, volume=1, buy=1, sell=0) \
        .add_entry(open=5, high=5, low=3, close=3, volume=1, buy=0, sell=1) \
        .add_entry(open=3, high=3, low=3, close=3, volume=1, buy=1, sell=0) \
        .add_entry(open=3, high=6, low=3, close=6, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.max_realised_drawdown, -75.4975)
Exemple #3
0
def test_capital():
    """Given 'value of coin rises', 'capital' should 'rise same minus fee'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.end_capital == 196.02
Exemple #4
0
def test_profit_percentage():
    """Given 'capital rises', 'profit_percentage' should 'rise accordingly'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.overall_profit_percentage, 96.02)
Exemple #5
0
def test_negative_best_worst_trade():
    """Given one negative trade, 'worst trade' should be trade profit,
    best trade should be 0"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.max_win_single_trade, 0)
    assert math.isclose(stats.main_results.max_drawdown_single_trade, -50.995)
Exemple #6
0
def test_fee():
    """Given 'multiple trades', 'fee' should 'be actual'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .multiply_price(1, TradeAction.BUY)\
        .multiply_price(2, TradeAction.SELL) \
        .multiply_price(1, TradeAction.BUY) \
        .multiply_price(2, TradeAction.SELL)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.total_fee_amount, 8.821396)
Exemple #7
0
def test_dynamic_stoploss_high():
    """Given 'dynamic stoploss higher than open',
    'end capital' should 'represent sold on stoploss price'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.trading_module_config.stoploss_type = "dynamic"

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0, stoploss=1) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=0, stoploss=3)
    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.end_capital == 98.01
Exemple #8
0
def test_roi():
    """given `value of coin rises over ROI limit` should sell at ROI price"""
    # arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=0) \
        .add_entry(open=2, high=3, low=2, close=2, volume=1, buy=0, sell=0)

    fixture.trading_module_config.roi = {"0": 150}

    # act
    stats = fixture.create().analyze()

    # assert
    assert stats.main_results.end_capital == 245.025
Exemple #9
0
def test_stoploss():
    """Given 'value of coin falls below stoploss', 'profit' should 'lower same minus fee'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=1)

    fixture.trading_module_config.stoploss = -25
    fixture.stats_config.stoploss = -25

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.end_capital == 73.5075
Exemple #10
0
def test_fee_downwards():
    """Given 'price goes down', 'fee' should 'be actual'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .multiply_price(1, TradeAction.BUY)\
        .multiply_price(0.5, TradeAction.SELL) \

    fixture.trading_module_config.roi = {
        "0": 100
    }
    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.total_fee_amount, 1.495)
Exemple #11
0
def test_simple_realized_drawdown():
    """Given 'sell at half value', 'realized drawdown' should 'be half'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=1)
    
    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1.5, close=1.5, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.max_realised_drawdown, -38.74375)
Exemple #12
0
def test_simple_no_realized_drawdown():
    """Given 'no drawdown trades', 'realized drawdown' should 'none'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1)
    
    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.max_realised_drawdown, 0)
Exemple #13
0
def test_both_roi_stoploss():
    """given 'both ROI and stoploss triggered single OHLCV candle' should 'close trade for open price'"""
    # arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=0.1, close=2, volume=1, buy=0, sell=0)

    fixture.trading_module_config.roi = {"0": 50}

    fixture.trading_module_config.stoploss = -50
    fixture.stats_config.stoploss = -50

    # act
    stats = fixture.create().analyze()

    # assert
    assert stats.main_results.end_capital == 98.01
Exemple #14
0
def test_roi_set_not_reached():
    """Given 'multiple roi reached and multiple buys', 'capital' should 'reflect expected value'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .multiply_price(2, TradeAction.BUY) \
        .multiply_price(2, TradeAction.SELL) \
        .multiply_price(2, TradeAction.BUY) \
        .multiply_price(2, TradeAction.SELL)

    fixture.trading_module_config.roi = {
        "0": 1.5 * 100
    }

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert math.isclose(stats.main_results.end_capital, 384.238404)
Exemple #15
0
def test_roi_reached_multiple_times():
    """Given 'multiple roi reached and multiple buys', 'capital' should 'reflect expected value'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE'])

    fixture.frame_with_signals['COIN/BASE']\
        .multiply_price(2, TradeAction.BUY)\
        .multiply_price(2)\
        .multiply_price(2, TradeAction.BUY) \
        .multiply_price(2)

    fixture.trading_module_config.roi = {
        "0": 10
    }

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.end_capital == 116.23211721000003
Exemple #16
0
def test_dividing_assets():
    """Given 'multiple assets', '' should 'rise same minus fee'"""
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE'])

    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=0)

    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=0)

    fixture.trading_module_config.stoploss = 25
    fixture.stats_config.stoploss = 25

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.end_capital == 73.5075
Exemple #17
0
def test_n_trades():
    """Given 'trades where made', 
    'number of trades' should 'display correct amount' """
    # Arrange
    fixture = StatsFixture(['COIN/BASE', 'COIN2/BASE', 'COIN3/BASE'])

    # Win/Loss/Open
    fixture.frame_with_signals['COIN/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1) \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=1) \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0)

    # Win/Win/Open
    fixture.frame_with_signals['COIN2/BASE'] \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0) \
        .add_entry(open=1, high=2, low=1, close=2, volume=1, buy=0, sell=1) \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=3, low=2, close=3, volume=1, buy=0, sell=1) \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0)

    # Loss/Loss/Open
    fixture.frame_with_signals['COIN3/BASE'] \
        .add_entry(open=3, high=3, low=3, close=3, volume=1, buy=1, sell=0) \
        .add_entry(open=3, high=3, low=2, close=2, volume=1, buy=0, sell=1) \
        .add_entry(open=2, high=2, low=2, close=2, volume=1, buy=1, sell=0) \
        .add_entry(open=2, high=2, low=1, close=1, volume=1, buy=0, sell=1) \
        .add_entry(open=1, high=1, low=1, close=1, volume=1, buy=1, sell=0)

    # Act
    stats = fixture.create().analyze()

    # Assert
    assert stats.main_results.n_trades == 9
    assert stats.main_results.n_left_open_trades == 3
    assert stats.main_results.n_trades_with_loss == 3
    assert stats.main_results.n_consecutive_losses == 2