def backtest(backtest_conf, backdata, mocker):
    trades = []
    exchange._API = Bittrex({'key': '', 'secret': ''})
    mocked_history = mocker.patch('freqtrade.analyze.get_ticker_history')
    mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
    mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00'))
    for pair, pair_data in backdata.items():
        mocked_history.return_value = pair_data
        ticker = analyze_ticker(pair)[['close', 'date', 'buy']].copy()
        # for each buy point
        for row in ticker[ticker.buy == 1].itertuples(index=True):
            trade = Trade(open_rate=row.close,
                          open_date=row.date,
                          amount=1,
                          fee=exchange.get_fee() * 2)
            # calculate win/lose forwards from buy point
            for row2 in ticker[row.Index:].itertuples(index=True):
                if should_sell(trade, row2.close, row2.date):
                    current_profit = trade.calc_profit(row2.close)

                    trades.append(
                        (pair, current_profit, row2.Index - row.Index))
                    break
    labels = ['currency', 'profit', 'duration']
    results = DataFrame.from_records(trades, columns=labels)
    return results
Beispiel #2
0
    def _get_sell_trade_entry(
            self, pair: str, buy_row: DataFrame,
            partial_ticker: List, trade_count_lock: Dict, args: Dict) -> Optional[Tuple]:

        stake_amount = args['stake_amount']
        max_open_trades = args.get('max_open_trades', 0)
        trade = Trade(
            open_rate=buy_row.close + self.slippage,             #implement slippage 0.01 for buy_row
            open_date=buy_row.date,
            stake_amount=stake_amount,
            amount=stake_amount / buy_row.open,
            fee=exchange.get_fee()
        )

        # calculate win/lose forwards from buy point
        for sell_row in partial_ticker:
            if max_open_trades > 0:
                # Increase trade_count_lock for every iteration
                trade_count_lock[sell_row.date] = trade_count_lock.get(sell_row.date, 0) + 1

            buy_signal = sell_row.buy
            #implement slippage 0.01 for sell_row

            if self.analyze.should_sell(trade, sell_row.close - self.slippage, sell_row.date, buy_signal,
                                        sell_row.sell):
                return \
                    sell_row, \
                    (
                        pair,
                        trade.calc_profit_percent(rate=sell_row.close),
                        trade.calc_profit(rate=sell_row.close),
                        (sell_row.date - buy_row.date).seconds // 60
                    ), \
                    sell_row.date
        return None
Beispiel #3
0
def backtest(backtest_conf, processed, mocker):
    trades = []
    exchange._API = Bittrex({'key': '', 'secret': ''})
    mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
    for pair, pair_data in processed.items():
        pair_data['buy'] = 0
        pair_data['sell'] = 0
        ticker = populate_sell_trend(populate_buy_trend(pair_data))
        # for each buy point
        for row in ticker[ticker.buy == 1].itertuples(index=True):
            trade = Trade(open_rate=row.close,
                          open_date=row.date,
                          amount=backtest_conf['stake_amount'],
                          fee=exchange.get_fee() * 2)
            # calculate win/lose forwards from buy point
            for row2 in ticker[row.Index:].itertuples(index=True):
                if min_roi_reached(trade, row2.close,
                                   row2.date) or row2.sell == 1:
                    current_profit = trade.calc_profit(row2.close)

                    trades.append(
                        (pair, current_profit, row2.Index - row.Index))
                    break
    labels = ['currency', 'profit', 'duration']
    return DataFrame.from_records(trades, columns=labels)
