Merge branch 'develop' into sell_signal

This commit is contained in:
Janne Sinivirta 2017-12-29 16:26:23 +02:00 committed by GitHub
commit f2ce367cec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 182 additions and 91 deletions

View File

@ -87,17 +87,17 @@ def download_backtesting_testdata(pair: str, interval: int = 5) -> bool:
)) ))
filepair = pair.replace("-", "_") filepair = pair.replace("-", "_")
filename = os.path.join(path, '{}-{}.json'.format( filename = os.path.join(path, '{pair}-{interval}.json'.format(
filepair, pair=filepair,
interval, interval=interval,
)) ))
filename = filename.replace('USDT_BTC', 'BTC_FAKEBULL') filename = filename.replace('USDT_BTC', 'BTC_FAKEBULL')
if os.path.isfile(filename): if os.path.isfile(filename):
with open(filename, "rt") as fp: with open(filename, "rt") as fp:
data = json.load(fp) data = json.load(fp)
logger.debug("Current Start:", data[1]['T']) logger.debug("Current Start: {}".format(data[1]['T']))
logger.debug("Current End: ", data[-1:][0]['T']) logger.debug("Current End: {}".format(data[-1:][0]['T']))
else: else:
data = [] data = []
logger.debug("Current Start: None") logger.debug("Current Start: None")
@ -107,8 +107,8 @@ def download_backtesting_testdata(pair: str, interval: int = 5) -> bool:
for row in new_data: for row in new_data:
if row not in data: if row not in data:
data.append(row) data.append(row)
logger.debug("New Start:", data[1]['T']) logger.debug("New Start: {}".format(data[1]['T']))
logger.debug("New End: ", data[-1:][0]['T']) logger.debug("New End: {}".format(data[-1:][0]['T']))
data = sorted(data, key=lambda data: data['T']) data = sorted(data, key=lambda data: data['T'])
with open(filename, "wt") as fp: with open(filename, "wt") as fp:

View File

