mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 18:23:55 +00:00
Merge branch 'develop' into trailing_only_offset
This commit is contained in:
commit
f1f311e456
|
@ -23,10 +23,13 @@ install:
|
|||
- pip install -r requirements-dev.txt
|
||||
- pip install -e .
|
||||
jobs:
|
||||
|
||||
include:
|
||||
- stage: tests
|
||||
script:
|
||||
- pytest --cov=freqtrade --cov-config=.coveragerc freqtrade/tests/
|
||||
# Allow failure for coveralls
|
||||
- coveralls || true
|
||||
name: pytest
|
||||
- script:
|
||||
- cp config.json.example config.json
|
||||
|
@ -47,9 +50,6 @@ jobs:
|
|||
- build_helpers/publish_docker.sh
|
||||
name: "Build and test and push docker image"
|
||||
|
||||
after_success:
|
||||
- coveralls
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
secure: bKLXmOrx8e2aPZl7W8DA5BdPAXWGpI5UzST33oc1G/thegXcDVmHBTJrBs4sZak6bgAclQQrdZIsRd2eFYzHLalJEaw6pk7hoAw8SvLnZO0ZurWboz7qg2+aZZXfK4eKl/VUe4sM9M4e/qxjkK+yWG7Marg69c4v1ypF7ezUi1fPYILYw8u0paaiX0N5UX8XNlXy+PBlga2MxDjUY70MuajSZhPsY2pDUvYnMY1D/7XN3cFW0g+3O8zXjF0IF4q1Z/1ASQe+eYjKwPQacE+O8KDD+ZJYoTOFBAPllrtpO1jnOPFjNGf3JIbVMZw4bFjIL0mSQaiSUaUErbU3sFZ5Or79rF93XZ81V7uEZ55vD8KMfR2CB1cQJcZcj0v50BxLo0InkFqa0Y8Nra3sbpV4fV5Oe8pDmomPJrNFJnX6ULQhQ1gTCe0M5beKgVms5SITEpt4/Y0CmLUr6iHDT0CUiyMIRWAXdIgbGh1jfaWOMksybeRevlgDsIsNBjXmYI1Sw2ZZR2Eo2u4R6zyfyjOMLwYJ3vgq9IrACv2w5nmf0+oguMWHf6iWi2hiOqhlAN1W74+3HsYQcqnuM3LGOmuCnPprV1oGBqkPXjIFGpy21gNx4vHfO1noLUyJnMnlu2L7SSuN1CdLsnjJ1hVjpJjPfqB4nn8g12x87TqM1bOm+3Q=
|
||||
|
|
|
@ -39,6 +39,7 @@ Mandatory Parameters are marked as **Required**.
|
|||
| `order_types` | None | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-strategy).
|
||||
| `order_time_in_force` | None | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-strategy).
|
||||
| `exchange.name` | bittrex | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
|
||||
| `exchange.sandbox` | false | 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.
|
||||
| `exchange.key` | key | API key to use for the exchange. Only required when you are in production mode.
|
||||
| `exchange.secret` | secret | API secret to use for the exchange. Only required when you are in production mode.
|
||||
| `exchange.pair_whitelist` | [] | List of currency to use by the bot. Can be overrided with `--dynamic-whitelist` param.
|
||||
|
|
|
@ -36,7 +36,7 @@ Complementary Loss Rate (*L*) is defined as
|
|||
|
||||
or, which is the same, as
|
||||
|
||||
R = 1 – W
|
||||
L = 1 – W
|
||||
|
||||
### Risk Reward Ratio
|
||||
Risk Reward Ratio (*R*) is a formula used to measure the expected gains of a given investment against the risk of loss. It is basically what you potentially win divided by what you potentially lose:
|
||||
|
|
|
@ -44,6 +44,14 @@ CREATE TABLE trades (
|
|||
open_date DATETIME NOT NULL,
|
||||
close_date DATETIME,
|
||||
open_order_id VARCHAR,
|
||||
stop_loss FLOAT,
|
||||
initial_stop_loss FLOAT,
|
||||
stoploss_order_id VARCHAR,
|
||||
stoploss_last_update DATETIME,
|
||||
max_rate FLOAT,
|
||||
sell_reason VARCHAR,
|
||||
strategy VARCHAR,
|
||||
ticker_interval INTEGER,
|
||||
PRIMARY KEY (id),
|
||||
CHECK (is_open IN (0, 1))
|
||||
);
|
||||
|
@ -55,38 +63,45 @@ CREATE TABLE trades (
|
|||
SELECT * FROM trades;
|
||||
```
|
||||
|
||||
## Fix trade still open after a /forcesell
|
||||
## Fix trade still open after a manual sell on the exchange
|
||||
|
||||
!!! Warning:
|
||||
Manually selling on the exchange should not be done by default, since the bot does not detect this and will try to sell anyway.
|
||||
/foresell <tradeid> should accomplish the same thing.
|
||||
|
||||
!!! Note:
|
||||
This should not be necessary after /forcesell, as forcesell orders are closed automatically by the bot on the next iteration.
|
||||
|
||||
```sql
|
||||
UPDATE trades
|
||||
SET is_open=0, close_date=<close_date>, close_rate=<close_rate>, close_profit=close_rate/open_rate-1
|
||||
SET is_open=0, close_date=<close_date>, close_rate=<close_rate>, close_profit=close_rate/open_rate-1, sell_reason=<sell_reason>
|
||||
WHERE id=<trade_ID_to_update>;
|
||||
```
|
||||
|
||||
**Example:**
|
||||
##### Example
|
||||
|
||||
```sql
|
||||
UPDATE trades
|
||||
SET is_open=0, close_date='2017-12-20 03:08:45.103418', close_rate=0.19638016, close_profit=0.0496
|
||||
SET is_open=0, close_date='2017-12-20 03:08:45.103418', close_rate=0.19638016, close_profit=0.0496, sell_reason='force_sell'
|
||||
WHERE id=31;
|
||||
```
|
||||
|
||||
## Insert manually a new trade
|
||||
|
||||
```sql
|
||||
INSERT
|
||||
INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
|
||||
VALUES ('BITTREX', 'BTC_<COIN>', 1, 0.0025, 0.0025, <open_rate>, <stake_amount>, <amount>, '<datetime>')
|
||||
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
|
||||
VALUES ('bittrex', 'ETH/BTC', 1, 0.0025, 0.0025, <open_rate>, <stake_amount>, <amount>, '<datetime>')
|
||||
```
|
||||
|
||||
**Example:**
|
||||
##### Example:
|
||||
|
||||
```sql
|
||||
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date) VALUES ('BITTREX', 'BTC_ETC', 1, 0.0025, 0.0025, 0.00258580, 0.002, 0.7715262081, '2017-11-28 12:44:24.000000')
|
||||
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
|
||||
VALUES ('bittrex', 'ETH/BTC', 1, 0.0025, 0.0025, 0.00258580, 0.002, 0.7715262081, '2017-11-28 12:44:24.000000')
|
||||
```
|
||||
|
||||
## Fix wrong fees in the table
|
||||
If your DB was created before
|
||||
[PR#200](https://github.com/freqtrade/freqtrade/pull/200) was merged
|
||||
(before 12/23/17).
|
||||
If your DB was created before [PR#200](https://github.com/freqtrade/freqtrade/pull/200) was merged (before 12/23/17).
|
||||
|
||||
```sql
|
||||
UPDATE trades SET fee=0.0025 WHERE fee=0.005;
|
||||
|
|
|
@ -298,7 +298,7 @@ class Exchange(object):
|
|||
'amount': amount,
|
||||
"cost": amount * rate,
|
||||
'type': ordertype,
|
||||
'side': 'buy',
|
||||
'side': side,
|
||||
'remaining': amount,
|
||||
'datetime': arrow.utcnow().isoformat(),
|
||||
'status': "open",
|
||||
|
@ -352,7 +352,7 @@ class Exchange(object):
|
|||
return dry_order
|
||||
|
||||
params = self._params.copy()
|
||||
if time_in_force != 'gtc':
|
||||
if time_in_force != 'gtc' and ordertype != 'market':
|
||||
params.update({'timeInForce': time_in_force})
|
||||
|
||||
return self.create_order(pair, ordertype, 'buy', amount, rate, params)
|
||||
|
@ -365,7 +365,7 @@ class Exchange(object):
|
|||
return dry_order
|
||||
|
||||
params = self._params.copy()
|
||||
if time_in_force != 'gtc':
|
||||
if time_in_force != 'gtc' and ordertype != 'market':
|
||||
params.update({'timeInForce': time_in_force})
|
||||
|
||||
return self.create_order(pair, ordertype, 'sell', amount, rate, params)
|
||||
|
|
|
@ -61,6 +61,8 @@ class RPCManager(object):
|
|||
stake_currency = config['stake_currency']
|
||||
stake_amount = config['stake_amount']
|
||||
minimal_roi = config['minimal_roi']
|
||||
stoploss = config['stoploss']
|
||||
trailing_stop = config['trailing_stop']
|
||||
ticker_interval = config['ticker_interval']
|
||||
exchange_name = config['exchange']['name']
|
||||
strategy_name = config.get('strategy', '')
|
||||
|
@ -69,6 +71,7 @@ class RPCManager(object):
|
|||
'status': f'*Exchange:* `{exchange_name}`\n'
|
||||
f'*Stake per trade:* `{stake_amount} {stake_currency}`\n'
|
||||
f'*Minimum ROI:* `{minimal_roi}`\n'
|
||||
f'*{"Trailing " if trailing_stop else ""}Stoploss:* `{stoploss}`\n'
|
||||
f'*Ticker Interval:* `{ticker_interval}`\n'
|
||||
f'*Strategy:* `{strategy_name}`'
|
||||
})
|
||||
|
|
|
@ -4,7 +4,7 @@ import copy
|
|||
import logging
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from unittest.mock import Mock, MagicMock, PropertyMock
|
||||
from unittest.mock import MagicMock, Mock, PropertyMock
|
||||
|
||||
import arrow
|
||||
import ccxt
|
||||
|
@ -12,11 +12,10 @@ import pytest
|
|||
from pandas import DataFrame
|
||||
|
||||
from freqtrade import DependencyException, OperationalException, TemporaryError
|
||||
from freqtrade.exchange import Exchange, Kraken, Binance
|
||||
from freqtrade.exchange import Binance, Exchange, Kraken
|
||||
from freqtrade.exchange.exchange import API_RETRY_COUNT
|
||||
from freqtrade.tests.conftest import get_patched_exchange, log_has, log_has_re
|
||||
from freqtrade.resolvers.exchange_resolver import ExchangeResolver
|
||||
|
||||
from freqtrade.tests.conftest import get_patched_exchange, log_has, log_has_re
|
||||
|
||||
# Make sure to always keep one exchange here which is NOT subclassed!!
|
||||
EXCHANGES = ['bittrex', 'binance', 'kraken', ]
|
||||
|
@ -470,6 +469,9 @@ def test_dry_run_order(default_conf, mocker, side, exchange_name):
|
|||
pair='ETH/BTC', ordertype='limit', side=side, amount=1, rate=200)
|
||||
assert 'id' in order
|
||||
assert f'dry_run_{side}_' in order["id"]
|
||||
assert order["side"] == side
|
||||
assert order["type"] == "limit"
|
||||
assert order["pair"] == "ETH/BTC"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side", [
|
||||
|
@ -588,11 +590,10 @@ def test_buy_prod(default_conf, mocker, exchange_name):
|
|||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
|
||||
def test_buy_considers_time_in_force(default_conf, mocker):
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_buy_considers_time_in_force(default_conf, mocker, exchange_name):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'market'
|
||||
time_in_force = 'ioc'
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
|
@ -602,7 +603,27 @@ def test_buy_considers_time_in_force(default_conf, mocker):
|
|||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
|
||||
|
||||
order_type = 'limit'
|
||||
time_in_force = 'ioc'
|
||||
|
||||
order = exchange.buy(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'buy'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] == 200
|
||||
assert "timeInForce" in api_mock.create_order.call_args[0][5]
|
||||
assert api_mock.create_order.call_args[0][5]["timeInForce"] == time_in_force
|
||||
|
||||
order_type = 'market'
|
||||
time_in_force = 'ioc'
|
||||
|
||||
order = exchange.buy(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
@ -615,68 +636,8 @@ def test_buy_considers_time_in_force(default_conf, mocker):
|
|||
assert api_mock.create_order.call_args[0][2] == 'buy'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] is None
|
||||
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc'}
|
||||
|
||||
|
||||
def test_buy_kraken_trading_agreement(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'market'
|
||||
time_in_force = 'ioc'
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.buy(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'buy'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] is None
|
||||
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc',
|
||||
'trading_agreement': 'agree'}
|
||||
|
||||
|
||||
def test_sell_kraken_trading_agreement(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'market'
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'sell'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] is None
|
||||
assert api_mock.create_order.call_args[0][5] == {'trading_agreement': 'agree'}
|
||||
# Market orders should not send timeInForce!!
|
||||
assert "timeInForce" not in api_mock.create_order.call_args[0][5]
|
||||
|
||||
|
||||
def test_sell_dry_run(default_conf, mocker):
|
||||
|
@ -747,6 +708,55 @@ def test_sell_prod(default_conf, mocker, exchange_name):
|
|||
exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_sell_considers_time_in_force(default_conf, mocker, exchange_name):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6))
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
|
||||
|
||||
order_type = 'limit'
|
||||
time_in_force = 'ioc'
|
||||
|
||||
order = exchange.sell(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'sell'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] == 200
|
||||
assert "timeInForce" in api_mock.create_order.call_args[0][5]
|
||||
assert api_mock.create_order.call_args[0][5]["timeInForce"] == time_in_force
|
||||
|
||||
order_type = 'market'
|
||||
time_in_force = 'ioc'
|
||||
order = exchange.sell(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'sell'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] is None
|
||||
# Market orders should not send timeInForce!!
|
||||
assert "timeInForce" not in api_mock.create_order.call_args[0][5]
|
||||
|
||||
|
||||
def test_get_balance_dry_run(default_conf, mocker):
|
||||
default_conf['dry_run'] = True
|
||||
|
||||
|
|
67
freqtrade/tests/exchange/test_kraken.py
Normal file
67
freqtrade/tests/exchange/test_kraken.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
# pragma pylint: disable=missing-docstring, C0103, bad-continuation, global-statement
|
||||
# pragma pylint: disable=protected-access
|
||||
from random import randint
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from freqtrade.tests.conftest import get_patched_exchange
|
||||
|
||||
|
||||
def test_buy_kraken_trading_agreement(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'limit'
|
||||
time_in_force = 'ioc'
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.buy(pair='ETH/BTC', ordertype=order_type,
|
||||
amount=1, rate=200, time_in_force=time_in_force)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'buy'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] == 200
|
||||
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc',
|
||||
'trading_agreement': 'agree'}
|
||||
|
||||
|
||||
def test_sell_kraken_trading_agreement(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'market'
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||
assert api_mock.create_order.call_args[0][1] == order_type
|
||||
assert api_mock.create_order.call_args[0][2] == 'sell'
|
||||
assert api_mock.create_order.call_args[0][3] == 1
|
||||
assert api_mock.create_order.call_args[0][4] is None
|
||||
assert api_mock.create_order.call_args[0][5] == {'trading_agreement': 'agree'}
|
|
@ -1,5 +1,5 @@
|
|||
# Include all requirements to run the bot.
|
||||
-r requirements.txt
|
||||
|
||||
plotly==3.6.1
|
||||
plotly==3.7.0
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
ccxt==1.18.345
|
||||
SQLAlchemy==1.3.0
|
||||
ccxt==1.18.357
|
||||
SQLAlchemy==1.3.1
|
||||
python-telegram-bot==11.1.0
|
||||
arrow==0.13.1
|
||||
cachetools==3.1.0
|
||||
|
|
Loading…
Reference in New Issue
Block a user