Beispiel #4
0
def create_trade(stake_amount: float) -> Optional[Trade]:
    """
    Checks the implemented trading indicator(s) for a randomly picked pair,
    if one pair triggers the buy_signal a new trade record gets created
    :param stake_amount: amount of btc to spend
    """
    logger.info(
        'Checking buy signals to create a new trade with stake_amount: %f ...',
        stake_amount)
    whitelist = copy.deepcopy(_CONF['exchange']['pair_whitelist'])
    # Check if stake_amount is fulfilled
    if exchange.get_balance(_CONF['stake_currency']) < stake_amount:
        raise ValueError('stake amount is not fulfilled (currency={})'.format(
            _CONF['stake_currency']))

    # Remove currently opened and latest pairs from whitelist
    for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
        if trade.pair in whitelist:
            whitelist.remove(trade.pair)
            logger.debug('Ignoring %s in pair whitelist', trade.pair)
    if not whitelist:
        raise ValueError('No pair in whitelist')

    # Pick pair based on StochRSI buy signals
    for _pair in whitelist:
        if get_buy_signal(_pair):
            pair = _pair
            break
    else:
        return None

    # Calculate amount and subtract fee
    fee = exchange.get_fee()
    buy_limit = get_target_bid(exchange.get_ticker(pair))
    amount = (1 - fee) * stake_amount / buy_limit

    order_id = exchange.buy(pair, buy_limit, amount)
    # Create trade entity and return
    message = '*{}:* Buying [{}]({}) with limit `{:.8f}`'.format(
        exchange.get_name().upper(), pair.replace('_', '/'),
        exchange.get_pair_detail_url(pair), buy_limit)
    logger.info(message)
    telegram.send_msg(message)
    # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
    return Trade(pair=pair,
                 stake_amount=stake_amount,
                 amount=amount,
                 fee=fee * 2,
                 open_rate=buy_limit,
                 open_date=datetime.utcnow(),
                 exchange=exchange.get_name().upper(),
                 open_order_id=order_id)
Beispiel #5
0
def test_exchange_misc(mocker):
    api_mock = MagicMock()
    mocker.patch('freqtrade.exchange._API', api_mock)
    exchange.get_markets()
    assert api_mock.get_markets.call_count == 1
    exchange.get_market_summaries()
    assert api_mock.get_market_summaries.call_count == 1
    api_mock.name = 123
    assert exchange.get_name() == 123
    api_mock.fee = 456
    assert exchange.get_fee() == 456
    exchange.get_wallet_health()
    assert api_mock.get_wallet_health.call_count == 1
Beispiel #6
0
    def create_trade(self) -> bool:
        """
        Checks the implemented trading indicator(s) for a randomly picked pair,
        if one pair triggers the buy_signal a new trade record gets created
        :param stake_amount: amount of btc to spend
        :param interval: Ticker interval used for Analyze
        :return: True if a trade object has been created and persisted, False otherwise
        """
        stake_amount = self.config['stake_amount']
        interval = self.analyze.get_ticker_interval()

        logger.info(
            'Checking buy signals to create a new trade with stake_amount: %f ...',
            stake_amount)
        whitelist = copy.deepcopy(self.config['exchange']['pair_whitelist'])
        # Check if stake_amount is fulfilled
        if exchange.get_balance(self.config['stake_currency']) < stake_amount:
            raise DependencyException(
                'stake amount is not fulfilled (currency={})'.format(
                    self.config['stake_currency']))

        # Remove currently opened and latest pairs from whitelist
        for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
            if trade.pair in whitelist:
                whitelist.remove(trade.pair)
                logger.debug('Ignoring %s in pair whitelist', trade.pair)

        if not whitelist:
            raise DependencyException('No currency pairs in whitelist')

        # Pick pair based on StochRSI buy signals
        for _pair in whitelist:
            (buy, sell) = self.analyze.get_signal(_pair, interval)
            if buy and not sell:
                pair = _pair
                break
        else:
            return False

        # Calculate amount
        buy_limit = self.get_target_bid(exchange.get_ticker(pair))
        amount = stake_amount / buy_limit

        order_id = exchange.buy(pair, buy_limit, amount)

        stake_amount_fiat = self.fiat_converter.convert_amount(
            stake_amount, self.config['stake_currency'],
            self.config['fiat_display_currency'])

        # Create trade entity and return
        self.rpc.send_msg(
            '*{}:* Buying [{}]({}) with limit `{:.8f} ({:.6f} {}, {:.3f} {})` '
            .format(exchange.get_name().upper(), pair.replace('_', '/'),
                    exchange.get_pair_detail_url(pair), buy_limit,
                    stake_amount, self.config['stake_currency'],
                    stake_amount_fiat, self.config['fiat_display_currency']))
        # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
        trade = Trade(pair=pair,
                      stake_amount=stake_amount,
                      amount=amount,
                      fee=exchange.get_fee(),
                      open_rate=buy_limit,
                      open_date=datetime.utcnow(),
                      exchange=exchange.get_name().upper(),
                      open_order_id=order_id)
        Trade.session.add(trade)
        Trade.session.flush()
        return True
