Fix the fee calculation, backtesting, and hyperopt fee calculation and avg_profit

This commit is contained in:
Gerald Lonlas
2017-12-18 21:58:02 -08:00
14 changed files with 94 additions and 59 deletions

View File

@@ -13,7 +13,8 @@ from freqtrade.analyze import populate_indicators, parse_ticker_dataframe
logger = logging.getLogger(__name__)
def load_data(pairs: List[str], ticker_interval: int = 5, refresh_pairs: Optional[bool] = False) -> Dict[str, List]:
def load_data(pairs: List[str], ticker_interval: int = 5,
refresh_pairs: Optional[bool] = False) -> Dict[str, List]:
"""
Loads ticker history data for the given parameters
:param ticker_interval: ticker interval in minutes
@@ -61,10 +62,10 @@ def download_pairs(pairs: List[str]) -> bool:
"""For each pairs passed in parameters, download 1 and 5 ticker intervals"""
for pair in pairs:
try:
for interval in [1,5]:
for interval in [1, 5]:
download_backtesting_testdata(pair=pair, interval=interval)
except BaseException:
logger.info('Impossible to download the pair: "{pair}", Interval: {interval} min'.format(
logger.info('Failed to download the pair: "{pair}", Interval: {interval} min'.format(
pair=pair,
interval=interval,
))
@@ -103,7 +104,7 @@ def download_backtesting_testdata(pair: str, interval: int = 5) -> bool:
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=int(interval))
for row in new_data:
if row not in data:
data.append(row)

View File

@@ -48,8 +48,8 @@ def generate_text_table(
tabular_data.append([
pair,
len(result.index),
'{:.2f}%'.format(result.profit.mean() * 100.0),
'{:.08f} {}'.format(result.profit.sum(), stake_currency),
'{:.2f}%'.format(result.profit_percent.mean() * 100.0),
'{:.08f} {}'.format(result.profit_BTC.sum(), stake_currency),
'{:.2f}'.format(result.duration.mean() * ticker_interval),
])
@@ -57,8 +57,8 @@ def generate_text_table(
tabular_data.append([
'TOTAL',
len(results.index),
'{:.2f}%'.format(results.profit.mean() * 100.0),
'{:.08f} {}'.format(results.profit.sum(), stake_currency),
'{:.2f}%'.format(results.profit_percent.mean() * 100.0),
'{:.08f} {}'.format(results.profit_BTC.sum(), stake_currency),
'{:.2f}'.format(results.duration.mean() * ticker_interval),
])
return tabulate(tabular_data, headers=headers)
@@ -98,7 +98,8 @@ def backtest(config: Dict, processed: Dict[str, DataFrame],
trade = Trade(
open_rate=row.close,
open_date=row.date,
amount=config['stake_amount'],
stake_amount=config['stake_amount'],
amount=config['stake_amount'] / row.open,
fee=exchange.get_fee()
)
@@ -109,12 +110,20 @@ def backtest(config: Dict, processed: Dict[str, DataFrame],
trade_count_lock[row2.date] = trade_count_lock.get(row2.date, 0) + 1
if min_roi_reached(trade, row2.close, row2.date) or row2.sell == 1:
current_profit = trade.calc_profit_percent(row2.close)
current_profit_percent = trade.calc_profit_percent(rate=row2.close)
current_profit_BTC = trade.calc_profit(rate=row2.close)
lock_pair_until = row2.Index
trades.append((pair, current_profit, row2.Index - row.Index))
trades.append(
(
pair,
current_profit_percent,
current_profit_BTC,
row2.Index - row.Index
)
)
break
labels = ['currency', 'profit', 'duration']
labels = ['currency', 'profit_percent', 'profit_BTC', 'duration']
return DataFrame.from_records(trades, columns=labels)
@@ -140,7 +149,8 @@ def start(args):
data[pair] = exchange.get_ticker_history(pair, args.ticker_interval)
else:
logger.info('Using local backtesting data (using whitelist in given config) ...')
data = load_data(pairs=pairs, ticker_interval=args.ticker_interval, refresh_pairs=args.refresh_pairs)
data = load_data(pairs=pairs, ticker_interval=args.ticker_interval,
refresh_pairs=args.refresh_pairs)
logger.info('Using stake_currency: %s ...', config['stake_currency'])
logger.info('Using stake_amount: %s ...', config['stake_amount'])

View File

@@ -131,7 +131,7 @@ def optimizer(params):
result = format_results(results)
total_profit = results.profit.sum() * 1000
total_profit = results.profit_percent.sum() * 1000
trade_count = len(results.index)
trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2)
@@ -144,13 +144,13 @@ def optimizer(params):
'total_profit': total_profit,
'trade_loss': trade_loss,
'profit_loss': profit_loss,
'avg_profit': results.profit.mean() * 100.0,
'avg_profit': results.profit_percent.mean() * 100.0,
'avg_duration': results.duration.mean() * 5,
'current_tries': _CURRENT_TRIES,
'total_tries': TOTAL_TRIES,
'result': result,
'results': results
}
}
# logger.info('{:5d}/{}: {}'.format(_CURRENT_TRIES, TOTAL_TRIES, result))
log_results(result_data)
@@ -166,10 +166,10 @@ def format_results(results: DataFrame):
return ('Made {:6d} buys. Average profit {: 5.2f}%. '
'Total profit was {: 7.3f}. Average duration {:5.1f} mins.').format(
len(results.index),
results.profit.mean() * 100.0,
results.profit.sum(),
results.profit_percent.mean() * 100.0,
results.profit_BTC.sum(),
results.duration.mean() * 5,
)
)
def buy_strategy_generator(params):
@@ -232,7 +232,8 @@ def start(args):
logger.info('Using config: %s ...', args.config)
config = load_config(args.config)
pairs = config['exchange']['pair_whitelist']
PROCESSED = optimize.preprocess(optimize.load_data(pairs=pairs, ticker_interval=args.ticker_interval))
PROCESSED = optimize.preprocess(optimize.load_data(
pairs=pairs, ticker_interval=args.ticker_interval))
if args.mongodb:
logger.info('Using mongodb ...')