Merge pull request #1576 from hroff-1902/patch-10

Minor: code cleanup in _process()
This commit is contained in:
Misagh 2019-02-26 10:17:21 +01:00 committed by GitHub
commit cee4116b80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 17 deletions

View File

@ -7,7 +7,7 @@ import logging
import time import time
import traceback import traceback
from datetime import datetime from datetime import datetime
from typing import Any, Callable, Dict, List, Optional from typing import Any, Callable, Dict, List, Optional, Tuple
import arrow import arrow
from requests.exceptions import RequestException from requests.exceptions import RequestException
@ -159,24 +159,20 @@ class FreqtradeBot(object):
self.pairlists.refresh_pairlist() self.pairlists.refresh_pairlist()
self.active_pair_whitelist = self.pairlists.whitelist self.active_pair_whitelist = self.pairlists.whitelist
# Calculating Edge positiong # Calculating Edge positioning
if self.edge: if self.edge:
self.edge.calculate() self.edge.calculate()
self.active_pair_whitelist = self.edge.adjust(self.active_pair_whitelist) self.active_pair_whitelist = self.edge.adjust(self.active_pair_whitelist)
# Query trades from persistence layer # Query trades from persistence layer
trades = Trade.query.filter(Trade.is_open.is_(True)).all() trades = Trade.get_open_trades()
# Extend active-pair whitelist with pairs from open trades # Extend active-pair whitelist with pairs from open trades
# ensures that tickers are downloaded for open trades # It ensures that tickers are downloaded for open trades
self.active_pair_whitelist.extend([trade.pair for trade in trades self._extend_whitelist_with_trades(self.active_pair_whitelist, trades)
if trade.pair not in self.active_pair_whitelist])
# Create pair-whitelist tuple with (pair, ticker_interval)
pair_whitelist_tuple = [(pair, self.config['ticker_interval'])
for pair in self.active_pair_whitelist]
# Refreshing candles # Refreshing candles
self.dataprovider.refresh(pair_whitelist_tuple, self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist),
self.strategy.informative_pairs()) self.strategy.informative_pairs())
# First process current opened trades # First process current opened trades
@ -206,6 +202,18 @@ class FreqtradeBot(object):
self.state = State.STOPPED self.state = State.STOPPED
return state_changed return state_changed
def _extend_whitelist_with_trades(self, whitelist: List[str], trades: List[Any]):
"""
Extend whitelist with pairs from open trades
"""
whitelist.extend([trade.pair for trade in trades if trade.pair not in whitelist])
def _create_pair_whitelist(self, pairs: List[str]) -> List[Tuple[str, str]]:
"""
Create pair-whitelist tuple with (pair, ticker_interval)
"""
return [(pair, self.config['ticker_interval']) for pair in pairs]
def get_target_bid(self, pair: str) -> float: def get_target_bid(self, pair: str) -> float:
""" """
Calculates bid target between current ask price and last price Calculates bid target between current ask price and last price
@ -253,7 +261,7 @@ class FreqtradeBot(object):
avaliable_amount = self.wallets.get_free(self.config['stake_currency']) avaliable_amount = self.wallets.get_free(self.config['stake_currency'])
if stake_amount == constants.UNLIMITED_STAKE_AMOUNT: if stake_amount == constants.UNLIMITED_STAKE_AMOUNT:
open_trades = len(Trade.query.filter(Trade.is_open.is_(True)).all()) open_trades = len(Trade.get_open_trades())
if open_trades >= self.config['max_open_trades']: if open_trades >= self.config['max_open_trades']:
logger.warning('Can\'t open a new trade: max number of trades is reached') logger.warning('Can\'t open a new trade: max number of trades is reached')
return None return None
@ -311,7 +319,7 @@ class FreqtradeBot(object):
whitelist = copy.deepcopy(self.active_pair_whitelist) whitelist = copy.deepcopy(self.active_pair_whitelist)
# Remove currently opened and latest pairs from whitelist # Remove currently opened and latest pairs from whitelist
for trade in Trade.query.filter(Trade.is_open.is_(True)).all(): for trade in Trade.get_open_trades():
if trade.pair in whitelist: if trade.pair in whitelist:
whitelist.remove(trade.pair) whitelist.remove(trade.pair)
logger.debug('Ignoring %s in pair whitelist', trade.pair) logger.debug('Ignoring %s in pair whitelist', trade.pair)