Beispiel #7
0
def backtest(stake_amount: float, processed: Dict[str, DataFrame],
             max_open_trades: int = 0, realistic: bool = True, sell_profit_only: bool = False,
             stoploss: int = -1.00, use_sell_signal: bool = False) -> DataFrame:
    """
    Implements backtesting functionality
    :param stake_amount: btc amount to use for each trade
    :param processed: a processed dictionary with format {pair, data}
    :param max_open_trades: maximum number of concurrent trades (default: 0, disabled)
    :param realistic: do we try to simulate realistic trades? (default: True)
    :return: DataFrame
    """
    trades = []
    trade_count_lock: dict = {}
    exchange._API = Bittrex({'key': '', 'secret': ''})
    for pair, pair_data in processed.items():
        pair_data['buy'], pair_data['sell'] = 0, 0
        ticker = populate_sell_trend(populate_buy_trend(pair_data))
        # for each buy point
        lock_pair_until = None
        buy_subset = ticker[ticker.buy == 1][['buy', 'open', 'close', 'date', 'sell']]
        for row in buy_subset.itertuples(index=True):
            if realistic:
                if lock_pair_until is not None and row.Index <= lock_pair_until:
                    continue
            if max_open_trades > 0:
                # Check if max_open_trades has already been reached for the given date
                if not trade_count_lock.get(row.date, 0) < max_open_trades:
                    continue

            if max_open_trades > 0:
                # Increase lock
                trade_count_lock[row.date] = trade_count_lock.get(row.date, 0) + 1

            trade = Trade(
                open_rate=row.close,
                open_date=row.date,
                stake_amount=stake_amount,
                amount=stake_amount / row.open,
                fee=exchange.get_fee()
            )

            # calculate win/lose forwards from buy point
            sell_subset = ticker[row.Index + 1:][['close', 'date', 'sell']]
            for row2 in sell_subset.itertuples(index=True):
                if max_open_trades > 0:
                    # Increase trade_count_lock for every iteration
                    trade_count_lock[row2.date] = trade_count_lock.get(row2.date, 0) + 1

                current_profit_percent = trade.calc_profit_percent(rate=row2.close)
                if (sell_profit_only and current_profit_percent < 0):
                    continue
                if min_roi_reached(trade, row2.close, row2.date) or \
                    (row2.sell == 1 and use_sell_signal) or \
                        current_profit_percent <= stoploss:
                    current_profit_btc = trade.calc_profit(rate=row2.close)
                    lock_pair_until = row2.Index

                    trades.append(
                        (
                            pair,
                            current_profit_percent,
                            current_profit_btc,
                            row2.Index - row.Index,
                            current_profit_btc > 0,
                            current_profit_btc < 0
                        )
                    )
                    break
    labels = ['currency', 'profit_percent', 'profit_BTC', 'duration', 'profit', 'loss']
    return DataFrame.from_records(trades, columns=labels)
Beispiel #8
0
def test_get_fee(default_conf, mocker):
    mocker.patch('freqtrade.exchange.validate_pairs',
                 side_effect=lambda s: True)
    init(default_conf)

    assert get_fee() == 0.0025
