Merge branch 'develop' into log_has_ref
This commit is contained in:
commit
002003292e
@ -20,7 +20,7 @@ from freqtrade.exchange import timeframe_to_minutes
|
|||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPCManager, RPCMessageType
|
from freqtrade.rpc import RPCManager, RPCMessageType
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver
|
from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State, RunMode
|
||||||
from freqtrade.strategy.interface import SellType, IStrategy
|
from freqtrade.strategy.interface import SellType, IStrategy
|
||||||
from freqtrade.wallets import Wallets
|
from freqtrade.wallets import Wallets
|
||||||
|
|
||||||
@ -75,6 +75,12 @@ class FreqtradeBot(object):
|
|||||||
persistence.init(self.config.get('db_url', None),
|
persistence.init(self.config.get('db_url', None),
|
||||||
clean_open_orders=self.config.get('dry_run', False))
|
clean_open_orders=self.config.get('dry_run', False))
|
||||||
|
|
||||||
|
# Stoploss on exchange does not make sense, therefore we need to disable that.
|
||||||
|
if (self.dataprovider.runmode == RunMode.DRY_RUN and
|
||||||
|
self.strategy.order_types.get('stoploss_on_exchange', False)):
|
||||||
|
logger.info("Disabling stoploss_on_exchange during dry-run.")
|
||||||
|
self.strategy.order_types['stoploss_on_exchange'] = False
|
||||||
|
config['order_types']['stoploss_on_exchange'] = False
|
||||||
# Set initial bot state from config
|
# Set initial bot state from config
|
||||||
initial_state = self.config.get('initial_state')
|
initial_state = self.config.get('initial_state')
|
||||||
self.state = State[initial_state.upper()] if initial_state else State.STOPPED
|
self.state = State[initial_state.upper()] if initial_state else State.STOPPED
|
||||||
|
@ -10,7 +10,7 @@ from typing import Dict, Any, List, Optional
|
|||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
import sqlalchemy as sql
|
import sqlalchemy as sql
|
||||||
from numpy import mean, nan_to_num, NAN
|
from numpy import mean, NAN
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import TemporaryError, DependencyException
|
from freqtrade import TemporaryError, DependencyException
|
||||||
@ -195,9 +195,9 @@ class RPC(object):
|
|||||||
trades = Trade.query.order_by(Trade.id).all()
|
trades = Trade.query.order_by(Trade.id).all()
|
||||||
|
|
||||||
profit_all_coin = []
|
profit_all_coin = []
|
||||||
profit_all_percent = []
|
profit_all_perc = []
|
||||||
profit_closed_coin = []
|
profit_closed_coin = []
|
||||||
profit_closed_percent = []
|
profit_closed_perc = []
|
||||||
durations = []
|
durations = []
|
||||||
|
|
||||||
for trade in trades:
|
for trade in trades:
|
||||||
@ -211,7 +211,7 @@ class RPC(object):
|
|||||||
if not trade.is_open:
|
if not trade.is_open:
|
||||||
profit_percent = trade.calc_profit_percent()
|
profit_percent = trade.calc_profit_percent()
|
||||||
profit_closed_coin.append(trade.calc_profit())
|
profit_closed_coin.append(trade.calc_profit())
|
||||||
profit_closed_percent.append(profit_percent)
|
profit_closed_perc.append(profit_percent)
|
||||||
else:
|
else:
|
||||||
# Get current rate
|
# Get current rate
|
||||||
try:
|
try:
|
||||||
@ -223,7 +223,7 @@ class RPC(object):
|
|||||||
profit_all_coin.append(
|
profit_all_coin.append(
|
||||||
trade.calc_profit(rate=Decimal(trade.close_rate or current_rate))
|
trade.calc_profit(rate=Decimal(trade.close_rate or current_rate))
|
||||||
)
|
)
|
||||||
profit_all_percent.append(profit_percent)
|
profit_all_perc.append(profit_percent)
|
||||||
|
|
||||||
best_pair = Trade.session.query(
|
best_pair = Trade.session.query(
|
||||||
Trade.pair, sql.func.sum(Trade.close_profit).label('profit_sum')
|
Trade.pair, sql.func.sum(Trade.close_profit).label('profit_sum')
|
||||||
@ -238,7 +238,8 @@ class RPC(object):
|
|||||||
|
|
||||||
# Prepare data to display
|
# Prepare data to display
|
||||||
profit_closed_coin_sum = round(sum(profit_closed_coin), 8)
|
profit_closed_coin_sum = round(sum(profit_closed_coin), 8)
|
||||||
profit_closed_percent = round(nan_to_num(mean(profit_closed_percent)) * 100, 2)
|
profit_closed_percent = (round(mean(profit_closed_perc) * 100, 2) if profit_closed_perc
|
||||||
|
else 0.0)
|
||||||
profit_closed_fiat = self._fiat_converter.convert_amount(
|
profit_closed_fiat = self._fiat_converter.convert_amount(
|
||||||
profit_closed_coin_sum,
|
profit_closed_coin_sum,
|
||||||
stake_currency,
|
stake_currency,
|
||||||
@ -246,7 +247,7 @@ class RPC(object):
|
|||||||
) if self._fiat_converter else 0
|
) if self._fiat_converter else 0
|
||||||
|
|
||||||
profit_all_coin_sum = round(sum(profit_all_coin), 8)
|
profit_all_coin_sum = round(sum(profit_all_coin), 8)
|
||||||
profit_all_percent = round(nan_to_num(mean(profit_all_percent)) * 100, 2)
|
profit_all_percent = round(mean(profit_all_perc) * 100, 2) if profit_all_perc else 0.0
|
||||||
profit_all_fiat = self._fiat_converter.convert_amount(
|
profit_all_fiat = self._fiat_converter.convert_amount(
|
||||||
profit_all_coin_sum,
|
profit_all_coin_sum,
|
||||||
stake_currency,
|
stake_currency,
|
||||||
|
@ -10,6 +10,7 @@ from unittest.mock import MagicMock, PropertyMock
|
|||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
import pytest
|
import pytest
|
||||||
|
import numpy as np
|
||||||
from telegram import Chat, Message, Update
|
from telegram import Chat, Message, Update
|
||||||
|
|
||||||
from freqtrade import constants, persistence
|
from freqtrade import constants, persistence
|
||||||
@ -25,6 +26,10 @@ from freqtrade.worker import Worker
|
|||||||
logging.getLogger('').setLevel(logging.INFO)
|
logging.getLogger('').setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
# Do not mask numpy errors as warnings that no one read, raise the exсeption
|
||||||
|
np.seterr(all='raise')
|
||||||
|
|
||||||
|
|
||||||
def log_has(line, logs):
|
def log_has(line, logs):
|
||||||
# caplog mocker returns log as a tuple: ('freqtrade.something', logging.WARNING, 'foobar')
|
# caplog mocker returns log as a tuple: ('freqtrade.something', logging.WARNING, 'foobar')
|
||||||
# and we want to match line against foobar in the tuple
|
# and we want to match line against foobar in the tuple
|
||||||
|
@ -16,7 +16,7 @@ from freqtrade.data.dataprovider import DataProvider
|
|||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPCMessageType
|
from freqtrade.rpc import RPCMessageType
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State, RunMode
|
||||||
from freqtrade.strategy.interface import SellCheckTuple, SellType
|
from freqtrade.strategy.interface import SellCheckTuple, SellType
|
||||||
from freqtrade.tests.conftest import (get_patched_freqtradebot,
|
from freqtrade.tests.conftest import (get_patched_freqtradebot,
|
||||||
get_patched_worker, log_has, log_has_re,
|
get_patched_worker, log_has, log_has_re,
|
||||||
@ -130,7 +130,77 @@ def test_throttle_with_assets(mocker, default_conf) -> None:
|
|||||||
assert result == -1
|
assert result == -1
|
||||||
|
|
||||||
|
|
||||||
def test_get_trade_stake_amount(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_order_dict_dry_run(default_conf, mocker, caplog) -> None:
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_exchange(mocker)
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2)
|
||||||
|
)
|
||||||
|
conf = default_conf.copy()
|
||||||
|
conf['runmode'] = RunMode.DRY_RUN
|
||||||
|
conf['order_types'] = {
|
||||||
|
'buy': 'market',
|
||||||
|
'sell': 'limit',
|
||||||
|
'stoploss': 'limit',
|
||||||
|
'stoploss_on_exchange': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
freqtrade = FreqtradeBot(conf)
|
||||||
|
assert log_has("Disabling stoploss_on_exchange during dry-run.", caplog)
|
||||||
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
# is left untouched
|
||||||
|
conf = default_conf.copy()
|
||||||
|
conf['runmode'] = RunMode.DRY_RUN
|
||||||
|
conf['order_types'] = {
|
||||||
|
'buy': 'market',
|
||||||
|
'sell': 'limit',
|
||||||
|
'stoploss': 'limit',
|
||||||
|
'stoploss_on_exchange': False,
|
||||||
|
}
|
||||||
|
freqtrade = FreqtradeBot(conf)
|
||||||
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
|
|
||||||
|
|
||||||
|
def test_order_dict_live(default_conf, mocker, caplog) -> None:
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_exchange(mocker)
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2)
|
||||||
|
)
|
||||||
|
conf = default_conf.copy()
|
||||||
|
conf['runmode'] = RunMode.LIVE
|
||||||
|
conf['order_types'] = {
|
||||||
|
'buy': 'market',
|
||||||
|
'sell': 'limit',
|
||||||
|
'stoploss': 'limit',
|
||||||
|
'stoploss_on_exchange': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
freqtrade = FreqtradeBot(conf)
|
||||||
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
|
assert freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
# is left untouched
|
||||||
|
conf = default_conf.copy()
|
||||||
|
conf['runmode'] = RunMode.LIVE
|
||||||
|
conf['order_types'] = {
|
||||||
|
'buy': 'market',
|
||||||
|
'sell': 'limit',
|
||||||
|
'stoploss': 'limit',
|
||||||
|
'stoploss_on_exchange': False,
|
||||||
|
}
|
||||||
|
freqtrade = FreqtradeBot(conf)
|
||||||
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
|
Loading…
Reference in New Issue
Block a user