View File

@ -5,7 +5,7 @@ This module contains the class to persist trades into SQLite
import logging import logging
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from typing import Any, Dict, Optional from typing import Any, Dict, List, Optional
import arrow import arrow
from sqlalchemy import (Boolean, Column, DateTime, Float, Integer, String, from sqlalchemy import (Boolean, Column, DateTime, Float, Integer, String,
@ -371,3 +371,10 @@ class Trade(_DECL_BASE):
.filter(Trade.is_open.is_(True))\ .filter(Trade.is_open.is_(True))\
.scalar() .scalar()
return total_open_stake_amount or 0 return total_open_stake_amount or 0
@staticmethod
def get_open_trades() -> List[Any]:
"""
Query trades from persistence layer
"""
return Trade.query.filter(Trade.is_open.is_(True)).all()

View File

@ -83,7 +83,7 @@ class RPC(object):
a remotely exposed function a remotely exposed function
""" """
# Fetch open trade # Fetch open trade
trades = Trade.query.filter(Trade.is_open.is_(True)).all() trades = Trade.get_open_trades()
if not trades: if not trades:
raise RPCException('no active trade') raise RPCException('no active trade')
else: else:
@ -118,7 +118,7 @@ class RPC(object):
return results return results
def _rpc_status_table(self) -> DataFrame: def _rpc_status_table(self) -> DataFrame:
trades = Trade.query.filter(Trade.is_open.is_(True)).all() trades = Trade.get_open_trades()
if not trades: if not trades:
raise RPCException('no active order') raise RPCException('no active order')
else: else:
@ -366,7 +366,7 @@ class RPC(object):
if trade_id == 'all': if trade_id == 'all':
# Execute sell for all open orders # Execute sell for all open orders
for trade in Trade.query.filter(Trade.is_open.is_(True)).all(): for trade in Trade.get_open_trades():
_exec_forcesell(trade) _exec_forcesell(trade)
Trade.session.flush() Trade.session.flush()
return return
@ -442,7 +442,7 @@ class RPC(object):
if self._freqtrade.state != State.RUNNING: if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running') raise RPCException('trader is not running')
return Trade.query.filter(Trade.is_open.is_(True)).all() return Trade.get_open_trades()
def _rpc_whitelist(self) -> Dict: def _rpc_whitelist(self) -> Dict:
""" Returns the currently active whitelist""" """ Returns the currently active whitelist"""

View File

@ -629,3 +629,48 @@ def test_adjust_stop_loss(limit_buy_order, limit_sell_order, fee):
assert round(trade.stop_loss, 8) == 1.26 assert round(trade.stop_loss, 8) == 1.26
assert trade.max_rate == 1.4 assert trade.max_rate == 1.4
assert trade.initial_stop_loss == 0.95 assert trade.initial_stop_loss == 0.95
def test_get_open(default_conf, fee):
init(default_conf)
# Simulate dry_run entries
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=123.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_rate=0.123,
exchange='bittrex',
open_order_id='dry_run_buy_12345'
)
Trade.session.add(trade)
trade = Trade(
pair='ETC/BTC',
stake_amount=0.001,
amount=123.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_rate=0.123,
exchange='bittrex',
is_open=False,
open_order_id='dry_run_sell_12345'
)
Trade.session.add(trade)
# Simulate prod entry
trade = Trade(
pair='ETC/BTC',
stake_amount=0.001,
amount=123.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_rate=0.123,
exchange='bittrex',
open_order_id='prod_buy_12345'
)
Trade.session.add(trade)
assert len(Trade.get_open_trades()) == 2