Beispiel #9
0
def backtest(stake_amount: float,
             processed: Dict[str, DataFrame],
             max_open_trades: int = 0,
             realistic: bool = True,
             sell_profit_only: bool = False,
             stoploss: int = -1.00,
             use_sell_signal: bool = False) -> DataFrame:
    """
    Implements backtesting functionality
    :param stake_amount: btc amount to use for each trade
    :param processed: a processed dictionary with format {pair, data}
    :param max_open_trades: maximum number of concurrent trades (default: 0, disabled)
    :param realistic: do we try to simulate realistic trades? (default: True)
    :return: DataFrame
    """
    trades = []
    trade_count_lock: dict = {}
    exchange._API = Bittrex({'key': '', 'secret': ''})
    for pair, pair_data in processed.items():
        pair_data['buy'], pair_data['sell'] = 0, 0
        ticker = populate_sell_trend(populate_buy_trend(pair_data))
        # for each buy point
        lock_pair_until = None
        buy_subset = ticker[ticker.buy == 1][[
            'buy', 'open', 'close', 'date', 'sell'
        ]]
        for row in buy_subset.itertuples(index=True):
            if realistic:
                if lock_pair_until is not None and row.Index <= lock_pair_until:
                    continue
            if max_open_trades > 0:
                # Check if max_open_trades has already been reached for the given date
                if not trade_count_lock.get(row.date, 0) < max_open_trades:
                    continue

            if max_open_trades > 0:
                # Increase lock
                trade_count_lock[row.date] = trade_count_lock.get(row.date,
                                                                  0) + 1

            trade = Trade(open_rate=row.close,
                          open_date=row.date,
                          stake_amount=stake_amount,
                          amount=stake_amount / row.open,
                          fee=exchange.get_fee())

            # calculate win/lose forwards from buy point
            sell_subset = ticker[row.Index + 1:][['close', 'date', 'sell']]
            for row2 in sell_subset.itertuples(index=True):
                if max_open_trades > 0:
                    # Increase trade_count_lock for every iteration
                    trade_count_lock[row2.date] = trade_count_lock.get(
                        row2.date, 0) + 1

                current_profit_percent = trade.calc_profit_percent(
                    rate=row2.close)
                if (sell_profit_only and current_profit_percent < 0):
                    continue
                if min_roi_reached(trade, row2.close, row2.date) or \
                    (row2.sell == 1 and use_sell_signal) or \
                        current_profit_percent <= stoploss:
                    current_profit_btc = trade.calc_profit(rate=row2.close)
                    lock_pair_until = row2.Index

                    trades.append(
                        (pair, current_profit_percent, current_profit_btc,
                         row2.Index - row.Index, current_profit_btc > 0,
                         current_profit_btc < 0))
                    break
    labels = [
        'currency', 'profit_percent', 'profit_BTC', 'duration', 'profit',
        'loss'
    ]
    return DataFrame.from_records(trades, columns=labels)
Beispiel #10
0
def create_trade(stake_amount: float) -> bool:
    """
    Checks the implemented trading indicator(s) for a randomly picked pair,
    if one pair triggers the buy_signal a new trade record gets created
    :param stake_amount: amount of btc to spend
    :return: True if a trade object has been created and persisted, False otherwise
    """
    logger.info(
        'Checking buy signals to create a new trade with stake_amount: %f ...',
        stake_amount
    )
    whitelist = copy.deepcopy(_CONF['exchange']['pair_whitelist'])
    # Check if stake_amount is fulfilled
    if exchange.get_balance(_CONF['stake_currency']) < stake_amount:
        raise DependencyException(
            'stake amount is not fulfilled (currency={})'.format(_CONF['stake_currency'])
        )

    # Remove currently opened and latest pairs from whitelist
    for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
        if trade.pair in whitelist:
            whitelist.remove(trade.pair)
            logger.debug('Ignoring %s in pair whitelist', trade.pair)
    if not whitelist:
        raise DependencyException('No pair in whitelist')

    # Pick pair based on StochRSI buy signals
    for _pair in whitelist:
        if get_signal(_pair, SignalType.BUY):
            pair = _pair
            break
    else:
        return False

    # Calculate amount
    buy_limit = get_target_bid(exchange.get_ticker(pair))
    amount = stake_amount / buy_limit

    order_id = exchange.buy(pair, buy_limit, amount)

    fiat_converter = CryptoToFiatConverter()
    stake_amount_fiat = fiat_converter.convert_amount(
        stake_amount,
        _CONF['stake_currency'],
        _CONF['fiat_display_currency']
    )

    # Create trade entity and return
    rpc.send_msg('*{}:* Buying [{}]({}) with limit `{:.8f} ({:.6f} {}, {:.3f} {})` '.format(
        exchange.get_name().upper(),
        pair.replace('_', '/'),
        exchange.get_pair_detail_url(pair),
        buy_limit, stake_amount, _CONF['stake_currency'],
        stake_amount_fiat, _CONF['fiat_display_currency']
    ))
    # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
    trade = Trade(
        pair=pair,
        stake_amount=stake_amount,
        amount=amount,
        fee=exchange.get_fee(),
        open_rate=buy_limit,
        open_date=datetime.utcnow(),
        exchange=exchange.get_name().upper(),
        open_order_id=order_id
    )
    Trade.session.add(trade)
    Trade.session.flush()
    return True
