diff --git a/config_examples/config_full.example.json b/config_examples/config_full.example.json index 42c05eaf5..4681ec7df 100644 --- a/config_examples/config_full.example.json +++ b/config_examples/config_full.example.json @@ -89,7 +89,6 @@ ], "exchange": { "name": "binance", - "sandbox": false, "key": "your_exchange_key", "secret": "your_exchange_secret", "password": "", diff --git a/docs/configuration.md b/docs/configuration.md index e05d1b450..6c0795c67 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -188,7 +188,6 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position).
[Strategy Override](#parameters-in-the-strategy).
*Defaults to `-1`.*
**Datatype:** Positive Integer or -1 | | **Exchange** | `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
**Datatype:** String -| `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
**Datatype:** Boolean | `exchange.key` | API key to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String | `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String | `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String diff --git a/docs/sandbox-testing.md b/docs/sandbox-testing.md deleted file mode 100644 index 2c0f306cf..000000000 --- a/docs/sandbox-testing.md +++ /dev/null @@ -1,121 +0,0 @@ -# Sandbox API testing - -Some exchanges provide sandboxes or testbeds for risk-free testing, while running the bot against a real exchange. -With some configuration, freqtrade (in combination with ccxt) provides access to these. - -This document is an overview to configure Freqtrade to be used with sandboxes. -This can be useful to developers and trader alike. - -!!! Warning - Sandboxes usually have very low volume, and either a very wide spread, or no orders available at all. - Therefore, sandboxes will usually not do a good job of showing you how a strategy would work in real trading. - -## Exchanges known to have a sandbox / testnet - -* [binance](https://testnet.binance.vision/) -* [coinbasepro](https://public.sandbox.pro.coinbase.com) -* [gemini](https://exchange.sandbox.gemini.com/) -* [huobipro](https://www.testnet.huobi.pro/) -* [kucoin](https://sandbox.kucoin.com/) -* [phemex](https://testnet.phemex.com/) - -!!! Note - We did not test correct functioning of all of the above testnets. Please report your experiences with each sandbox. - ---- - -## Configure a Sandbox account - -When testing your API connectivity, make sure to use the appropriate sandbox / testnet URL. - -In general, you should follow these steps to enable an exchange's sandbox: - -* Figure out if an exchange has a sandbox (most likely by using google or the exchange's support documents) -* Create a sandbox account (often the sandbox-account requires separate registration) -* [Add some test assets to account](#add-test-funds) -* Create API keys - -### Add test funds - -Usually, sandbox exchanges allow depositing funds directly via web-interface. -You should make sure to have a realistic amount of funds available to your test-account, so results are representable of your real account funds. - -!!! Warning - Test exchanges will **NEVER** require your real credit card or banking details! - -## Configure freqtrade to use a exchange's sandbox - -### Sandbox URLs - -Freqtrade makes use of CCXT which in turn provides a list of URLs to Freqtrade. -These include `['test']` and `['api']`. - -* `[Test]` if available will point to an Exchanges sandbox. -* `[Api]` normally used, and resolves to live API target on the exchange. - -To make use of sandbox / test add "sandbox": true, to your config.json - -```json - "exchange": { - "name": "coinbasepro", - "sandbox": true, - "key": "5wowfxemogxeowo;heiohgmd", - "secret": "/ZMH1P62rCVmwefewrgcewX8nh4gob+lywxfwfxwwfxwfNsH1ySgvWCUR/w==", - "password": "1bkjfkhfhfu6sr", - "outdated_offset": 5 - "pair_whitelist": [ - "BTC/USD" - ] - }, - "datadir": "user_data/data/coinbasepro_sandbox" -``` - -Also the following information: - -* api-key (created for the sandbox webpage) -* api-secret (noted earlier) -* password (the passphrase - noted earlier) - -!!! Tip "Different data directory" - We also recommend to set `datadir` to something identifying downloaded data as sandbox data, to avoid having sandbox data mixed with data from the real exchange. - This can be done by adding the `"datadir"` key to the configuration. - Now, whenever you use this configuration, your data directory will be set to this directory. - ---- - -## You should now be ready to test your sandbox - -Ensure Freqtrade logs show the sandbox URL, and trades made are shown in sandbox. Also make sure to select a pair which shows at least some decent value (which very often is BTC/). - -## Common problems with sandbox exchanges - -Sandbox exchange instances often have very low volume, which can cause some problems which usually are not seen on a real exchange instance. - -### Old Candles problem - -Since Sandboxes often have low volume, candles can be quite old and show no volume. -To disable the error "Outdated history for pair ...", best increase the parameter `"outdated_offset"` to a number that seems realistic for the sandbox you're using. - -### Unfilled orders - -Sandboxes often have very low volumes - which means that many trades can go unfilled, or can go unfilled for a very long time. - -To mitigate this, you can try to match the first order on the opposite orderbook side using the following configuration: - -``` jsonc - "order_types": { - "entry": "limit", - "exit": "limit" - // ... - }, - "entry_pricing": { - "price_side": "other", - // ... - }, - "exit_pricing":{ - "price_side": "other", - // ... - }, - ``` - - The configuration is similar to the suggested configuration for market orders - however by using limit-orders you can avoid moving the price too much, and you can set the worst price you might get. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 4b3cff7a1..fedd34726 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -461,7 +461,6 @@ CONF_SCHEMA = { 'type': 'object', 'properties': { 'name': {'type': 'string'}, - 'sandbox': {'type': 'boolean', 'default': False}, 'key': {'type': 'string', 'default': ''}, 'secret': {'type': 'string', 'default': ''}, 'password': {'type': 'string', 'default': ''}, diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 5f2530431..afbcff3b6 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -263,8 +263,6 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(f"Initialization of ccxt failed. Reason: {e}") from e - self.set_sandbox(api, exchange_config, name) - return api @property @@ -465,16 +463,6 @@ class Exchange: return amount_to_contract_precision(amount, self.get_precision_amount(pair), self.precisionMode, contract_size) - def set_sandbox(self, api: ccxt.Exchange, exchange_config: dict, name: str) -> None: - if exchange_config.get('sandbox'): - if api.urls.get('test'): - api.urls['api'] = api.urls['test'] - logger.info("Enabled Sandbox API on %s", name) - else: - logger.warning( - f"No Sandbox URL in CCXT for {name}, exiting. Please check your config.json") - raise OperationalException(f'Exchange {name} does not provide a sandbox api') - def _load_async_markets(self, reload: bool = False) -> None: try: if self._api_async: diff --git a/mkdocs.yml b/mkdocs.yml index 815a10419..bb5ae0010 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,7 +47,6 @@ nav: - Advanced Hyperopt: advanced-hyperopt.md - Producer/Consumer mode: producer-consumer.md - Edge Positioning: edge.md - - Sandbox Testing: sandbox-testing.md - FAQ: faq.md - SQL Cheat-sheet: sql_cheatsheet.md - Strategy migration: strategy_migration.md diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index a8c765553..85d30a9cd 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -556,41 +556,6 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: assert result == 4000 -def test_set_sandbox(default_conf, mocker): - """ - Test working scenario - """ - api_mock = MagicMock() - api_mock.load_markets = MagicMock(return_value={ - 'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': '' - }) - url_mock = PropertyMock(return_value={'test': "api-public.sandbox.gdax.com", - 'api': 'https://api.gdax.com'}) - type(api_mock).urls = url_mock - exchange = get_patched_exchange(mocker, default_conf, api_mock) - liveurl = exchange._api.urls['api'] - default_conf['exchange']['sandbox'] = True - exchange.set_sandbox(exchange._api, default_conf['exchange'], 'Logname') - assert exchange._api.urls['api'] != liveurl - - -def test_set_sandbox_exception(default_conf, mocker): - """ - Test Fail scenario - """ - api_mock = MagicMock() - api_mock.load_markets = MagicMock(return_value={ - 'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': '' - }) - url_mock = PropertyMock(return_value={'api': 'https://api.gdax.com'}) - type(api_mock).urls = url_mock - - with pytest.raises(OperationalException, match=r'does not provide a sandbox api'): - exchange = get_patched_exchange(mocker, default_conf, api_mock) - default_conf['exchange']['sandbox'] = True - exchange.set_sandbox(exchange._api, default_conf['exchange'], 'Logname') - - def test__load_async_markets(default_conf, mocker, caplog): mocker.patch(f'{EXMS}._init_ccxt') mocker.patch(f'{EXMS}.validate_pairs') diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 7808fb5c8..3f2fb0669 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1038,8 +1038,7 @@ def test_load_config_stoploss_exchange_limit_ratio(all_conf) -> None: validate_config_schema(all_conf) -@pytest.mark.parametrize("keys", [("exchange", "sandbox", False), - ("exchange", "key", ""), +@pytest.mark.parametrize("keys", [("exchange", "key", ""), ("exchange", "secret", ""), ("exchange", "password", ""), ])