@ -1,12 +1,12 @@
import logging import logging
import re import re
from decimal import Decimal from decimal import Decimal
from datetime import timedelta, date, datetime from datetime import timedelta, datetime
from typing import Callable, Any from typing import Callable, Any
import arrow import arrow
from pandas import DataFrame from pandas import DataFrame
from sqlalchemy import and_, func, text, between from sqlalchemy import and_, func, text
from tabulate import tabulate from tabulate import tabulate
from telegram import ParseMode, Bot, Update, ReplyKeyboardMarkup from telegram import ParseMode, Bot, Update, ReplyKeyboardMarkup
from telegram.error import NetworkError, TelegramError from telegram.error import NetworkError, TelegramError
@ -220,29 +220,28 @@ def _daily(bot: Bot, update: Update) -> None:
:param update: message update :param update: message update
:return: None :return: None
""" """
today = datetime.utcnow().toordinal() today = datetime.utcnow().date()
profit_days = {} profit_days = {}
try: try:
timescale = int(update.message.text.replace('/daily', '').strip()) timescale = int(update.message.text.replace('/daily', '').strip())
except (TypeError, ValueError): except (TypeError, ValueError):
timescale = 5 timescale = 7
if not (isinstance(timescale, int) and timescale > 0): if not (isinstance(timescale, int) and timescale > 0):
send_msg('*Daily [n]:* `must be an integer greater than 0`', bot=bot) send_msg('*Daily [n]:* `must be an integer greater than 0`', bot=bot)
return return
for day in range(0, timescale): for day in range(0, timescale):
# need to query between day+1 and day-1 profitday = today - timedelta(days=day)
nextdate = date.fromordinal(today - day + 1)
prevdate = date.fromordinal(today - day - 1)
trades = Trade.query \ trades = Trade.query \
.filter(Trade.is_open.is_(False)) \ .filter(Trade.is_open.is_(False)) \
.filter(between(Trade.close_date, prevdate, nextdate)) \ .filter(Trade.close_date >= profitday)\
.filter(Trade.close_date < (profitday + timedelta(days=1)))\
.order_by(Trade.close_date)\ .order_by(Trade.close_date)\
.all() .all()
curdayprofit = sum(trade.calc_profit() for trade in trades) curdayprofit = sum(trade.calc_profit() for trade in trades)
profit_days[date.fromordinal(today - day)] = format(curdayprofit, '.8f') profit_days[profitday] = format(curdayprofit, '.8f')
stats = [ stats = [
[ [

View File

@ -1,11 +1,9 @@
# pragma pylint: disable=missing-docstring,W0212 # pragma pylint: disable=missing-docstring,W0212
import os
import pandas as pd import pandas as pd
from freqtrade import exchange, optimize from freqtrade import exchange, optimize
from freqtrade.exchange import Bittrex from freqtrade.exchange import Bittrex
from freqtrade.optimize.backtesting import backtest, generate_text_table, get_timeframe from freqtrade.optimize.backtesting import backtest, generate_text_table, get_timeframe
from freqtrade.optimize.__init__ import testdata_path, download_pairs, download_backtesting_testdata
def test_generate_text_table(): def test_generate_text_table():
@ -40,7 +38,7 @@ def test_backtest(default_conf, mocker):
assert not results.empty assert not results.empty
def test_1min_ticker_interval(default_conf, mocker): def test_backtest_1min_ticker_interval(default_conf, mocker):
mocker.patch.dict('freqtrade.main._CONF', default_conf) mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
@ -48,75 +46,3 @@ def test_1min_ticker_interval(default_conf, mocker):
data = optimize.load_data(ticker_interval=1, pairs=['BTC_UNITEST']) data = optimize.load_data(ticker_interval=1, pairs=['BTC_UNITEST'])
results = backtest(default_conf['stake_amount'], optimize.preprocess(data), 1, True) results = backtest(default_conf['stake_amount'], optimize.preprocess(data), 1, True)
assert not results.empty assert not results.empty
def test_backtest_with_new_pair(default_conf, ticker_history, mocker):
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
optimize.load_data(ticker_interval=1, pairs=['BTC_MEME'])
file = 'freqtrade/tests/testdata/BTC_MEME-1.json'
assert os.path.isfile(file) is True
# delete file freshly downloaded
if os.path.isfile(file):
os.remove(file)
def test_testdata_path():
assert os.path.join('freqtrade', 'tests', 'testdata') in testdata_path()
def test_download_pairs(default_conf, ticker_history, mocker):
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file1_1 = 'freqtrade/tests/testdata/BTC_MEME-1.json'
file1_5 = 'freqtrade/tests/testdata/BTC_MEME-5.json'
file2_1 = 'freqtrade/tests/testdata/BTC_CFI-1.json'
file2_5 = 'freqtrade/tests/testdata/BTC_CFI-5.json'
assert download_pairs(pairs=['BTC-MEME', 'BTC-CFI']) is True
assert os.path.isfile(file1_1) is True
assert os.path.isfile(file1_5) is True
assert os.path.isfile(file2_1) is True
assert os.path.isfile(file2_5) is True
# delete files freshly downloaded
if os.path.isfile(file1_1):
os.remove(file1_1)
if os.path.isfile(file1_5):
os.remove(file1_5)
if os.path.isfile(file2_1):
os.remove(file2_1)
if os.path.isfile(file2_5):
os.remove(file2_5)
def test_download_backtesting_testdata(default_conf, ticker_history, mocker):
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
# Download a 1 min ticker file
file1 = 'freqtrade/tests/testdata/BTC_XEL-1.json'
download_backtesting_testdata(pair="BTC-XEL", interval=1)
assert os.path.isfile(file1) is True
if os.path.isfile(file1):
os.remove(file1)
# Download a 5 min ticker file
file2 = 'freqtrade/tests/testdata/BTC_STORJ-5.json'
download_backtesting_testdata(pair="BTC-STORJ", interval=5)
assert os.path.isfile(file2) is True
if os.path.isfile(file2):
os.remove(file2)

View File

@ -0,0 +1,166 @@
# pragma pylint: disable=missing-docstring,W0212
import os
import logging
from shutil import copyfile
from freqtrade import exchange, optimize
from freqtrade.exchange import Bittrex
from freqtrade.optimize.__init__ import testdata_path, download_pairs, download_backtesting_testdata
def _backup_file(file: str, copy_file: bool = False) -> None:
"""
Backup existing file to avoid deleting the user file
:param file: complete path to the file
:param touch_file: create an empty file in replacement
:return: None
"""
file_swp = file + '.swp'
if os.path.isfile(file):
os.rename(file, file_swp)
if copy_file:
copyfile(file_swp, file)
def _clean_test_file(file: str) -> None:
"""
Backup existing file to avoid deleting the user file
:param file: complete path to the file
:return: None
"""
file_swp = file + '.swp'
# 1. Delete file from the test
if os.path.isfile(file):
os.remove(file)
# 2. Rollback to the initial file
if os.path.isfile(file_swp):
os.rename(file_swp, file)
def test_load_data_5min_ticker(default_conf, ticker_history, mocker, caplog):
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file = 'freqtrade/tests/testdata/BTC_ETH-5.json'
_backup_file(file, copy_file=True)
optimize.load_data(pairs=['BTC_ETH'])
assert os.path.isfile(file) is True
assert ('freqtrade.optimize',
logging.INFO,
'Download the pair: "BTC_ETH", Interval: 5 min'
) not in caplog.record_tuples
_clean_test_file(file)
def test_load_data_1min_ticker(default_conf, ticker_history, mocker, caplog):
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file = 'freqtrade/tests/testdata/BTC_ETH-1.json'
_backup_file(file, copy_file=True)
optimize.load_data(ticker_interval=1, pairs=['BTC_ETH'])
assert os.path.isfile(file) is True
assert ('freqtrade.optimize',
logging.INFO,
'Download the pair: "BTC_ETH", Interval: 1 min'
) not in caplog.record_tuples
_clean_test_file(file)
def test_load_data_with_new_pair_1min(default_conf, ticker_history, mocker, caplog):
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file = 'freqtrade/tests/testdata/BTC_MEME-1.json'
_backup_file(file)
optimize.load_data(ticker_interval=1, pairs=['BTC_MEME'])
assert os.path.isfile(file) is True
assert ('freqtrade.optimize',
logging.INFO,
'Download the pair: "BTC_MEME", Interval: 1 min'
) in caplog.record_tuples
_clean_test_file(file)
def test_testdata_path():
assert os.path.join('freqtrade', 'tests', 'testdata') in testdata_path()
def test_download_pairs(default_conf, ticker_history, mocker):
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file1_1 = 'freqtrade/tests/testdata/BTC_MEME-1.json'
file1_5 = 'freqtrade/tests/testdata/BTC_MEME-5.json'
file2_1 = 'freqtrade/tests/testdata/BTC_CFI-1.json'
file2_5 = 'freqtrade/tests/testdata/BTC_CFI-5.json'
_backup_file(file1_1)
_backup_file(file1_5)
_backup_file(file2_1)
_backup_file(file2_5)
assert download_pairs(pairs=['BTC-MEME', 'BTC-CFI']) is True
assert os.path.isfile(file1_1) is True
assert os.path.isfile(file1_5) is True
assert os.path.isfile(file2_1) is True
assert os.path.isfile(file2_5) is True
# clean files freshly downloaded
_clean_test_file(file1_1)
_clean_test_file(file1_5)
_clean_test_file(file2_1)
_clean_test_file(file2_5)
def test_download_pairs_exception(default_conf, ticker_history, mocker, caplog):
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.optimize.__init__.download_backtesting_testdata',
side_effect=BaseException('File Error'))
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
file1_1 = 'freqtrade/tests/testdata/BTC_MEME-1.json'
file1_5 = 'freqtrade/tests/testdata/BTC_MEME-5.json'
_backup_file(file1_1)
_backup_file(file1_5)
download_pairs(pairs=['BTC-MEME'])
# clean files freshly downloaded
_clean_test_file(file1_1)
_clean_test_file(file1_5)
assert ('freqtrade.optimize.__init__',
logging.INFO,
'Failed to download the pair: "BTC-MEME", Interval: 1 min'
) in caplog.record_tuples
def test_download_backtesting_testdata(default_conf, ticker_history, mocker):
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
mocker.patch.dict('freqtrade.main._CONF', default_conf)
exchange._API = Bittrex({'key': '', 'secret': ''})
# Download a 1 min ticker file
file1 = 'freqtrade/tests/testdata/BTC_XEL-1.json'
_backup_file(file1)
download_backtesting_testdata(pair="BTC-XEL", interval=1)
assert os.path.isfile(file1) is True
_clean_test_file(file1)
# Download a 5 min ticker file
file2 = 'freqtrade/tests/testdata/BTC_STORJ-5.json'
_backup_file(file2)
download_backtesting_testdata(pair="BTC-STORJ", interval=5)
assert os.path.isfile(file2) is True
_clean_test_file(file2)