Beispiel #11
0
def test_get_fee(default_conf, mocker):
    mocker.patch('freqtrade.exchange.validate_pairs',
                 side_effect=lambda s: True)
    init(default_conf)

    assert get_fee() == 0.0025
Beispiel #12
0
def create_trade(stake_amount: float) -> Optional[Trade]:
    """
    Checks the implemented trading indicator(s) for a randomly picked pair,
    if one pair triggers the buy_signal a new trade record gets created
    :param stake_amount: amount of btc to spend
    """
    logger.info('Creating new trade with stake_amount: %f ...', stake_amount)
    whitelist = copy.deepcopy(_CONF['exchange']['pair_whitelist'])
    # Check if stake_amount is fulfilled
    if exchange.get_balance(_CONF['stake_currency']) < stake_amount:
        raise ValueError('stake amount is not fulfilled (currency={})'.format(
            _CONF['stake_currency']))

    # Remove currently opened and latest pairs from whitelist
    for trade in Trade.query.filter(Trade.is_open.is_(True)).all():
        if trade.pair in whitelist:
            whitelist.remove(trade.pair)
            logger.debug('Ignoring %s in pair whitelist', trade.pair)
    # if not whitelist:
    #     raise ValueError('No pair in whitelist')

    # Pick pair based on StochRSI buy signals
    if analyzer.name == 'danml':
        for _pair in whitelist:
            if get_buy_signal(_pair, exchange.get_name(), analyzer):
                pair = _pair
                break
        else:
            return None
    elif analyzer.name == 'cryptoml':
        update = False
        if datetime.utcnow().minute % 5 == 0:
            update = True
        pair = analyzer.get_buy_signal(whitelist,
                                       update=update,
                                       threshold=0.01,
                                       repeats=3)
        if pair is None:
            return None

    # Calculate amount and subtract fee
    fee = exchange.get_fee()
    buy_limit = get_target_bid(exchange.get_ticker(pair))
    amount = (1 - fee) * stake_amount / buy_limit

    health = exchange.get_wallet_health()
    if exchange.get_name() == 'HitBTC':
        token = pair
    else:
        token = get_quote_token(pair)
    token_healthy = False
    for status in health:
        if status['Currency'] == token:
            token_healthy = status['IsActive']
    if token_healthy:
        order_id = exchange.buy(pair, buy_limit, amount)
        # Create trade entity and return
        message = '*{}:* Buying [{}]({}) with limit `{:.8f}`'.format(
            exchange.get_name().upper(), pair.replace('_', '/'),
            exchange.get_pair_detail_url(pair), buy_limit)
        logger.info(message)
        telegram.send_msg(message)
        # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
        return Trade(
            pair=pair,
            stake_amount=stake_amount,
            amount=amount,
            fee=fee * 2.,
            open_rate=buy_limit,
            open_date=datetime.utcnow(),
            exchange=exchange.get_name().upper(),
            open_order_id=order_id,
            # open_order_type='buy'
        )
Beispiel #13
0

# ensure directory exists
base_path = os.path.join(os.path.expanduser('~'), 'freqtrade')

# get configuration
with open(os.path.join(base_path, 'config.json')) as file:
	_CONF = json.load(file)

# initialize the exchange
exchange.init(_CONF)

# get ticker
data = exchange.get_ticker(pair='ETH_BTC')
print(data)


# get ticker history
df = exchange.get_ticker_history(pair='ETH_BTC', tick_interval=1)
print(pd.DataFrame(df))

# get markets
data = exchange.get_markets()
print(data)

# get name
print(exchange.get_name())

print(exchange.get_sleep_time())
print(exchange.get_fee())