loop over arrays instead of dataframes

This commit is contained in:
Janne Sinivirta 2018-02-11 12:48:06 +02:00
parent 12a19e400f
commit c62356438a

View File

@ -67,30 +67,29 @@ def generate_text_table(
return tabulate(tabular_data, headers=headers, floatfmt=floatfmt) return tabulate(tabular_data, headers=headers, floatfmt=floatfmt)
def get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args): def get_sell_trade_entry(pair, row, partial_ticker, trade_count_lock, args):
stake_amount = args['stake_amount'] stake_amount = args['stake_amount']
max_open_trades = args.get('max_open_trades', 0) max_open_trades = args.get('max_open_trades', 0)
trade = Trade(open_rate=row.close, trade = Trade(open_rate=row.close,
open_date=row.Index, open_date=row.date,
stake_amount=stake_amount, stake_amount=stake_amount,
amount=stake_amount / row.open, amount=stake_amount / row.open,
fee=exchange.get_fee() fee=exchange.get_fee()
) )
# calculate win/lose forwards from buy point # calculate win/lose forwards from buy point
sell_subset = ticker[ticker.index > row.Index][['close', 'sell', 'buy']] for row2 in partial_ticker:
for row2 in sell_subset.itertuples(index=True):
if max_open_trades > 0: if max_open_trades > 0:
# Increase trade_count_lock for every iteration # Increase trade_count_lock for every iteration
trade_count_lock[row2.Index] = trade_count_lock.get(row2.Index, 0) + 1 trade_count_lock[row2.date] = trade_count_lock.get(row2.date, 0) + 1
buy_signal = row2.buy buy_signal = row2.buy
if(should_sell(trade, row2.close, row2.Index, buy_signal, row2.sell)): if should_sell(trade, row2.close, row2.date, buy_signal, row2.sell):
return row2, (pair, return row2, (pair,
trade.calc_profit_percent(rate=row2.close), trade.calc_profit_percent(rate=row2.close),
trade.calc_profit(rate=row2.close), trade.calc_profit(rate=row2.close),
(row2.Index - row.Index).seconds // 60 (row2.date - row.date).seconds // 60
), row2.Index ), row2.date
return None return None
@ -107,6 +106,7 @@ def backtest(args) -> DataFrame:
stoploss: use stoploss stoploss: use stoploss
:return: DataFrame :return: DataFrame
""" """
headers = ['date', 'buy', 'open', 'close', 'sell']
processed = args['processed'] processed = args['processed']
max_open_trades = args.get('max_open_trades', 0) max_open_trades = args.get('max_open_trades', 0)
realistic = args.get('realistic', True) realistic = args.get('realistic', True)
@ -116,29 +116,29 @@ def backtest(args) -> DataFrame:
trade_count_lock: dict = {} trade_count_lock: dict = {}
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
for pair, pair_data in processed.items(): for pair, pair_data in processed.items():
pair_data['buy'], pair_data['sell'] = 0, 0 pair_data['buy'], pair_data['sell'] = 0, 0 # cleanup from previous run
ticker = populate_sell_trend(populate_buy_trend(pair_data))
if 'date' in ticker: ticker_data = populate_sell_trend(populate_buy_trend(pair_data))[headers]
ticker.set_index('date', inplace=True) ticker = [x for x in ticker_data.itertuples()]
# for each buy point
lock_pair_until = None lock_pair_until = None
headers = ['buy', 'open', 'close', 'sell'] for index, row in enumerate(ticker):
buy_subset = ticker[(ticker.buy == 1) & (ticker.sell == 0)][headers] if row.buy == 0 or row.sell == 1:
for row in buy_subset.itertuples(index=True): continue # skip rows where no buy signal or that would immediately sell off
if realistic: if realistic:
if lock_pair_until is not None and row.Index <= lock_pair_until: if lock_pair_until is not None and row.date <= lock_pair_until:
continue continue
if max_open_trades > 0: if max_open_trades > 0:
# Check if max_open_trades has already been reached for the given date # Check if max_open_trades has already been reached for the given date
if not trade_count_lock.get(row.Index, 0) < max_open_trades: if not trade_count_lock.get(row.date, 0) < max_open_trades:
continue continue
if max_open_trades > 0: if max_open_trades > 0:
# Increase lock # Increase lock
trade_count_lock[row.Index] = trade_count_lock.get(row.Index, 0) + 1 trade_count_lock[row.date] = trade_count_lock.get(row.date, 0) + 1
ret = get_sell_trade_entry(pair, row, buy_subset, ticker, ret = get_sell_trade_entry(pair, row, ticker[index+1:], trade_count_lock, args)
trade_count_lock, args)
if ret: if ret:
row2, trade_entry, next_date = ret row2, trade_entry, next_date = ret
lock_pair_until = next_date lock_pair_until = next_date
@ -148,9 +148,9 @@ def backtest(args) -> DataFrame:
# record a tuple of pair, current_profit_percent, # record a tuple of pair, current_profit_percent,
# entry-date, duration # entry-date, duration
records.append((pair, trade_entry[1], records.append((pair, trade_entry[1],
row.Index.strftime('%s'), row.date.strftime('%s'),
row2.Index.strftime('%s'), row2.date.strftime('%s'),
row.Index, trade_entry[3])) row.date, trade_entry[3]))
# For now export inside backtest(), maybe change so that backtest() # For now export inside backtest(), maybe change so that backtest()
# returns a tuple like: (dataframe, records, logs, etc) # returns a tuple like: (dataframe, records, logs, etc)
if record and record.find('trades') >= 0: if record and record.find('trades') >= 0: