Ejemplo n.º 1
0
def test__send_msg_with_json_format(default_conf, mocker, caplog):
    default_conf["webhook"] = get_webhook_dict()
    default_conf["webhook"]["format"] = "json"
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
    msg = {'text': 'Hello'}
    post = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.post", post)
    webhook._send_msg(msg)

    assert post.call_args[1] == {'json': msg}
Ejemplo n.º 2
0
def test__send_msg_with_raw_format(default_conf, mocker, caplog):
    default_conf["webhook"] = get_webhook_dict()
    default_conf["webhook"]["format"] = "raw"
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
    msg = {'data': 'Hello'}
    post = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.post", post)
    webhook._send_msg(msg)

    assert post.call_args[1] == {'data': msg['data'], 'headers': {'Content-Type': 'text/plain'}}
Ejemplo n.º 3
0
def test_exception_send_msg(default_conf, mocker, caplog):
    default_conf["webhook"] = get_webhook_dict()
    del default_conf["webhook"]["webhookentry"]

    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)),
                      default_conf)
    webhook.send_msg({'type': RPCMessageType.ENTRY})
    assert log_has(
        f"Message type '{RPCMessageType.ENTRY}' not configured for webhooks",
        caplog)

    default_conf["webhook"] = get_webhook_dict()
    default_conf["webhook"]["webhookentry"]["value1"] = "{DEADBEEF:8f}"
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)),
                      default_conf)
    msg = {
        'type': RPCMessageType.ENTRY,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'limit': 0.005,
        'order_type': 'limit',
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg)
    assert log_has(
        "Problem calling Webhook. Please check your webhook configuration. "
        "Exception: 'DEADBEEF'", caplog)

    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {'type': 'DEADBEEF', 'status': 'whatever'}
    with pytest.raises(NotImplementedError):
        webhook.send_msg(msg)
Ejemplo n.º 4
0
def test_exception_send_msg(default_conf, mocker, caplog):
    default_conf["webhook"] = get_webhook_dict()
    default_conf["webhook"]["webhookbuy"] = None

    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION})
    assert log_has(
        f"Message type {RPCMessageType.BUY_NOTIFICATION} not configured for webhooks",
        caplog.record_tuples)

    default_conf["webhook"] = get_webhook_dict()
    default_conf["webhook"]["webhookbuy"]["value1"] = "{DEADBEEF:8f}"
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    msg = {
        'type': RPCMessageType.BUY_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'market_url': "http://mockedurl/ETH_BTC",
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg)
    assert log_has(
        "Problem calling Webhook. Please check your webhook configuration. "
        "Exception: 'DEADBEEF'", caplog.record_tuples)

    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {'type': 'DEADBEEF', 'status': 'whatever'}
    with pytest.raises(NotImplementedError):
        webhook.send_msg(msg)
Ejemplo n.º 5
0
    def __init__(self, freqtrade) -> None:
        """ Initializes all enabled rpc modules """
        self.registered_modules: List[RPC] = []

        # Enable telegram
        if freqtrade.config['telegram'].get('enabled', False):
            logger.info('Enabling rpc.telegram ...')
            from freqtrade.rpc.telegram import Telegram
            self.registered_modules.append(Telegram(freqtrade))

        # Enable Webhook
        if freqtrade.config.get('webhook', {}).get('enabled', False):
            logger.info('Enabling rpc.webhook ...')
            from freqtrade.rpc.webhook import Webhook
            self.registered_modules.append(Webhook(freqtrade))
Ejemplo n.º 6
0
    def __init__(self, freqtrade) -> None:
        """ Initializes all enabled rpc modules """
        self.registered_modules: List[RPC] = []

        # Enable telegram
        if freqtrade.config.get('telegram', {}).get('enabled', False):
            logger.info('Enabling rpc.telegram ...')
            from freqtrade.rpc.telegram import Telegram
            self.registered_modules.append(Telegram(freqtrade))

        # Enable Webhook
        if freqtrade.config.get('webhook', {}).get('enabled', False):
            logger.info('Enabling rpc.webhook ...')
            from freqtrade.rpc.webhook import Webhook
            self.registered_modules.append(Webhook(freqtrade))

        # Enable local rest api server for cmd line control
        if freqtrade.config.get('api_server', {}).get('enabled', False):
            logger.info('Enabling rpc.api_server')
            from freqtrade.rpc.api_server import ApiServer
            self.registered_modules.append(ApiServer(freqtrade))
