Merge pull request #600 from enenn/ccxt-obecjtify-pr2_1

[2/3] Add support for multiple exchanges with ccxt (objectified version)
This commit is contained in:
Samuel Husso 2018-04-12 07:36:18 +03:00 committed by GitHub
commit eac3c4b72c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 265 additions and 229 deletions

View File

@ -4,7 +4,7 @@
"stake_amount": 0.05,
"fiat_display_currency": "USD",
"dry_run": false,
"ticker_interval": 5,
"ticker_interval": "5m",
"minimal_roi": {
"40": 0.0,
"30": 0.01,

View File

@ -33,7 +33,7 @@ python3 ./freqtrade/main.py backtesting --realistic-simulation
**With 1 min tickers**
```bash
python3 ./freqtrade/main.py backtesting --realistic-simulation --ticker-interval 1
python3 ./freqtrade/main.py backtesting --realistic-simulation --ticker-interval 1m
```
**Reload your testdata files**
@ -117,16 +117,16 @@ A backtesting result will look like that:
====================== BACKTESTING REPORT ================================
pair buy count avg profit % total profit BTC avg duration
-------- ----------- -------------- ------------------ --------------
BTC_ETH 56 -0.67 -0.00075455 62.3
BTC_LTC 38 -0.48 -0.00036315 57.9
BTC_ETC 42 -1.15 -0.00096469 67.0
BTC_DASH 72 -0.62 -0.00089368 39.9
BTC_ZEC 45 -0.46 -0.00041387 63.2
BTC_XLM 24 -0.88 -0.00041846 47.7
BTC_NXT 24 0.68 0.00031833 40.2
BTC_POWR 35 0.98 0.00064887 45.3
BTC_ADA 43 -0.39 -0.00032292 55.0
BTC_XMR 40 -0.40 -0.00032181 47.4
ETH/BTC 56 -0.67 -0.00075455 62.3
LTC/BTC 38 -0.48 -0.00036315 57.9
ETC/BTC 42 -1.15 -0.00096469 67.0
DASH/BTC 72 -0.62 -0.00089368 39.9
ZEC/BTC 45 -0.46 -0.00041387 63.2
XLM/BTC 24 -0.88 -0.00041846 47.7
NXT/BTC 24 0.68 0.00031833 40.2
POWR/BTC 35 0.98 0.00064887 45.3
ADA/BTC 43 -0.39 -0.00032292 55.0
XMR/BTC 40 -0.40 -0.00032181 47.4
TOTAL 419 -0.41 -0.00348593 52.9
```

View File

@ -118,7 +118,7 @@ optional arguments:
-h, --help show this help message and exit
-l, --live using live data
-i INT, --ticker-interval INT
specify ticker interval in minutes (default: 5)
specify ticker interval (default: '5m')
--realistic-simulation
uses max_open_trades from config to simulate real
world limitations

View File

@ -17,7 +17,7 @@ The table below will list all configuration parameters.
| `max_open_trades` | 3 | Yes | Number of trades open your bot will have.
| `stake_currency` | BTC | Yes | Crypto-currency used for trading.
| `stake_amount` | 0.05 | Yes | Amount of crypto-currency your bot will use for each trade. Per default, the bot will use (0.05 BTC x 3) = 0.15 BTC in total will be always engaged.
| `ticker_interval` | [1, 5, 30, 60, 1440] | No | The ticker interval to use (1min, 5 min, 30 min, 1 hour or 1 day). Defaut is 5 minutes
| `ticker_interval` | [1m, 5m, 30m, 1h, 1d] | No | The ticker interval to use (1min, 5 min, 30 min, 1 hour or 1 day). Default is 5 minutes
| `fiat_display_currency` | USD | Yes | Fiat currency used to show your profits. More information below.
| `dry_run` | true | Yes | Define if the bot must be in Dry-run or production mode.
| `minimal_roi` | See below | No | Set the threshold in percent the bot will use to sell a trade. More information below. If set, this parameter will override `minimal_roi` from your strategy file.

View File

@ -42,7 +42,7 @@ Below, example of Telegram message you will receive for each command.
For each open trade, the bot will send you the following message.
> **Trade ID:** `123`
> **Current Pair:** BTC_CVC
> **Current Pair:** CVC/BTC
> **Open Since:** `1 days ago`
> **Amount:** `26.64180098`
> **Open Rate:** `0.00007489`
@ -57,8 +57,8 @@ Return the status of all open trades in a table format.
```
ID Pair Since Profit
---- -------- ------- --------
67 BTC_SC 1 d 13.33%
123 BTC_CVC 1 h 12.95%
67 SC/BTC 1 d 13.33%
123 CVC/BTC 1 h 12.95%
```
## /count
@ -83,7 +83,7 @@ Return a summary of your profit/loss and performance.
> **First Trade opened:** `3 days ago`
> **Latest Trade opened:** `2 minutes ago`
> **Avg. Duration:** `2:33:45`
> **Best Performing:** `BTC_PAY: 50.23%`
> **Best Performing:** `PAY/BTC: 50.23%`
## /forcesell <trade_id>
@ -92,11 +92,11 @@ Return a summary of your profit/loss and performance.
## /performance
Return the performance of each crypto-currency the bot has sold.
> Performance:
> 1. `BTC_RCN 57.77%`
> 2. `BTC_PAY 56.91%`
> 3. `BTC_VIB 47.07%`
> 4. `BTC_SALT 30.24%`
> 5. `BTC_STORJ 27.24%`
> 1. `RCN/BTC 57.77%`
> 2. `PAY/BTC 56.91%`
> 3. `VIB/BTC 47.07%`
> 4. `SALT/BTC 30.24%`
> 5. `STORJ/BTC 27.24%`
> ...
## /balance

View File

@ -12,6 +12,7 @@ from freqtrade.exchange import get_ticker_history
from freqtrade.logger import Logger
from freqtrade.persistence import Trade
from freqtrade.strategy.strategy import Strategy
from freqtrade.constants import Constants
class SignalType(Enum):
@ -81,7 +82,7 @@ class Analyze(object):
"""
return self.strategy.populate_sell_trend(dataframe=dataframe)
def get_ticker_interval(self) -> int:
def get_ticker_interval(self) -> str:
"""
Return ticker interval to use
:return: Ticker interval value to use
@ -100,10 +101,10 @@ class Analyze(object):
dataframe = self.populate_sell_trend(dataframe)
return dataframe
def get_signal(self, pair: str, interval: int) -> Tuple[bool, bool]:
def get_signal(self, pair: str, interval: str) -> Tuple[bool, bool]:
"""
Calculates current signal based several technical analysis indicators
:param pair: pair in format BTC_ANT or BTC-ANT
:param pair: pair in format ANT/BTC
:param interval: Interval to use (in min)
:return: (Buy, Sell) A bool-tuple indicating buy/sell signal
"""
@ -137,7 +138,8 @@ class Analyze(object):
# Check if dataframe is out of date
signal_date = arrow.get(latest['date'])
if signal_date < arrow.utcnow() - timedelta(minutes=(interval + 5)):
interval_minutes = Constants.TICKER_INTERVAL_MINUTES[interval]
if signal_date < arrow.utcnow() - timedelta(minutes=(interval_minutes + 5)):
self.logger.warning(
'Outdated history for pair %s. Last tick is %s minutes old',
pair,

View File

@ -135,10 +135,9 @@ class Arguments(object):
def optimizer_shared_options(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
'-i', '--ticker-interval',
help='specify ticker interval in minutes (1, 5, 30, 60, 1440)',
help='specify ticker interval (1m, 5m, 30m, 1h, 1d)',
dest='ticker_interval',
type=int,
metavar='INT',
type=str,
)
parser.add_argument(
'--realistic-simulation',

View File

@ -117,7 +117,7 @@ class Configuration(object):
if 'ticker_interval' in self.args and self.args.ticker_interval:
config.update({'ticker_interval': self.args.ticker_interval})
self.logger.info('Parameter -i/--ticker-interval detected ...')
self.logger.info('Using ticker_interval: %d ...', config.get('ticker_interval'))
self.logger.info('Using ticker_interval: %s ...', config.get('ticker_interval'))
# If -l/--live is used we add it to the configuration
if 'live' in self.args and self.args.live:

View File

@ -16,12 +16,26 @@ class Constants(object):
RETRY_TIMEOUT = 30 # sec
DEFAULT_STRATEGY = 'default_strategy'
TICKER_INTERVAL_MINUTES = {
'1m': 1,
'5m': 5,
'15m': 15,
'30m': 30,
'1h': 60,
'2h': 120,
'4h': 240,
'6h': 360,
'12h': 720,
'1d': 1440,
'1w': 10080,
}
# Required json-schema for user specified config
CONF_SCHEMA = {
'type': 'object',
'properties': {
'max_open_trades': {'type': 'integer', 'minimum': 1},
'ticker_interval': {'type': 'integer', 'enum': [1, 5, 30, 60, 1440]},
'ticker_interval': {'type': 'string', 'enum': list(TICKER_INTERVAL_MINUTES.keys())},
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']},
'stake_amount': {'type': 'number', 'minimum': 0.0005},
'fiat_display_currency': {'type': 'string', 'enum': ['AUD', 'BRL', 'CAD', 'CHF',

View File

@ -27,15 +27,16 @@ def trim_tickerlist(tickerlist: List[Dict], timerange: Tuple[Tuple, int, int]) -
def load_tickerdata_file(
datadir: str, pair: str,
ticker_interval: int,
ticker_interval: str,
timerange: Optional[Tuple[Tuple, int, int]] = None) -> Optional[List[Dict]]:
"""
Load a pair from file,
:return dict OR empty if unsuccesful
"""
path = make_testdata_path(datadir)
pair_file_string = pair.replace('/', '_')
file = os.path.join(path, '{pair}-{ticker_interval}.json'.format(
pair=pair.replace('/', '_'),
pair=pair_file_string,
ticker_interval=ticker_interval,
))
gzipfile = file + '.gz'
@ -58,7 +59,8 @@ def load_tickerdata_file(
return pairdata
def load_data(datadir: str, ticker_interval: int,
def load_data(datadir: str,
ticker_interval: str,
pairs: Optional[List[str]] = None,
refresh_pairs: Optional[bool] = False,
timerange: Optional[Tuple[Tuple, int, int]] = None) -> Dict[str, List]:
@ -95,14 +97,14 @@ def make_testdata_path(datadir: str) -> str:
)
def download_pairs(datadir, pairs: List[str], ticker_interval: int) -> bool:
def download_pairs(datadir, pairs: List[str], ticker_interval: str) -> bool:
"""For each pairs passed in parameters, download the ticker intervals"""
for pair in pairs:
try:
download_backtesting_testdata(datadir, pair=pair, interval=ticker_interval)
except BaseException:
logger.info(
'Failed to download the pair: "%s", Interval: %s min',
'Failed to download the pair: "%s", Interval: %s',
pair,
ticker_interval
)
@ -111,7 +113,7 @@ def download_pairs(datadir, pairs: List[str], ticker_interval: int) -> bool:
# FIX: 20180110, suggest rename interval to tick_interval
def download_backtesting_testdata(datadir: str, pair: str, interval: int = 5) -> bool:
def download_backtesting_testdata(datadir: str, pair: str, interval: str = '5m') -> bool:
"""
Download the latest 1 and 5 ticker intervals from Bittrex for the pairs passed in parameters
Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
@ -121,7 +123,7 @@ def download_backtesting_testdata(datadir: str, pair: str, interval: int = 5) ->
path = make_testdata_path(datadir)
logger.info(
'Download the pair: "%s", Interval: %s min',
'Download the pair: "%s", Interval: %s',
pair,
interval
)
@ -142,7 +144,7 @@ def download_backtesting_testdata(datadir: str, pair: str, interval: int = 5) ->
logger.debug("Current Start: None")
logger.debug("Current End: None")
new_data = get_ticker_history(pair=pair, tick_interval=int(interval))
new_data = get_ticker_history(pair=pair, tick_interval=interval)
for row in new_data:
if row not in data:
data.append(row)

View File

@ -262,9 +262,9 @@ class RPC(object):
currency["Rate"] = 1.0
else:
if coin == 'USDT':
currency["Rate"] = 1.0 / exchange.get_ticker('USDT_BTC', False)['bid']
currency["Rate"] = 1.0 / exchange.get_ticker('BTC/USDT', False)['bid']
else:
currency["Rate"] = exchange.get_ticker('BTC_' + coin, False)['bid']
currency["Rate"] = exchange.get_ticker(coin + '/BTC', False)['bid']
currency['BTC'] = currency["Rate"] * currency["Balance"]
total = total + currency['BTC']
output.append(

View File

@ -28,7 +28,7 @@ class DefaultStrategy(IStrategy):
stoploss = -0.10
# Optimal ticker interval for the strategy
ticker_interval = 5
ticker_interval = '5m'
def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
"""

View File

@ -65,7 +65,7 @@ class Strategy(object):
# Optimal stoploss designed for the strategy
self.stoploss = float(self.custom_strategy.stoploss)
self.ticker_interval = int(self.custom_strategy.ticker_interval)
self.ticker_interval = self.custom_strategy.ticker_interval
def _load_strategy(self, strategy_name: str) -> None:
"""

View File

@ -54,7 +54,7 @@ def default_conf():
"stake_currency": "BTC",
"stake_amount": 0.001,
"fiat_display_currency": "USD",
"ticker_interval": 5,
"ticker_interval": '5m',
"dry_run": True,
"minimal_roi": {
"40": 0.0,
@ -323,10 +323,9 @@ def ticker_history_without_bv():
]
# FIX: Perhaps change result fixture to use BTC_UNITEST instead?
@pytest.fixture
def result():
with open('freqtrade/tests/testdata/BTC_ETH-1.json') as data_file:
with open('freqtrade/tests/testdata/UNITTEST_BTC-1m.json') as data_file:
return Analyze.parse_ticker_dataframe(json.load(data_file))

View File

@ -34,8 +34,8 @@ def trim_dictlist(dict_list, num):
def load_data_test(what):
timerange = ((None, 'line'), None, -100)
data = optimize.load_data(None, ticker_interval=1, pairs=['BTC_UNITEST'], timerange=timerange)
pair = data['BTC_UNITEST']
data = optimize.load_data(None, ticker_interval='1m', pairs=['UNITTEST/BTC'], timerange=timerange)
pair = data['UNITTEST/BTC']
datalen = len(pair)
# Depending on the what parameter we now adjust the
# loaded data looks:
@ -44,7 +44,7 @@ def load_data_test(what):
# 'T': '2017-11-04T23:02:00', 'BV': 0.123}]
base = 0.001
if what == 'raise':
return {'BTC_UNITEST':
return {'UNITTEST/BTC':
[{'T': pair[x]['T'], # Keep old dates
'V': pair[x]['V'], # Keep old volume
'BV': pair[x]['BV'], # keep too
@ -53,7 +53,7 @@ def load_data_test(what):
'L': x * base - 0.0001,
'C': x * base} for x in range(0, datalen)]}
if what == 'lower':
return {'BTC_UNITEST':
return {'UNITTEST/BTC':
[{'T': pair[x]['T'], # Keep old dates
'V': pair[x]['V'], # Keep old volume
'BV': pair[x]['BV'], # keep too
@ -63,7 +63,7 @@ def load_data_test(what):
'C': 1 - x * base} for x in range(0, datalen)]}
if what == 'sine':
hz = 0.1 # frequency
return {'BTC_UNITEST':
return {'UNITTEST/BTC':
[{'T': pair[x]['T'], # Keep old dates
'V': pair[x]['V'], # Keep old volume
'BV': pair[x]['BV'], # keep too
@ -93,9 +93,9 @@ def simple_backtest(config, contour, num_results) -> None:
assert len(results) == num_results
def mocked_load_data(datadir, pairs=[], ticker_interval=0, refresh_pairs=False, timerange=None):
tickerdata = optimize.load_tickerdata_file(datadir, 'BTC_UNITEST', 1, timerange=timerange)
pairdata = {'BTC_UNITEST': tickerdata}
def mocked_load_data(datadir, pairs=[], ticker_interval='0m', refresh_pairs=False, timerange=None):
tickerdata = optimize.load_tickerdata_file(datadir, 'UNITTEST/BTC', '1m', timerange=timerange)
pairdata = {'UNITTEST/BTC': tickerdata}
return pairdata
@ -107,8 +107,8 @@ def _load_pair_as_ticks(pair, tickfreq):
# FIX: fixturize this?
def _make_backtest_conf(conf=None, pair='BTC_UNITEST', record=None):
data = optimize.load_data(None, ticker_interval=8, pairs=[pair])
def _make_backtest_conf(conf=None, pair='UNITTEST/BTC', record=None):
data = optimize.load_data(None, ticker_interval='8m', pairs=[pair])
data = trim_dictlist(data, -200)
return {
'stake_amount': conf['stake_amount'],
@ -218,7 +218,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
'--strategy', 'default_strategy',
'--datadir', '/foo/bar',
'backtesting',
'--ticker-interval', '1',
'--ticker-interval', '1m',
'--live',
'--realistic-simulation',
'--refresh-pairs-cached',
@ -240,7 +240,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
assert 'ticker_interval' in config
assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
assert log_has(
'Using ticker_interval: 1 ...',
'Using ticker_interval: 1m ...',
caplog.record_tuples
)
@ -313,7 +313,7 @@ def test_backtesting_init(default_conf) -> None:
backtesting = Backtesting(default_conf)
assert backtesting.config == default_conf
assert isinstance(backtesting.analyze, Analyze)
assert backtesting.ticker_interval == 5
assert backtesting.ticker_interval == '5m'
assert callable(backtesting.tickerdata_to_dataframe)
assert callable(backtesting.populate_buy_trend)
assert callable(backtesting.populate_sell_trend)
@ -325,17 +325,17 @@ def test_tickerdata_to_dataframe(default_conf) -> None:
"""
timerange = ((None, 'line'), None, -100)
tick = optimize.load_tickerdata_file(None, 'BTC_UNITEST', 1, timerange=timerange)
tickerlist = {'BTC_UNITEST': tick}
tick = optimize.load_tickerdata_file(None, 'UNITTEST/BTC', '1m', timerange=timerange)
tickerlist = {'UNITTEST/BTC': tick}
backtesting = _BACKTESTING
data = backtesting.tickerdata_to_dataframe(tickerlist)
assert len(data['BTC_UNITEST']) == 100
assert len(data['UNITTEST/BTC']) == 100
# Load Analyze to compare the result between Backtesting function and Analyze are the same
analyze = Analyze(default_conf)
data2 = analyze.tickerdata_to_dataframe(tickerlist)
assert data['BTC_UNITEST'].equals(data2['BTC_UNITEST'])
assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC'])
def test_get_timeframe() -> None:
@ -347,8 +347,8 @@ def test_get_timeframe() -> None:
data = backtesting.tickerdata_to_dataframe(
optimize.load_data(
None,
ticker_interval=1,
pairs=['BTC_UNITEST']
ticker_interval='1m',
pairs=['UNITTEST/BTC']
)
)
min_date, max_date = backtesting.get_timeframe(data)
@ -364,7 +364,7 @@ def test_generate_text_table():
results = pd.DataFrame(
{
'currency': ['BTC_ETH', 'BTC_ETH'],
'currency': ['ETH/BTC', 'ETH/BTC'],
'profit_percent': [0.1, 0.2],
'profit_BTC': [0.2, 0.4],
'duration': [10, 30],
@ -378,13 +378,13 @@ def test_generate_text_table():
'total profit BTC avg duration profit loss\n'
'------- ----------- -------------- '
'------------------ -------------- -------- ------\n'
'BTC_ETH 2 15.00 '
'ETH/BTC 2 15.00 '
'0.60000000 20.0 2 0\n'
'TOTAL 2 15.00 '
'0.60000000 20.0 2 0'
)
assert backtesting._generate_text_table(data={'BTC_ETH': {}}, results=results) == result_str
assert backtesting._generate_text_table(data={'ETH/BTC': {}}, results=results) == result_str
def test_backtesting_start(default_conf, mocker, caplog) -> None:
@ -405,7 +405,7 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None:
)
conf = deepcopy(default_conf)
conf['exchange']['pair_whitelist'] = ['BTC_UNITEST']
conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
conf['ticker_interval'] = 1
conf['live'] = False
conf['datadir'] = None
@ -432,7 +432,7 @@ def test_backtest(default_conf) -> None:
"""
backtesting = _BACKTESTING
data = optimize.load_data(None, ticker_interval=5, pairs=['BTC_ETH'])
data = optimize.load_data(None, ticker_interval='5m', pairs=['UNITTEST/BTC'])
data = trim_dictlist(data, -200)
results = backtesting.backtest(
{
@ -452,7 +452,7 @@ def test_backtest_1min_ticker_interval(default_conf) -> None:
backtesting = _BACKTESTING
# Run a backtesting for an exiting 5min ticker_interval
data = optimize.load_data(None, ticker_interval=1, pairs=['BTC_UNITEST'])
data = optimize.load_data(None, ticker_interval='1m', pairs=['UNITTEST/BTC'])
data = trim_dictlist(data, -200)
results = backtesting.backtest(
{
@ -473,7 +473,7 @@ def test_processed() -> None:
dict_of_tickerrows = load_data_test('raise')
dataframes = backtesting.tickerdata_to_dataframe(dict_of_tickerrows)
dataframe = dataframes['BTC_UNITEST']
dataframe = dataframes['UNITTEST/BTC']
cols = dataframe.columns
# assert the dataframe got some of the indicator columns
for col in ['close', 'high', 'low', 'open', 'date',
@ -522,7 +522,7 @@ def test_backtest_only_sell(default_conf):
def test_backtest_alternate_buy_sell(default_conf):
backtest_conf = _make_backtest_conf(conf=default_conf, pair='BTC_UNITEST')
backtest_conf = _make_backtest_conf(conf=default_conf, pair='UNITTEST/BTC')
results = _run_backtest_1(_trend_alternate, backtest_conf)
assert len(results) == 3
@ -536,7 +536,7 @@ def test_backtest_record(default_conf, mocker):
)
backtest_conf = _make_backtest_conf(
conf=default_conf,
pair='BTC_UNITEST',
pair='UNITTEST/BTC',
record="trades"
)
results = _run_backtest_1(_trend_alternate, backtest_conf)
@ -546,11 +546,11 @@ def test_backtest_record(default_conf, mocker):
records = records[0]
# Ensure records are of correct type
assert len(records) == 3
# ('BTC_UNITEST', 0.00331158, '1510684320', '1510691700', 0, 117)
# ('UNITTEST/BTC', 0.00331158, '1510684320', '1510691700', 0, 117)
# Below follows just a typecheck of the schema/type of trade-records
oix = None
for (pair, profit, date_buy, date_sell, buy_index, dur) in records:
assert pair == 'BTC_UNITEST'
assert pair == 'UNITTEST/BTC'
isinstance(profit, float)
# FIX: buy/sell should be converted to ints
isinstance(date_buy, str)
@ -563,7 +563,7 @@ def test_backtest_record(default_conf, mocker):
def test_backtest_start_live(default_conf, mocker, caplog):
default_conf['exchange']['pair_whitelist'] = ['BTC_UNITEST']
default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
mocker.patch('freqtrade.exchange.get_ticker_history',
new=lambda n, i: _load_pair_as_ticks(n, i))
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
@ -585,7 +585,7 @@ def test_backtest_start_live(default_conf, mocker, caplog):
'--config', 'config.json',
'--strategy', 'default_strategy',
'backtesting',
'--ticker-interval', '1',
'--ticker-interval', '1m',
'--live',
'--timerange', '-100'
]
@ -594,7 +594,7 @@ def test_backtest_start_live(default_conf, mocker, caplog):
# check the logs, that will contain the backtest result
exists = [
'Parameter -i/--ticker-interval detected ...',
'Using ticker_interval: 1 ...',
'Using ticker_interval: 1m ...',
'Parameter -l/--live detected ...',
'Using max_open_trades: 1 ...',
'Parameter --timerange detected: -100 ..',

View File

@ -375,9 +375,9 @@ def test_format_results():
Test Hyperopt.format_results()
"""
trades = [
('BTC_ETH', 2, 2, 123),
('BTC_LTC', 1, 1, 123),
('BTC_XRP', -1, -2, -246)
('ETH/BTC', 2, 2, 123),
('LTC/BTC', 1, 1, 123),
('XPR/BTC', -1, -2, -246)
]
labels = ['currency', 'profit_percent', 'profit_BTC', 'duration']
df = pd.DataFrame.from_records(trades, columns=labels)
@ -416,10 +416,10 @@ def test_populate_indicators() -> None:
"""
Test Hyperopt.populate_indicators()
"""
tick = load_tickerdata_file(None, 'BTC_UNITEST', 1)
tickerlist = {'BTC_UNITEST': tick}
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
tickerlist = {'UNITTEST/BTC': tick}
dataframes = _HYPEROPT.tickerdata_to_dataframe(tickerlist)
dataframe = _HYPEROPT.populate_indicators(dataframes['BTC_UNITEST'])
dataframe = _HYPEROPT.populate_indicators(dataframes['UNITTEST/BTC'])
# Check if some indicators are generated. We will not test all of them
assert 'adx' in dataframe
@ -431,10 +431,10 @@ def test_buy_strategy_generator() -> None:
"""
Test Hyperopt.buy_strategy_generator()
"""
tick = load_tickerdata_file(None, 'BTC_UNITEST', 1)
tickerlist = {'BTC_UNITEST': tick}
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
tickerlist = {'UNITTEST/BTC': tick}
dataframes = _HYPEROPT.tickerdata_to_dataframe(tickerlist)
dataframe = _HYPEROPT.populate_indicators(dataframes['BTC_UNITEST'])
dataframe = _HYPEROPT.populate_indicators(dataframes['UNITTEST/BTC'])
populate_buy_trend = _HYPEROPT.buy_strategy_generator(
{
@ -494,7 +494,7 @@ def test_generate_optimizer(mocker, default_conf) -> None:
conf.update({'spaces': 'all'})
trades = [
('BTC_POWR', 0.023117, 0.000233, 100)
('POWR/BTC', 0.023117, 0.000233, 100)
]
labels = ['currency', 'profit_percent', 'profit_BTC', 'duration']
backtest_result = pd.DataFrame.from_records(trades, columns=labels)

View File

@ -11,7 +11,7 @@ from freqtrade.optimize.__init__ import make_testdata_path, download_pairs, \
download_backtesting_testdata, load_tickerdata_file, trim_tickerlist
from freqtrade.tests.conftest import log_has
# Change this if modifying BTC_UNITEST testdatafile
# Change this if modifying UNITTEST/BTC testdatafile
_BTC_UNITTEST_LENGTH = 13681
@ -52,11 +52,11 @@ def test_load_data_30min_ticker(ticker_history, mocker, caplog) -> None:
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
file = 'freqtrade/tests/testdata/BTC_UNITTEST-30.json'
file = 'freqtrade/tests/testdata/UNITTEST_BTC-30m.json'
_backup_file(file, copy_file=True)
optimize.load_data(None, pairs=['BTC_UNITTEST'], ticker_interval=30)
optimize.load_data(None, pairs=['UNITTEST/BTC'], ticker_interval='30m')
assert os.path.isfile(file) is True
assert not log_has('Download the pair: "BTC_ETH", Interval: 30 min', caplog.record_tuples)
assert not log_has('Download the pair: "ETH/BTC", Interval: 30 min', caplog.record_tuples)
_clean_test_file(file)
@ -66,11 +66,11 @@ def test_load_data_5min_ticker(ticker_history, mocker, caplog) -> None:
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
file = 'freqtrade/tests/testdata/BTC_ETH-5.json'
file = 'freqtrade/tests/testdata/ETH_BTC-5m.json'
_backup_file(file, copy_file=True)
optimize.load_data(None, pairs=['BTC_ETH'], ticker_interval=5)
optimize.load_data(None, pairs=['ETH/BTC'], ticker_interval='5m')
assert os.path.isfile(file) is True
assert not log_has('Download the pair: "BTC_ETH", Interval: 5 min', caplog.record_tuples)
assert not log_has('Download the pair: "ETH/BTC", Interval: 5 min', caplog.record_tuples)
_clean_test_file(file)
@ -80,11 +80,11 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog) -> None:
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
file = 'freqtrade/tests/testdata/BTC_ETH-1.json'
file = 'freqtrade/tests/testdata/ETH_BTC-1m.json'
_backup_file(file, copy_file=True)
optimize.load_data(None, ticker_interval=1, pairs=['BTC_ETH'])
optimize.load_data(None, ticker_interval='1m', pairs=['ETH/BTC'])
assert os.path.isfile(file) is True
assert not log_has('Download the pair: "BTC_ETH", Interval: 1 min', caplog.record_tuples)
assert not log_has('Download the pair: "ETH/BTC", Interval: 1 min', caplog.record_tuples)
_clean_test_file(file)
@ -94,11 +94,11 @@ def test_load_data_with_new_pair_1min(ticker_history, mocker, caplog) -> None:
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
file = 'freqtrade/tests/testdata/BTC_MEME-1.json'
file = 'freqtrade/tests/testdata/MEME_BTC-1m.json'
_backup_file(file)
optimize.load_data(None, ticker_interval=1, pairs=['BTC_MEME'])
optimize.load_data(None, ticker_interval='1m', pairs=['MEME/BTC'])
assert os.path.isfile(file) is True
assert log_has('Download the pair: "BTC_MEME", Interval: 1 min', caplog.record_tuples)
assert log_has('Download the pair: "MEME/BTC", Interval: 1 min', caplog.record_tuples)
_clean_test_file(file)
@ -109,10 +109,10 @@ def test_testdata_path() -> None:
def test_download_pairs(ticker_history, mocker) -> None:
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
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'
file1_1 = 'freqtrade/tests/testdata/MEME_BTC-1m.json'
file1_5 = 'freqtrade/tests/testdata/MEME_BTC-5m.json'
file2_1 = 'freqtrade/tests/testdata/CFI_BTC-1m.json'
file2_5 = 'freqtrade/tests/testdata/CFI_BTC-5m.json'
_backup_file(file1_1)
_backup_file(file1_5)
@ -122,7 +122,7 @@ def test_download_pairs(ticker_history, mocker) -> None:
assert os.path.isfile(file1_1) is False
assert os.path.isfile(file2_1) is False
assert download_pairs(None, pairs=['BTC-MEME', 'BTC-CFI'], ticker_interval=1) is True
assert download_pairs(None, pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='1m') is True
assert os.path.isfile(file1_1) is True
assert os.path.isfile(file2_1) is True
@ -134,7 +134,7 @@ def test_download_pairs(ticker_history, mocker) -> None:
assert os.path.isfile(file1_5) is False
assert os.path.isfile(file2_5) is False
assert download_pairs(None, pairs=['BTC-MEME', 'BTC-CFI'], ticker_interval=5) is True
assert download_pairs(None, pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='5m') is True
assert os.path.isfile(file1_5) is True
assert os.path.isfile(file2_5) is True
@ -149,33 +149,33 @@ def test_download_pairs_exception(ticker_history, mocker, caplog) -> None:
mocker.patch('freqtrade.optimize.__init__.download_backtesting_testdata',
side_effect=BaseException('File Error'))
file1_1 = 'freqtrade/tests/testdata/BTC_MEME-1.json'
file1_5 = 'freqtrade/tests/testdata/BTC_MEME-5.json'
file1_1 = 'freqtrade/tests/testdata/MEME_BTC-1m.json'
file1_5 = 'freqtrade/tests/testdata/MEME_BTC-5m.json'
_backup_file(file1_1)
_backup_file(file1_5)
download_pairs(None, pairs=['BTC-MEME'], ticker_interval=1)
download_pairs(None, pairs=['MEME/BTC'], ticker_interval='1m')
# clean files freshly downloaded
_clean_test_file(file1_1)
_clean_test_file(file1_5)
assert log_has('Failed to download the pair: "BTC-MEME", Interval: 1 min', caplog.record_tuples)
assert log_has('Failed to download the pair: "MEME/BTC", Interval: 1 min', caplog.record_tuples)
def test_download_backtesting_testdata(ticker_history, mocker) -> None:
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
# Download a 1 min ticker file
file1 = 'freqtrade/tests/testdata/BTC_XEL-1.json'
file1 = 'freqtrade/tests/testdata/XEL_BTC-1m.json'
_backup_file(file1)
download_backtesting_testdata(None, pair="BTC-XEL", interval=1)
download_backtesting_testdata(None, pair="XEL/BTC", interval='1m')
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'
file2 = 'freqtrade/tests/testdata/STORJ_BTC-5m.json'
_backup_file(file2)
download_backtesting_testdata(None, pair="BTC-STORJ", interval=5)
download_backtesting_testdata(None, pair="STORJ/BTC", interval='5m')
assert os.path.isfile(file2) is True
_clean_test_file(file2)
@ -184,18 +184,18 @@ def test_download_backtesting_testdata2(mocker) -> None:
tick = [{'T': 'bar'}, {'T': 'foo'}]
mocker.patch('freqtrade.misc.file_dump_json', return_value=None)
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=tick)
assert download_backtesting_testdata(None, pair="BTC-UNITEST", interval=1)
assert download_backtesting_testdata(None, pair="BTC-UNITEST", interval=3)
assert download_backtesting_testdata(None, pair="UNITTEST/BTC", interval='1m')
assert download_backtesting_testdata(None, pair="UNITTEST/BTC", interval='3m')
def test_load_tickerdata_file() -> None:
# 7 does not exist in either format.
assert not load_tickerdata_file(None, 'BTC_UNITEST', 7)
assert not load_tickerdata_file(None, 'UNITTEST/BTC', '7m')
# 1 exists only as a .json
tickerdata = load_tickerdata_file(None, 'BTC_UNITEST', 1)
tickerdata = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
assert _BTC_UNITTEST_LENGTH == len(tickerdata)
# 8 .json is empty and will fail if it's loaded. .json.gz is a copy of 1.json
tickerdata = load_tickerdata_file(None, 'BTC_UNITEST', 8)
tickerdata = load_tickerdata_file(None, 'UNITTEST/BTC', '8m')
assert _BTC_UNITTEST_LENGTH == len(tickerdata)
@ -206,12 +206,12 @@ def test_init(default_conf, mocker) -> None:
'',
pairs=[],
refresh_pairs=True,
ticker_interval=int(default_conf['ticker_interval'])
ticker_interval=default_conf['ticker_interval']
)
def test_trim_tickerlist() -> None:
with open('freqtrade/tests/testdata/BTC_ETH-1.json') as data_file:
with open('freqtrade/tests/testdata/ETH_BTC-1m.json') as data_file:
ticker_list = json.load(data_file)
ticker_list_len = len(ticker_list)

View File

@ -585,7 +585,7 @@ def test_telegram_balance_handle(default_conf, update, mocker) -> None:
"""
Mock Bittrex.get_ticker() response
"""
if symbol == 'USDT_BTC':
if symbol == 'BTC/USDT':
return {
'bid': 10000.00,
'ask': 10000.00,

View File

@ -9,7 +9,7 @@ from freqtrade.strategy.default_strategy import DefaultStrategy, class_name
@pytest.fixture
def result():
with open('freqtrade/tests/testdata/BTC_ETH-1.json') as data_file:
with open('freqtrade/tests/testdata/ETH_BTC-1m.json') as data_file:
return Analyze.parse_ticker_dataframe(json.load(data_file))
@ -31,7 +31,7 @@ def test_default_strategy(result):
assert type(strategy.minimal_roi) is dict
assert type(strategy.stoploss) is float
assert type(strategy.ticker_interval) is int
assert type(strategy.ticker_interval) is str
indicators = strategy.populate_indicators(result)
assert type(indicators) is DataFrame
assert type(strategy.populate_buy_trend(indicators)) is DataFrame

View File

@ -74,7 +74,7 @@ def test_returns_latest_buy_signal(mocker):
return_value=DataFrame([{'buy': 1, 'sell': 0, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('BTC-ETH', 5) == (True, False)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (True, False)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
@ -82,7 +82,7 @@ def test_returns_latest_buy_signal(mocker):
return_value=DataFrame([{'buy': 0, 'sell': 1, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('BTC-ETH', 5) == (False, True)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, True)
def test_returns_latest_sell_signal(mocker):
@ -94,7 +94,7 @@ def test_returns_latest_sell_signal(mocker):
)
)
assert _ANALYZE.get_signal('BTC-ETH', 5) == (False, True)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, True)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
@ -102,13 +102,13 @@ def test_returns_latest_sell_signal(mocker):
return_value=DataFrame([{'sell': 0, 'buy': 1, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('BTC-ETH', 5) == (True, False)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (True, False)
def test_get_signal_empty(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=None)
assert (False, False) == _ANALYZE.get_signal('foo', int(default_conf['ticker_interval']))
assert (False, False) == _ANALYZE.get_signal('foo', default_conf['ticker_interval'])
assert log_has('Empty ticker history for pair foo', caplog.record_tuples)
@ -121,7 +121,7 @@ def test_get_signal_exception_valueerror(default_conf, mocker, caplog):
side_effect=ValueError('xyz')
)
)
assert (False, False) == _ANALYZE.get_signal('foo', int(default_conf['ticker_interval']))
assert (False, False) == _ANALYZE.get_signal('foo', default_conf['ticker_interval'])
assert log_has('Unable to analyze ticker for pair foo: xyz', caplog.record_tuples)
@ -134,7 +134,7 @@ def test_get_signal_empty_dataframe(default_conf, mocker, caplog):
return_value=DataFrame([])
)
)
assert (False, False) == _ANALYZE.get_signal('xyz', int(default_conf['ticker_interval']))
assert (False, False) == _ANALYZE.get_signal('xyz', default_conf['ticker_interval'])
assert log_has('Empty dataframe for pair xyz', caplog.record_tuples)
@ -150,7 +150,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog):
return_value=DataFrame(ticks)
)
)
assert (False, False) == _ANALYZE.get_signal('xyz', int(default_conf['ticker_interval']))
assert (False, False) == _ANALYZE.get_signal('xyz', default_conf['ticker_interval'])
assert log_has(
'Outdated history for pair xyz. Last tick is 11 minutes old',
caplog.record_tuples
@ -166,7 +166,7 @@ def test_get_signal_handles_exceptions(mocker):
)
)
assert _ANALYZE.get_signal('BTC-ETH', 5) == (False, False)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, False)
def test_parse_ticker_dataframe(ticker_history, ticker_history_without_bv):
@ -188,7 +188,7 @@ def test_tickerdata_to_dataframe(default_conf) -> None:
analyze = Analyze(default_conf)
timerange = ((None, 'line'), None, -100)
tick = load_tickerdata_file(None, 'BTC_UNITEST', 1, timerange=timerange)
tickerlist = {'BTC_UNITEST': tick}
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m', timerange=timerange)
tickerlist = {'UNITTEST/BTC': tick}
data = analyze.tickerdata_to_dataframe(tickerlist)
assert len(data['BTC_UNITEST']) == 100
assert len(data['UNITTEST/BTC']) == 100

View File

@ -55,10 +55,10 @@ def test_parse_args_verbose() -> None:
def test_scripts_options() -> None:
arguments = Arguments(['-p', 'BTC_ETH'], '')
arguments = Arguments(['-p', 'ETH/BTC'], '')
arguments.scripts_options()
args = arguments.get_parsed_arg()
assert args.pair == 'BTC_ETH'
assert args.pair == 'ETH/BTC'
def test_parse_args_version() -> None:
@ -106,7 +106,7 @@ def test_parse_args_backtesting_custom() -> None:
'-c', 'test_conf.json',
'backtesting',
'--live',
'--ticker-interval', '1',
'--ticker-interval', '1m',
'--refresh-pairs-cached']
call_args = Arguments(args, '').get_parsed_arg()
assert call_args.config == 'test_conf.json'
@ -114,7 +114,7 @@ def test_parse_args_backtesting_custom() -> None:
assert call_args.loglevel == logging.INFO
assert call_args.subparser == 'backtesting'
assert call_args.func is not None
assert call_args.ticker_interval == 1
assert call_args.ticker_interval == '1m'
assert call_args.refresh_pairs is True

View File

@ -34,7 +34,7 @@ def test_load_config_invalid_pair(default_conf) -> None:
Test the configuration validator with an invalid PAIR format
"""
conf = deepcopy(default_conf)
conf['exchange']['pair_whitelist'].append('BTC-ETH')
conf['exchange']['pair_whitelist'].append('ETH-BTC')
with pytest.raises(ValidationError, match=r'.*does not match.*'):
configuration = Configuration([])
@ -232,7 +232,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
'--strategy', 'default_strategy',
'--datadir', '/foo/bar',
'backtesting',
'--ticker-interval', '1',
'--ticker-interval', '1m',
'--live',
'--realistic-simulation',
'--refresh-pairs-cached',
@ -257,7 +257,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
assert 'ticker_interval' in config
assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
assert log_has(
'Using ticker_interval: 1 ...',
'Using ticker_interval: 1m ...',
caplog.record_tuples
)

View File

@ -6,11 +6,11 @@ from freqtrade.analyze import Analyze
from freqtrade.optimize import load_data
from freqtrade.strategy.strategy import Strategy
_pairs = ['BTC_ETH']
_pairs = ['ETH/BTC']
def load_dataframe_pair(pairs):
ld = load_data(None, ticker_interval=5, pairs=pairs)
ld = load_data(None, ticker_interval='5m', pairs=pairs)
assert isinstance(ld, dict)
assert isinstance(pairs[0], str)
dataframe = ld[pairs[0]]

View File

@ -50,15 +50,15 @@ def test_common_datearray(default_conf, mocker) -> None:
mocker.patch('freqtrade.strategy.strategy.Strategy', MagicMock())
analyze = Analyze(default_conf)
tick = load_tickerdata_file(None, 'BTC_UNITEST', 1)
tickerlist = {'BTC_UNITEST': tick}
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
tickerlist = {'UNITTEST/BTC': tick}
dataframes = analyze.tickerdata_to_dataframe(tickerlist)
dates = common_datearray(dataframes)
assert dates.size == dataframes['BTC_UNITEST']['date'].size
assert dates[0] == dataframes['BTC_UNITEST']['date'][0]
assert dates[-1] == dataframes['BTC_UNITEST']['date'][-1]
assert dates.size == dataframes['UNITTEST/BTC']['date'].size
assert dates[0] == dataframes['UNITTEST/BTC']['date'][0]
assert dates[-1] == dataframes['UNITTEST/BTC']['date'][-1]
def test_file_dump_json(mocker) -> None:

View File

@ -118,7 +118,7 @@ def test_update_with_bittrex(limit_buy_order, limit_sell_order):
"""
trade = Trade(
pair='BTC_ETH',
pair='ETH/BTC',
stake_amount=0.001,
fee=0.0025,
exchange='bittrex',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
[
{"O": 0.00162008, "H": 0.00162008, "L": 0.00162008, "C": 0.00162008, "V": 108.14853839, "T": "2017-11-04T23:02:00", "BV": 0.17520927}
]

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ parser.add_argument(
)
args = parser.parse_args(sys.argv[1:])
TICKER_INTERVALS = [1, 5] # ticker interval in minutes (currently implemented: 1 and 5)
TICKER_INTERVALS = ['1m', '5m']
PAIRS = []
if args.pair:
@ -34,5 +34,6 @@ for pair in PAIRS:
for tick_interval in TICKER_INTERVALS:
print('downloading pair %s, interval %s' % (pair, tick_interval))
data = exchange.get_ticker_history(pair, tick_interval)
filename = '{}-{}.json'.format(pair, tick_interval)
pair_print = pair.replace('/', '_')
filename = '{}-{}.json'.format(pair_print, tick_interval)
misc.file_dump_json(filename, data)

View File

@ -1,26 +1,26 @@
[
"BTC_ADA",
"BTC_BAT",
"BTC_DASH",
"BTC_ETC",
"BTC_ETH",
"BTC_GBYTE",
"BTC_LSK",
"BTC_LTC",
"BTC_NEO",
"BTC_NXT",
"BTC_POWR",
"BTC_STORJ",
"BTC_QTUM",
"BTC_WAVES",
"BTC_VTC",
"BTC_XLM",
"BTC_XMR",
"BTC_XVG",
"BTC_XRP",
"BTC_ZEC",
"USDT_BTC",
"USDT_LTC",
"USDT_ETH"
"ADA/BTC",
"BAT/BTC",
"DASH/BTC",
"ETC/BTC",
"ETH/BTC",
"GBYTE/BTC",
"LSK/BTC",
"LTC/BTC",
"NEO/BTC",
"NXT/BTC",
"POWR/BTC",
"STORJ/BTC",
"QTUM/BTC",
"WAVES/BTC",
"VTC/BTC",
"XLM/BTC",
"XMR/BTC",
"XVG/BTC",
"XRP/BTC",
"ZEC/BTC",
"BTC/USDT",
"LTC/USDT",
"ETH/USDT"
]

View File

@ -24,6 +24,7 @@ from freqtrade.arguments import Arguments
from freqtrade import misc
from freqtrade.logger import Logger
from pandas import DataFrame
from freqtrade.constants import Constants
import dateutil.parser
@ -82,9 +83,10 @@ def convert_dataframe(frame: DataFrame):
cols = ['date', 'open', 'high', 'low', 'close', 'volume']
frame = frame[cols]
# Make sure parsing/printing data is assumed to be UTC
frame['date'] = frame['date'].apply(
lambda d: int(dateutil.parser.parse(d).timestamp()) * 1000)
frame['date'] = frame['date'].astype(int)
lambda d: int(dateutil.parser.parse(d+'+00:00').timestamp()) * 1000)
frame['date'] = frame['date'].astype('int64')
# Convert columns one by one to preserve type.
by_column = [frame[x].values.tolist() for x in frame.columns]
return list(list(x) for x in zip(*by_column))
@ -130,15 +132,32 @@ def convert_main(args: Namespace) -> None:
filename)
continue
ret = re.search(r'\d+(?=\.json)', path.basename(filename))
if not ret:
logger.warning("file %s could not be converted, interval not found", filename)
continue
interval = ret.group(0)
ret_integer = re.search(r'\d+(?=\.json)', path.basename(filename))
ret_string = re.search(r'(\d+[mhdw])(?=\.json)', path.basename(filename))
if ret_integer:
minutes = int(ret_integer.group(0))
interval = str(minutes) + 'm' # default to adding 'm' to end of minutes for new interval name
# but check if there is a mapping between int and string also
for str_interval, minutes_interval in Constants.TICKER_INTERVAL_MINUTES.items():
if minutes_interval == minutes:
interval = str_interval
break
# change order on pairs if old ticker interval found
filename_new = path.join(path.dirname(filename),
"{}_{}-{}.json".format(currencies[1],
currencies[0], interval))
elif ret_string:
interval = ret_string.group(0)
filename_new = path.join(path.dirname(filename),
"{}_{}-{}.json".format(currencies[0],
currencies[1], interval))
else:
logger.warning("file %s could not be converted, interval not found", filename)
continue
logger.debug("Converting and renaming %s to %s", filename, filename_new)
convert_file(filename, filename_new)

View File

@ -25,6 +25,7 @@ from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration
from freqtrade.analyze import Analyze
from freqtrade.logger import Logger
from freqtrade.constants import Constants
import freqtrade.optimize as optimize
import freqtrade.misc as misc
@ -34,7 +35,7 @@ logger = Logger(name="Graph profits").get_logger()
# data:: [ pair, profit-%, enter, exit, time, duration]
# data:: ["BTC_ETH", 0.0023975, "1515598200", "1515602100", "2018-01-10 07:30:00+00:00", 65]
# data:: ["ETH/BTC", 0.0023975, "1515598200", "1515602100", "2018-01-10 07:30:00+00:00", 65]
def make_profit_array(
data: List, px: int, min_date: int,
interval: int, filter_pairs: Optional[List] = None) -> np.ndarray:
@ -187,11 +188,12 @@ def plot_profit(args: Namespace) -> None:
plot(fig, filename='freqtrade-profit-plot.html')
def define_index(min_date: int, max_date: int, interval: int) -> int:
def define_index(min_date: int, max_date: int, interval: str) -> int:
"""
Return the index of a specific date
"""
return int((max_date - min_date) / (interval * 60))
interval_minutes = Constants.TICKER_INTERVAL_MINUTES[interval]
return int((max_date - min_date) / (interval_minutes * 60))
def plot_parse_args(args: List[str]) -> Namespace:

View File

@ -26,16 +26,16 @@ def hyperopt_optimize_conf() -> dict:
},
"exchange": {
"pair_whitelist": [
"BTC_ETH",
"BTC_LTC",
"BTC_ETC",
"BTC_DASH",
"BTC_ZEC",
"BTC_XLM",
"BTC_NXT",
"BTC_POWR",
"BTC_ADA",
"BTC_XMR"
"ETH/BTC",
"LTC/BTC",
"ETC/BTC",
"DASH/BTC",
"ZEC/BTC",
"XLM/BTC",
"NXT/BTC",
"POWR/BTC",
"ADA/BTC",
"XMR/BTC"
]
}
}