def test_get_balance_prod(default_conf, mocker): api_mock = MagicMock() api_mock.get_balance = MagicMock(return_value=123.4) mocker.patch('freqtrade.exchange._API', api_mock) default_conf['dry_run'] = False mocker.patch.dict('freqtrade.exchange._CONF', default_conf) assert get_balance(currency='BTC') == 123.4
def test_get_balance_prod(default_conf, mocker): api_mock = MagicMock() api_mock.get_balance = MagicMock(return_value=123.4) mocker.patch('freqtrade.exchange._API', api_mock) default_conf['dry_run'] = False mocker.patch.dict('freqtrade.exchange._CONF', default_conf) assert get_balance(currency='BTC') == 123.4
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)
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 for _pair in whitelist: if get_buy_signal(_pair): pair = _pair break else: return None open_rate = get_target_bid(exchange.get_ticker(pair)) amount = stake_amount / open_rate order_id = exchange.buy(pair, open_rate, amount) # Create trade entity and return message = '*{}:* Buying [{}]({}) at rate `{:f}`'.format( exchange.EXCHANGE.name.upper(), pair.replace('_', '/'), exchange.get_pair_detail_url(pair), open_rate ) logger.info(message) telegram.send_msg(message) return Trade(pair=pair, stake_amount=stake_amount, open_rate=open_rate, open_date=datetime.utcnow(), amount=amount, exchange=exchange.EXCHANGE.name.upper(), open_order_id=order_id, is_open=True)
def execute_sell(trade: Trade, current_rate: float) -> None: """ Executes a sell for the given trade and current rate :param trade: Trade instance :param current_rate: current rate :return: None """ # Get available balance currency = trade.pair.split('_')[1] balance = exchange.get_balance(currency) profit = trade.exec_sell_order(current_rate, balance) message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format( trade.exchange, trade.pair.replace('_', '/'), exchange.get_pair_detail_url(trade.pair), trade.close_rate, round(profit, 2)) logger.info(message) telegram.send_msg(message)
def _forcesell(bot: Bot, update: Update) -> None: """ Handler for /forcesell <id>. Sells the given trade at current price :param bot: telegram bot :param update: message update :return: None """ if get_state() != State.RUNNING: send_msg('`trader is not running`', bot=bot) return try: trade_id = int(update.message.text .replace('/forcesell', '') .strip()) # Query for trade trade = Trade.query.filter(and_( Trade.id == trade_id, Trade.is_open.is_(True) )).first() if not trade: send_msg('There is no open trade with ID: `{}`'.format(trade_id)) return # Get current rate current_rate = exchange.get_ticker(trade.pair)['bid'] # Get available balance currency = trade.pair.split('_')[1] balance = exchange.get_balance(currency) # Execute sell profit = trade.exec_sell_order(current_rate, balance) message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format( trade.exchange, trade.pair.replace('_', '/'), exchange.get_pair_detail_url(trade.pair), trade.close_rate, round(profit, 2) ) logger.info(message) send_msg(message) except ValueError: send_msg('Invalid argument. Usage: `/forcesell <trade_id>`') logger.warning('/forcesell: Invalid argument received')
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
def test_get_balance_dry_run(default_conf, mocker): default_conf['dry_run'] = True mocker.patch.dict('freqtrade.exchange._CONF', default_conf) assert get_balance(currency='BTC') == 999.9
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
def test_get_balance_dry_run(default_conf, mocker): default_conf['dry_run'] = True mocker.patch.dict('freqtrade.exchange._CONF', default_conf) assert get_balance(currency='BTC') == 999.9
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' )