def test__send_msg(default_conf, mocker, caplog):
    default_conf["webhook"] = get_webhook_dict()
    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    msg = {'value1': 'DEADBEEF', 'value2': 'ALIVEBEEF', 'value3': 'FREQTRADE'}
    post = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.post", post)
    webhook._send_msg(msg)

    assert post.call_count == 1
    assert post.call_args[1] == {'data': msg}
    assert post.call_args[0] == (default_conf['webhook']['url'], )

    post = MagicMock(side_effect=RequestException)
    mocker.patch("freqtrade.rpc.webhook.post", post)
    webhook._send_msg(msg)
    assert log_has('Could not call webhook url. Exception: ', caplog)
Ejemplo n.º 8
0
    def __init__(self, freqtrade) -> None:
        """ Initializes all enabled rpc modules """
        self.registered_modules: List[RPCHandler] = []
        self._rpc = RPC(freqtrade)
        config = freqtrade.config
        # Enable telegram
        if config.get('telegram', {}).get('enabled', False):
            logger.info('Enabling rpc.telegram ...')
            from freqtrade.rpc.telegram import Telegram
            self.registered_modules.append(Telegram(self._rpc, config))

        # Enable Webhook
        if config.get('webhook', {}).get('enabled', False):
            logger.info('Enabling rpc.webhook ...')
            from freqtrade.rpc.webhook import Webhook
            self.registered_modules.append(Webhook(self._rpc, config))

        # Enable local rest api server for cmd line control
        if config.get('api_server', {}).get('enabled', False):
            logger.info('Enabling rpc.api_server')
            from freqtrade.rpc.api_server import ApiServer
            apiserver = ApiServer(config)
            apiserver.add_rpc_handler(self._rpc)
            self.registered_modules.append(apiserver)
def test_send_msg(default_conf, mocker):
    default_conf["webhook"] = get_webhook_dict()
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    # Test buy
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.BUY_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookbuy"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookbuy"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookbuy"]["value3"].format(**msg))
    # Test buy cancel
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.BUY_CANCEL_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookbuycancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookbuycancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookbuycancel"]["value3"].format(**msg))
    # Test sell
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.SELL_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': SellType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhooksell"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhooksell"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhooksell"]["value3"].format(**msg))
    # Test sell cancel
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.SELL_CANCEL_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': SellType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhooksellcancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhooksellcancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhooksellcancel"]["value3"].format(**msg))
    for msgtype in [
            RPCMessageType.STATUS_NOTIFICATION,
            RPCMessageType.WARNING_NOTIFICATION,
            RPCMessageType.STARTUP_NOTIFICATION
    ]:
        # Test notification
        msg = {
            'type': msgtype,
            'status': 'Unfilled sell order for BTC cancelled due to timeout'
        }
        msg_mock = MagicMock()
        mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
        webhook.send_msg(msg)
        assert msg_mock.call_count == 1
        assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
                ["webhookstatus"]["value1"].format(**msg))
        assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
                ["webhookstatus"]["value2"].format(**msg))
        assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
                ["webhookstatus"]["value3"].format(**msg))
def test__init__(mocker, default_conf):
    default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    assert webhook._config == default_conf
