Merge branch 'develop' into ta_on_candle
This commit is contained in:
@@ -102,7 +102,18 @@ def default_conf():
|
||||
"sell": 30
|
||||
},
|
||||
"bid_strategy": {
|
||||
"ask_last_balance": 0.0
|
||||
"ask_last_balance": 0.0,
|
||||
"use_order_book": False,
|
||||
"order_book_top": 1,
|
||||
"check_depth_of_market": {
|
||||
"enabled": False,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"ask_strategy": {
|
||||
"use_order_book": False,
|
||||
"order_book_min": 1,
|
||||
"order_book_max": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "bittrex",
|
||||
@@ -403,6 +414,39 @@ def limit_sell_order():
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order_book_l2():
|
||||
return MagicMock(return_value={
|
||||
'bids': [
|
||||
[0.043936, 10.442],
|
||||
[0.043935, 31.865],
|
||||
[0.043933, 11.212],
|
||||
[0.043928, 0.088],
|
||||
[0.043925, 10.0],
|
||||
[0.043921, 10.0],
|
||||
[0.04392, 37.64],
|
||||
[0.043899, 0.066],
|
||||
[0.043885, 0.676],
|
||||
[0.04387, 22.758]
|
||||
],
|
||||
'asks': [
|
||||
[0.043949, 0.346],
|
||||
[0.04395, 0.608],
|
||||
[0.043951, 3.948],
|
||||
[0.043954, 0.288],
|
||||
[0.043958, 9.277],
|
||||
[0.043995, 1.566],
|
||||
[0.044, 0.588],
|
||||
[0.044002, 0.992],
|
||||
[0.044003, 0.095],
|
||||
[0.04402, 37.64]
|
||||
],
|
||||
'timestamp': None,
|
||||
'datetime': None,
|
||||
'nonce': 288004540
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ticker_history():
|
||||
return [
|
||||
|
@@ -515,6 +515,35 @@ def test_get_ticker(default_conf, mocker):
|
||||
exchange.get_ticker(pair='ETH/BTC', refresh=True)
|
||||
|
||||
|
||||
def test_get_order_book(default_conf, mocker, order_book_l2):
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
api_mock = MagicMock()
|
||||
|
||||
api_mock.fetch_l2_order_book = order_book_l2
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
order_book = exchange.get_order_book(pair='ETH/BTC', limit=10)
|
||||
assert 'bids' in order_book
|
||||
assert 'asks' in order_book
|
||||
assert len(order_book['bids']) == 10
|
||||
assert len(order_book['asks']) == 10
|
||||
|
||||
|
||||
def test_get_order_book_exception(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
with pytest.raises(OperationalException):
|
||||
api_mock.fetch_l2_order_book = MagicMock(side_effect=ccxt.NotSupported)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange.get_order_book(pair='ETH/BTC', limit=50)
|
||||
with pytest.raises(TemporaryError):
|
||||
api_mock.fetch_l2_order_book = MagicMock(side_effect=ccxt.NetworkError)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange.get_order_book(pair='ETH/BTC', limit=50)
|
||||
with pytest.raises(OperationalException):
|
||||
api_mock.fetch_l2_order_book = MagicMock(side_effect=ccxt.BaseError)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange.get_order_book(pair='ETH/BTC', limit=50)
|
||||
|
||||
|
||||
def make_fetch_ohlcv_mock(data):
|
||||
def fetch_ohlcv_mock(pair, timeframe, since):
|
||||
if since:
|
||||
@@ -823,15 +852,3 @@ def test_get_fee(default_conf, mocker):
|
||||
|
||||
ccxt_exceptionhandlers(mocker, default_conf, api_mock,
|
||||
'get_fee', 'calculate_fee')
|
||||
|
||||
|
||||
def test_get_amount_lots(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
api_mock.amount_to_lots = MagicMock(return_value=1.0)
|
||||
api_mock.markets = None
|
||||
marketmock = MagicMock()
|
||||
api_mock.load_markets = marketmock
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
|
||||
assert exchange.get_amount_lots('LTC/BTC', 1.54) == 1
|
||||
assert marketmock.call_count == 1
|
||||
|
@@ -6,6 +6,7 @@ from unittest.mock import MagicMock, ANY
|
||||
|
||||
import pytest
|
||||
|
||||
from freqtrade import TemporaryError
|
||||
from freqtrade.fiat_convert import CryptoToFiatConverter
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
from freqtrade.persistence import Trade
|
||||
@@ -285,11 +286,12 @@ def test_rpc_balance_handle(default_conf, mocker):
|
||||
'used': 2.0,
|
||||
},
|
||||
'ETH': {
|
||||
'free': 0.0,
|
||||
'total': 0.0,
|
||||
'used': 0.0,
|
||||
'free': 1.0,
|
||||
'total': 5.0,
|
||||
'used': 4.0,
|
||||
}
|
||||
}
|
||||
# ETH will be skipped due to mocked Error below
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.fiat_convert.Market',
|
||||
@@ -301,7 +303,8 @@ def test_rpc_balance_handle(default_conf, mocker):
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_balances=MagicMock(return_value=mock_balance)
|
||||
get_balances=MagicMock(return_value=mock_balance),
|
||||
get_ticker=MagicMock(side_effect=TemporaryError('Could not load ticker due to xxx'))
|
||||
)
|
||||
|
||||
freqtradebot = FreqtradeBot(default_conf)
|
||||
@@ -320,6 +323,7 @@ def test_rpc_balance_handle(default_conf, mocker):
|
||||
'pending': 2.0,
|
||||
'est_btc': 12.0,
|
||||
}]
|
||||
assert result['total'] == 12.0
|
||||
|
||||
|
||||
def test_rpc_start(mocker, default_conf) -> None:
|
||||
|
@@ -1095,6 +1095,38 @@ def test_send_msg_status_notification(default_conf, mocker) -> None:
|
||||
assert msg_mock.call_args[0][0] == '*Status:* `running`'
|
||||
|
||||
|
||||
def test_warning_notification(default_conf, mocker) -> None:
|
||||
msg_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.rpc.telegram.Telegram',
|
||||
_init=MagicMock(),
|
||||
_send_msg=msg_mock
|
||||
)
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
telegram = Telegram(freqtradebot)
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.WARNING_NOTIFICATION,
|
||||
'status': 'message'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] == '*Warning:* `message`'
|
||||
|
||||
|
||||
def test_custom_notification(default_conf, mocker) -> None:
|
||||
msg_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.rpc.telegram.Telegram',
|
||||
_init=MagicMock(),
|
||||
_send_msg=msg_mock
|
||||
)
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
telegram = Telegram(freqtradebot)
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.CUSTOM_NOTIFICATION,
|
||||
'status': '*Custom:* `Hello World`'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] == '*Custom:* `Hello World`'
|
||||
|
||||
|
||||
def test_send_msg_unknown_type(default_conf, mocker) -> None:
|
||||
msg_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
|
@@ -8,6 +8,7 @@ from pandas import DataFrame
|
||||
|
||||
from freqtrade.arguments import TimeRange
|
||||
from freqtrade.optimize.__init__ import load_tickerdata_file
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.tests.conftest import get_patched_exchange, log_has
|
||||
from freqtrade.strategy.default_strategy import DefaultStrategy
|
||||
|
||||
@@ -107,6 +108,29 @@ def test_tickerdata_to_dataframe(default_conf) -> None:
|
||||
assert len(data['UNITTEST/BTC']) == 99 # partial candle was removed
|
||||
|
||||
|
||||
def test_min_roi_reached(default_conf, fee) -> None:
|
||||
strategy = DefaultStrategy(default_conf)
|
||||
strategy.minimal_roi = {0: 0.1, 20: 0.05, 55: 0.01}
|
||||
trade = Trade(
|
||||
pair='ETH/BTC',
|
||||
stake_amount=0.001,
|
||||
open_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||
fee_open=fee.return_value,
|
||||
fee_close=fee.return_value,
|
||||
exchange='bittrex',
|
||||
open_rate=1,
|
||||
)
|
||||
|
||||
assert not strategy.min_roi_reached(trade, 0.01, arrow.utcnow().shift(minutes=-55).datetime)
|
||||
assert strategy.min_roi_reached(trade, 0.12, arrow.utcnow().shift(minutes=-55).datetime)
|
||||
|
||||
assert not strategy.min_roi_reached(trade, 0.04, arrow.utcnow().shift(minutes=-39).datetime)
|
||||
assert strategy.min_roi_reached(trade, 0.06, arrow.utcnow().shift(minutes=-39).datetime)
|
||||
|
||||
assert not strategy.min_roi_reached(trade, -0.01, arrow.utcnow().shift(minutes=-1).datetime)
|
||||
assert strategy.min_roi_reached(trade, 0.02, arrow.utcnow().shift(minutes=-1).datetime)
|
||||
|
||||
|
||||
def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||
caplog.set_level(logging.DEBUG)
|
||||
ind_mock = MagicMock(side_effect=lambda x, meta: x)
|
||||
|
@@ -130,7 +130,7 @@ def test_strategy_override_minimal_roi(caplog):
|
||||
assert resolver.strategy.minimal_roi[0] == 0.5
|
||||
assert ('freqtrade.strategy.resolver',
|
||||
logging.INFO,
|
||||
"Override strategy 'minimal_roi' with value in config file."
|
||||
"Override strategy 'minimal_roi' with value in config file: {'0': 0.5}."
|
||||
) in caplog.record_tuples
|
||||
|
||||
|
||||
|
@@ -159,6 +159,15 @@ def test_gen_pair_whitelist(mocker, default_conf, tickers) -> None:
|
||||
assert whitelist == []
|
||||
|
||||
|
||||
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=False))
|
||||
|
||||
with pytest.raises(OperationalException):
|
||||
freqtrade._gen_pair_whitelist(base_currency='BTC')
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Test not implemented")
|
||||
def test_refresh_whitelist() -> None:
|
||||
pass
|
||||
@@ -664,21 +673,21 @@ def test_balance_fully_ask_side(mocker, default_conf) -> None:
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 0.0
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
|
||||
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 20
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 20, 'last': 10}) == 20
|
||||
|
||||
|
||||
def test_balance_fully_last_side(mocker, default_conf) -> None:
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 1.0
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
|
||||
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 10
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 20, 'last': 10}) == 10
|
||||
|
||||
|
||||
def test_balance_bigger_last_ask(mocker, default_conf) -> None:
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 1.0
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
|
||||
assert freqtrade.get_target_bid({'ask': 5, 'last': 10}) == 5
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 5, 'last': 10}) == 5
|
||||
|
||||
|
||||
def test_process_maybe_execute_buy(mocker, default_conf) -> None:
|
||||
@@ -1876,3 +1885,194 @@ def test_get_real_amount_open_trade(default_conf, mocker):
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
patch_get_signal(freqtrade)
|
||||
assert freqtrade.get_real_amount(trade, order) == amount
|
||||
|
||||
|
||||
def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee, markets, mocker,
|
||||
order_book_l2):
|
||||
default_conf['bid_strategy']['check_depth_of_market']['enabled'] = True
|
||||
default_conf['bid_strategy']['check_depth_of_market']['bids_to_ask_delta'] = 0.1
|
||||
patch_RPCManager(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker,
|
||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||
get_fee=fee,
|
||||
get_markets=markets
|
||||
)
|
||||
|
||||
# Save state of current whitelist
|
||||
whitelist = deepcopy(default_conf['exchange']['pair_whitelist'])
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
patch_get_signal(freqtrade)
|
||||
freqtrade.create_trade()
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade is not None
|
||||
assert trade.stake_amount == 0.001
|
||||
assert trade.is_open
|
||||
assert trade.open_date is not None
|
||||
assert trade.exchange == 'bittrex'
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
trade.update(limit_buy_order)
|
||||
|
||||
assert trade.open_rate == 0.00001099
|
||||
assert whitelist == default_conf['exchange']['pair_whitelist']
|
||||
|
||||
|
||||
def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_order,
|
||||
fee, markets, mocker, order_book_l2):
|
||||
default_conf['bid_strategy']['check_depth_of_market']['enabled'] = True
|
||||
# delta is 100 which is impossible to reach. hence check_depth_of_market will return false
|
||||
default_conf['bid_strategy']['check_depth_of_market']['bids_to_ask_delta'] = 100
|
||||
patch_RPCManager(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker,
|
||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||
get_fee=fee,
|
||||
get_markets=markets
|
||||
)
|
||||
# Save state of current whitelist
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
patch_get_signal(freqtrade)
|
||||
freqtrade.create_trade()
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade is None
|
||||
|
||||
|
||||
def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2, markets) -> None:
|
||||
"""
|
||||
test if function get_target_bid will return the order book price
|
||||
instead of the ask rate
|
||||
"""
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_markets=markets,
|
||||
get_order_book=order_book_l2
|
||||
)
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
default_conf['bid_strategy']['use_order_book'] = True
|
||||
default_conf['bid_strategy']['order_book_top'] = 2
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 0
|
||||
default_conf['telegram']['enabled'] = False
|
||||
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.045, 'last': 0.046}) == 0.043935
|
||||
|
||||
|
||||
def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2, markets) -> None:
|
||||
"""
|
||||
test if function get_target_bid will return the ask rate (since its value is lower)
|
||||
instead of the order book rate (even if enabled)
|
||||
"""
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_markets=markets,
|
||||
get_order_book=order_book_l2
|
||||
)
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
default_conf['bid_strategy']['use_order_book'] = True
|
||||
default_conf['bid_strategy']['order_book_top'] = 2
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 0
|
||||
default_conf['telegram']['enabled'] = False
|
||||
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.042, 'last': 0.046}) == 0.042
|
||||
|
||||
|
||||
def test_order_book_bid_strategy3(default_conf, mocker, order_book_l2, markets) -> None:
|
||||
"""
|
||||
test if function get_target_bid will return ask rate instead
|
||||
of the order book rate
|
||||
"""
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_markets=markets,
|
||||
get_order_book=order_book_l2
|
||||
)
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
default_conf['bid_strategy']['use_order_book'] = True
|
||||
default_conf['bid_strategy']['order_book_top'] = 1
|
||||
default_conf['bid_strategy']['ask_last_balance'] = 0
|
||||
default_conf['telegram']['enabled'] = False
|
||||
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
|
||||
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.03, 'last': 0.029}) == 0.03
|
||||
|
||||
|
||||
def test_check_depth_of_market_buy(default_conf, mocker, order_book_l2, markets) -> None:
|
||||
"""
|
||||
test check depth of market
|
||||
"""
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_markets=markets,
|
||||
get_order_book=order_book_l2
|
||||
)
|
||||
default_conf['telegram']['enabled'] = False
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
default_conf['bid_strategy']['check_depth_of_market']['enabled'] = True
|
||||
# delta is 100 which is impossible to reach. hence function will return false
|
||||
default_conf['bid_strategy']['check_depth_of_market']['bids_to_ask_delta'] = 100
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
|
||||
conf = default_conf['bid_strategy']['check_depth_of_market']
|
||||
assert freqtrade._check_depth_of_market_buy('ETH/BTC', conf) is False
|
||||
|
||||
|
||||
def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order,
|
||||
fee, markets, mocker, order_book_l2) -> None:
|
||||
"""
|
||||
test order book ask strategy
|
||||
"""
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2)
|
||||
default_conf['exchange']['name'] = 'binance'
|
||||
default_conf['ask_strategy']['use_order_book'] = True
|
||||
default_conf['ask_strategy']['order_book_min'] = 1
|
||||
default_conf['ask_strategy']['order_book_max'] = 2
|
||||
default_conf['telegram']['enabled'] = False
|
||||
patch_RPCManager(mocker)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=MagicMock(return_value={
|
||||
'bid': 0.00001172,
|
||||
'ask': 0.00001173,
|
||||
'last': 0.00001172
|
||||
}),
|
||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
|
||||
get_fee=fee,
|
||||
get_markets=markets
|
||||
)
|
||||
freqtrade = FreqtradeBot(default_conf)
|
||||
patch_get_signal(freqtrade)
|
||||
|
||||
freqtrade.create_trade()
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
|
||||
time.sleep(0.01) # Race condition fix
|
||||
trade.update(limit_buy_order)
|
||||
assert trade.is_open is True
|
||||
|
||||
patch_get_signal(freqtrade, value=(False, True))
|
||||
assert freqtrade.handle_trade(trade) is True
|
||||
|
||||
|
||||
def test_startup_messages(default_conf, mocker):
|
||||
default_conf['dynamic_whitelist'] = 20
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
assert freqtrade.state is State.RUNNING
|
||||
|
@@ -1,5 +1,6 @@
|
||||
# pragma pylint: disable=missing-docstring, C0103
|
||||
from unittest.mock import MagicMock
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import create_engine
|
||||
@@ -403,7 +404,9 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||
"""
|
||||
Test Database migration (starting with new pairformat)
|
||||
"""
|
||||
caplog.set_level(logging.DEBUG)
|
||||
amount = 103.223
|
||||
# Always create all columns apart from the last!
|
||||
create_table_old = """CREATE TABLE IF NOT EXISTS "trades" (
|
||||
id INTEGER NOT NULL,
|
||||
exchange VARCHAR NOT NULL,
|
||||
@@ -418,14 +421,21 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||
open_date DATETIME NOT NULL,
|
||||
close_date DATETIME,
|
||||
open_order_id VARCHAR,
|
||||
stop_loss FLOAT,
|
||||
initial_stop_loss FLOAT,
|
||||
max_rate FLOAT,
|
||||
sell_reason VARCHAR,
|
||||
strategy VARCHAR,
|
||||
PRIMARY KEY (id),
|
||||
CHECK (is_open IN (0, 1))
|
||||
);"""
|
||||
insert_table_old = """INSERT INTO trades (exchange, pair, is_open, fee,
|
||||
open_rate, stake_amount, amount, open_date)
|
||||
open_rate, stake_amount, amount, open_date,
|
||||
stop_loss, initial_stop_loss, max_rate)
|
||||
VALUES ('binance', 'ETC/BTC', 1, {fee},
|
||||
0.00258580, {stake}, {amount},
|
||||
'2019-11-28 12:44:24.000000')
|
||||
'2019-11-28 12:44:24.000000',
|
||||
0.0, 0.0, 0.0)
|
||||
""".format(fee=fee.return_value,
|
||||
stake=default_conf.get("stake_amount"),
|
||||
amount=amount
|
||||
@@ -463,12 +473,15 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||
assert trade.ticker_interval is None
|
||||
assert log_has("trying trades_bak1", caplog.record_tuples)
|
||||
assert log_has("trying trades_bak2", caplog.record_tuples)
|
||||
assert log_has("Running database migration - backup available as trades_bak2",
|
||||
caplog.record_tuples)
|
||||
|
||||
|
||||
def test_migrate_mid_state(mocker, default_conf, fee, caplog):
|
||||
"""
|
||||
Test Database migration (starting with new pairformat)
|
||||
"""
|
||||
caplog.set_level(logging.DEBUG)
|
||||
amount = 103.223
|
||||
create_table_old = """CREATE TABLE IF NOT EXISTS "trades" (
|
||||
id INTEGER NOT NULL,
|
||||
@@ -522,6 +535,8 @@ def test_migrate_mid_state(mocker, default_conf, fee, caplog):
|
||||
assert trade.stop_loss == 0.0
|
||||
assert trade.initial_stop_loss == 0.0
|
||||
assert log_has("trying trades_bak0", caplog.record_tuples)
|
||||
assert log_has("Running database migration - backup available as trades_bak0",
|
||||
caplog.record_tuples)
|
||||
|
||||
|
||||
def test_adjust_stop_loss(limit_buy_order, limit_sell_order, fee):
|
||||
|
16
freqtrade/tests/test_talib.py
Normal file
16
freqtrade/tests/test_talib.py
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
import talib.abstract as ta
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def test_talib_bollingerbands_near_zero_values():
|
||||
inputs = pd.DataFrame([
|
||||
{'close': 0.00000010},
|
||||
{'close': 0.00000011},
|
||||
{'close': 0.00000012},
|
||||
{'close': 0.00000013},
|
||||
{'close': 0.00000014}
|
||||
])
|
||||
bollinger = ta.BBANDS(inputs, matype=0, timeperiod=2)
|
||||
assert (bollinger['upperband'][3] != bollinger['middleband'][3])
|
Reference in New Issue
Block a user