commit
4a91ecd91a
@ -1,3 +1,10 @@
|
||||
[MASTER]
|
||||
extension-pkg-whitelist=numpy,talib
|
||||
|
||||
[BASIC]
|
||||
good-names=logger
|
||||
ignore=vendor
|
||||
ignore=vendor
|
||||
|
||||
[TYPECHECK]
|
||||
ignored-modules=numpy,talib
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
""" FreqTrade bot """
|
||||
__version__ = '0.14.2'
|
||||
|
||||
from . import main
|
||||
|
@ -1,3 +1,6 @@
|
||||
"""
|
||||
Functions to analyze ticker data with indicators and produce buy and sell signals
|
||||
"""
|
||||
from enum import Enum
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
@ -7,11 +10,12 @@ import talib.abstract as ta
|
||||
from pandas import DataFrame, to_datetime
|
||||
|
||||
from freqtrade.exchange import get_ticker_history
|
||||
from freqtrade.vendor.qtpylib.indicators import awesome_oscillator, crossed_above, crossed_below
|
||||
from freqtrade.vendor.qtpylib.indicators import awesome_oscillator, crossed_above
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class SignalType(Enum):
|
||||
""" Enum to distinguish between buy and sell signals """
|
||||
BUY = "buy"
|
||||
SELL = "sell"
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
# pragma pylint: disable=W0603
|
||||
""" Cryptocurrency Exchanges support """
|
||||
import enum
|
||||
import logging
|
||||
from random import randint
|
||||
@ -77,7 +79,7 @@ def validate_pairs(pairs: List[str]) -> None:
|
||||
def buy(pair: str, rate: float, amount: float) -> str:
|
||||
if _CONF['dry_run']:
|
||||
global _DRY_RUN_OPEN_ORDERS
|
||||
order_id = 'dry_run_buy_{}'.format(randint(0, 1e6))
|
||||
order_id = 'dry_run_buy_{}'.format(randint(0, 10**6))
|
||||
_DRY_RUN_OPEN_ORDERS[order_id] = {
|
||||
'pair': pair,
|
||||
'rate': rate,
|
||||
@ -95,7 +97,7 @@ def buy(pair: str, rate: float, amount: float) -> str:
|
||||
def sell(pair: str, rate: float, amount: float) -> str:
|
||||
if _CONF['dry_run']:
|
||||
global _DRY_RUN_OPEN_ORDERS
|
||||
order_id = 'dry_run_sell_{}'.format(randint(0, 1e6))
|
||||
order_id = 'dry_run_sell_{}'.format(randint(0, 10**6))
|
||||
_DRY_RUN_OPEN_ORDERS[order_id] = {
|
||||
'pair': pair,
|
||||
'rate': rate,
|
||||
|
@ -1,3 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
import json
|
||||
import os
|
||||
|
||||
@ -11,9 +12,9 @@ def load_backtesting_data(ticker_interval: int = 5):
|
||||
]
|
||||
for pair in pairs:
|
||||
with open('{abspath}/testdata/{pair}-{ticker_interval}.json'.format(
|
||||
abspath=path,
|
||||
pair=pair,
|
||||
ticker_interval=ticker_interval,
|
||||
)) as fp:
|
||||
result[pair] = json.load(fp)
|
||||
abspath=path,
|
||||
pair=pair,
|
||||
ticker_interval=ticker_interval,
|
||||
)) as tickerdata:
|
||||
result[pair] = json.load(tickerdata)
|
||||
return result
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,W0621
|
||||
from datetime import datetime
|
||||
import json
|
||||
import pytest
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,W0212
|
||||
|
||||
|
||||
import logging
|
||||
@ -23,13 +23,13 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def format_results(results: DataFrame):
|
||||
return 'Made {} buys. Average profit {:.2f}%. ' \
|
||||
'Total profit was {:.3f}. Average duration {:.1f} mins.'.format(
|
||||
len(results.index),
|
||||
results.profit.mean() * 100.0,
|
||||
results.profit.sum(),
|
||||
results.duration.mean() * 5,
|
||||
)
|
||||
return ('Made {} buys. Average profit {:.2f}%. '
|
||||
'Total profit was {:.3f}. Average duration {:.1f} mins.').format(
|
||||
len(results.index),
|
||||
results.profit.mean() * 100.0,
|
||||
results.profit.sum(),
|
||||
results.duration.mean() * 5,
|
||||
)
|
||||
|
||||
|
||||
def preprocess(backdata) -> Dict[str, DataFrame]:
|
||||
@ -47,11 +47,11 @@ def get_timeframe(data: Dict[str, Dict]) -> Tuple[arrow.Arrow, arrow.Arrow]:
|
||||
"""
|
||||
min_date, max_date = None, None
|
||||
for values in data.values():
|
||||
values = sorted(values, key=lambda d: arrow.get(d['T']))
|
||||
if not min_date or values[0]['T'] < min_date:
|
||||
min_date = values[0]['T']
|
||||
if not max_date or values[-1]['T'] > max_date:
|
||||
max_date = values[-1]['T']
|
||||
sorted_values = sorted(values, key=lambda d: arrow.get(d['T']))
|
||||
if not min_date or sorted_values[0]['T'] < min_date:
|
||||
min_date = sorted_values[0]['T']
|
||||
if not max_date or sorted_values[-1]['T'] > max_date:
|
||||
max_date = sorted_values[-1]['T']
|
||||
return arrow.get(min_date), arrow.get(max_date)
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,C0103
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
@ -33,4 +33,3 @@ def test_validate_pairs_not_compatible(default_conf, mocker):
|
||||
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
|
||||
with pytest.raises(RuntimeError, match=r'not compatible'):
|
||||
validate_pairs(default_conf['exchange']['pair_whitelist'])
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,W0212
|
||||
import logging
|
||||
import os
|
||||
from functools import reduce
|
||||
@ -21,6 +21,7 @@ logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
|
||||
# set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data
|
||||
TARGET_TRADES = 1100
|
||||
TOTAL_TRIES = 4
|
||||
# pylint: disable=C0103
|
||||
current_tries = 0
|
||||
|
||||
|
||||
@ -90,6 +91,7 @@ def test_hyperopt(backtest_conf, mocker):
|
||||
trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2)
|
||||
profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000
|
||||
|
||||
# pylint: disable=W0603
|
||||
global current_tries
|
||||
current_tries += 1
|
||||
print('{}/{}: {}'.format(current_tries, TOTAL_TRIES, result))
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,C0103
|
||||
import copy
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
@ -26,7 +26,7 @@ def test_process_trade_creation(default_conf, ticker, health, mocker):
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||
assert len(trades) == 0
|
||||
assert not trades
|
||||
|
||||
result = _process()
|
||||
assert result is True
|
||||
@ -81,7 +81,8 @@ def test_process_runtime_error(default_conf, ticker, health, mocker):
|
||||
def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, mocker):
|
||||
mocker.patch.dict('freqtrade.main._CONF', default_conf)
|
||||
mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock())
|
||||
signal = mocker.patch('freqtrade.main.get_signal', side_effect=lambda *args: False if args[1] == SignalType.SELL else True)
|
||||
mocker.patch('freqtrade.main.get_signal',
|
||||
side_effect=lambda *args: False if args[1] == SignalType.SELL else True)
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker,
|
||||
@ -91,7 +92,7 @@ def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, m
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||
assert len(trades) == 0
|
||||
assert not trades
|
||||
result = _process()
|
||||
assert result is True
|
||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring
|
||||
# pragma pylint: disable=missing-docstring,C0103
|
||||
import time
|
||||
import os
|
||||
from argparse import Namespace
|
||||
|
@ -1,10 +1,9 @@
|
||||
# pragma pylint: disable=missing-docstring, too-many-arguments, too-many-ancestors
|
||||
# pragma pylint: disable=missing-docstring, too-many-arguments, too-many-ancestors, C0103
|
||||
import re
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import create_engine
|
||||
from telegram import Update, Message, Chat
|
||||
from telegram.error import NetworkError
|
||||
@ -519,7 +518,7 @@ def test_send_msg(default_conf, mocker):
|
||||
init=MagicMock())
|
||||
bot = MagicMock()
|
||||
send_msg('test', bot)
|
||||
assert len(bot.method_calls) == 0
|
||||
assert not bot.method_calls
|
||||
bot.reset_mock()
|
||||
|
||||
default_conf['telegram']['enabled'] = True
|
||||
|
Loading…
Reference in New Issue
Block a user