Ejemplo n.º 11
0
def test_send_msg(default_conf, mocker):
    default_conf["webhook"] = get_webhook_dict()
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
    msg = {
        'type': RPCMessageType.BUY_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'market_url': "http://mockedurl/ETH_BTC",
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookbuy"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookbuy"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookbuy"]["value3"].format(**msg))
    # Test sell
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.SELL_NOTIFICATION,
        'exchange': 'Bittrex',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'market_url': "http://mockedurl/ETH_BTC",
        'limit': 0.005,
        'amount': 0.8,
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_percent': 0.20,
        'stake_currency': 'BTC',
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhooksell"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhooksell"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhooksell"]["value3"].format(**msg))

    # Test notification
    msg = {
        'type': RPCMessageType.STATUS_NOTIFICATION,
        'status': 'Unfilled sell order for BTC cancelled due to timeout'
    }
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook.send_msg(msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookstatus"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookstatus"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookstatus"]["value3"].format(**msg))
Ejemplo n.º 12
0
def test_send_msg_webhook(default_conf, mocker):
    default_conf["webhook"] = get_webhook_dict()
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)),
                      default_conf)
    # Test buy
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.ENTRY,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 1.0,
        'direction': 'Long',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentry"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentry"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentry"]["value3"].format(**msg))
    assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]
            ["webhookentry"]["value4"].format(**msg))
    assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]
            ["webhookentry"]["value5"].format(**msg))
    # Test short
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.ENTRY,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 2.0,
        'direction': 'Short',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentry"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentry"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentry"]["value3"].format(**msg))
    assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]
            ["webhookentry"]["value4"].format(**msg))
    assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]
            ["webhookentry"]["value5"].format(**msg))
    # Test buy cancel
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.ENTRY_CANCEL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 1.0,
        'direction': 'Long',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentrycancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentrycancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentrycancel"]["value3"].format(**msg))
    # Test short cancel
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.ENTRY_CANCEL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 2.0,
        'direction': 'Short',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentrycancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentrycancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentrycancel"]["value3"].format(**msg))
    assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]
            ["webhookentrycancel"]["value4"].format(**msg))
    assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]
            ["webhookentrycancel"]["value5"].format(**msg))
    # Test buy fill
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.ENTRY_FILL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 1.0,
        'direction': 'Long',
        'open_rate': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentryfill"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentryfill"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentryfill"]["value3"].format(**msg))
    assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]
            ["webhookentrycancel"]["value4"].format(**msg))
    assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]
            ["webhookentrycancel"]["value5"].format(**msg))
    # Test short fill
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.ENTRY_FILL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'leverage': 2.0,
        'direction': 'Short',
        'open_rate': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookentryfill"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookentryfill"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookentryfill"]["value3"].format(**msg))
    assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]
            ["webhookentrycancel"]["value4"].format(**msg))
    assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]
            ["webhookentrycancel"]["value5"].format(**msg))
    # Test sell
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.EXIT,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': ExitType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookexit"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookexit"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookexit"]["value3"].format(**msg))
    # Test sell cancel
    msg_mock.reset_mock()
    msg = {
        'type': RPCMessageType.EXIT_CANCEL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': ExitType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookexitcancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookexitcancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookexitcancel"]["value3"].format(**msg))
    # Test Sell fill
    msg_mock.reset_mock()
    msg = {
        'type': RPCMessageType.EXIT_FILL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'close_rate': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': ExitType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
            ["webhookexitfill"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
            ["webhookexitfill"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
            ["webhookexitfill"]["value3"].format(**msg))

    for msgtype in [
            RPCMessageType.STATUS, RPCMessageType.WARNING,
            RPCMessageType.STARTUP
    ]:
        # Test notification
        msg = {
            'type': msgtype,
            'status': 'Unfilled sell order for BTC cancelled due to timeout'
        }
        msg_mock = MagicMock()
        mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
        webhook.send_msg(msg)
        assert msg_mock.call_count == 1
        assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]
                ["webhookstatus"]["value1"].format(**msg))
        assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]
                ["webhookstatus"]["value2"].format(**msg))
        assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]
                ["webhookstatus"]["value3"].format(**msg))