Repository: freqtrade/freqtrade

Issue:
process_only_new_candles not applied correctly when trades happen
Can freqtrade prevent new buys when stop loss is reach and signal buy still active. 

Example (5 minutes strategy max_trade_open = 1 ) : Freqtrade buy at 10h00 stop loss reached at 10:02 (2% stop loss) and buy another pair at 10h02 but I don't want because it is 2 minutes too late.

Many tks
process_only_new_candles not applied correctly when trades happen
Can freqtrade prevent new buys when stop loss is reach and signal buy still active. 

Example (5 minutes strategy max_trade_open = 1 ) : Freqtrade buy at 10h00 stop loss reached at 10:02 (2% stop loss) and buy another pair at 10h02 but I don't want because it is 2 minutes too late.

Many tks


Discussion:
no - and i am not sure that makes sense either ... for one, you should work on the strategy ...

However, once a trade is closed (via ROI or stoploss) - then that trade is over and does not really matter for future signals. We could (maybe) implement a "cooldown" period after stoplosses to prevent repetitive buying (which might tie into #1841) - however i'm not sure this isn't responsability of the strategy...

On the other hand - if a coin went down, chances are it'll come back up soonish (assuming no strong trend is present) - so buying shortly after that can make sense.

If your concern is regarding the buy in the middle of a candle (5m candles - should in theory buy only at 5 / 0 marks) - then `self.process_only_new_candles=True` in the strategy is your friend (which only analyzes when new candles arrive - not at the 2m mark). 

Note that this will also affect your sell-signal - but does NOT apply to ROI / stoploss.

I think @gaugau3000 is talking about buy signal used once. interval 5min, buy at 12:00, stoploss hit at 12:02 then 5sec after buys again ... bot does not have a memory of already used signal.

EDIT: sorry I didn't read "another pair". so my comment is unrelated unless "another pair" means same pair :D but another trade.
What can "another pair" mean in the question above?

@gaugau3000, could you illustrate the point in some more details?

@hroff-1902 yes i will try to explain better.

I have a 2% stop loss and only 1 max open trade my ticker interval is 5 minutes and the process only new candle is set to true.

The bot make a buy at 10:00 (BTC/ETH) -> stop loss is reached at 10:02 -> then the bot make (immediatly) a new buy an another pair (BTC/ETC) . But i don't want he do a new buy an BTC/ETC has it is too late.

@xmatthias 

> no - and i am not sure that makes sense either ... for one, you should work on the strategy ...

Yes i am sure i have to improve but my concern is just don't hold an asset too long when the market is agitated not to miss opportunities as i have only 1 max open trade.

> However, once a trade is closed (via ROI or stoploss) - then that trade is over and does not really matter for future signals. We could (maybe) implement a "cooldown" period after stoplosses to prevent repetitive buying (which might tie into #1841) - however i'm not sure this isn't responsability of the strategy...

Yes i fully agree with you. My concern is just when there is a buy on the middle of a candle an another pair . For info the process only new candle is set to true.

> On the other hand - if a coin went down, chances are it'll come back up soonish (assuming no strong trend is present) - so buying shortly after that can make sense.

I am not successful with trends strategies :-( so the strategy is only a buy on oversold. If it buy 1 minutes later it's too late (i have plot many times backtest results). I have even disable rate limit to win couples of seconds :-) . 

> If your concern is regarding the buy in the middle of a candle (5m candles - should in theory buy only at 5 / 0 marks) - then self.process_only_new_candles=True in the strategy is your friend (which only analyzes when new candles arrive - not at the 2m mark).

I have activated but it seems that if  there is a buy signal on two pairs and it buy one pair and the stop loss is reached before the end of the candle it performs a new buy on the other pair.

> Note that this will also affect your sell-signal - but does NOT apply to ROI / stoploss.
I have no sell signal :-) but it affect the sell signal only if it based on tick data ?

Many tks

I think @gaugau3000 is right, I've also noted this behaviour in the past but I forgot about it.

Let's say we have `5m, max_open_trades=1, process_only_new_candles=1` and 2 pairs ETH/BTC, LTC/BTC:
- At 10:00 **both** pairs signal to buy. ETH/BTC is before in the whitelist so the bot buys it.
- The trade goes wrong and the SL is reached at 10:02, so it sells ETH.
- Immediately after the bot search for a new possible trade and since `_last_candle_seen_per_pair` is not set for the pair LTC/BTC and the candle is the same as before (we remove the last partial candle) the bot buys LTC.

Maybe this behaviour is not wrong for some strategies, but we can consider to make it configurable. 
i'm not sure why `_last_candle_seen_per_pair` would not be set - it bought at 10:00 - and part of creating the buy-signal is setting this flag (`interface.py - analyze_ticker`).

The same method is called when generating the sell signal - so even with a delay (buy at 10:00, sell at 10:07) should not trigger this (since at 10:05 the pair was elaborated for sell signals).


>and part of creating the buy-signal is setting this flag (interface.py - analyze_ticker)

Yes, but it is set only for ETH/BTC. If you follow the code back in `freqtradebot.py` you will note that if a buy signal is executed the loop over whitelist will not be completed - so LTC/BTC will not have a value for `_last_candle_seen_per_pair` at 10:00.

https://github.com/freqtrade/freqtrade/blob/175fc8591e1d6619f891b4136c7adae106272125/freqtrade/freqtradebot.py#L290 
yes - but the above is for buying the same pair - not a different pair ... (but yes - terminating the loop is "unfortunate" at best - wrong at worst - depending on the view) - as it'll also cause "earlier" pairs to be evaluated far more often than "later" pairs.

I think gaugau300 is referring to buying a different pair, not the same.

>The bot make a buy at 10:00 (BTC/ETH) -> stop loss is reached at 10:02 -> then the bot make (immediatly) a new buy an another pair (BTC/ETC) .
Happened just few hours ago. Interval is 2h, so all buy signals are relative to 16:00. 
Config: `max_open_trades=1, process_only_new_candles=1`.

```
2019-05-16 16:00:10,352 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:00:10,353 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:00:13,864 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now)
2019-05-16 16:00:13,865 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:00:13,865 - freqtrade.persistence - INFO - Updating trade (id=49) ...
2019-05-16 16:00:13,865 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now).

2019-05-16 16:02:46,138 - freqtrade.freqtradebot - INFO - executed sell, reason: SellType.STOP_LOSS
2019-05-16 16:02:50,830 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=2 minutes ago)
2019-05-16 16:02:50,831 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=2 minutes ago) failed: myTrade-Dict empty found
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - Updating trade (id=49) ...
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - Marking Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=closed) as closed as the trade is fulfilled and found no open orders for it.
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - MARKET_SELL has been fulfilled for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=closed).

2019-05-16 16:02:56,832 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:02:56,832 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:03:00,837 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now)
2019-05-16 16:03:00,837 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:03:00,838 - freqtrade.persistence - INFO - Updating trade (id=50) ...
2019-05-16 16:03:00,838 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now).

2019-05-16 16:14:46,593 - freqtrade.freqtradebot - INFO - executed sell, reason: SellType.TRAILING_STOP_LOSS
2019-05-16 16:14:51,298 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=11 minutes ago)
2019-05-16 16:14:51,298 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=11 minutes ago) failed: myTrade-Dict empty found
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - Updating trade (id=50) ...
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - Marking Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=closed) as closed as the trade is fulfilled and found no open orders for it.
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - MARKET_SELL has been fulfilled for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=closed).

2019-05-16 16:14:56,605 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:14:56,606 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:15:01,311 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now)
2019-05-16 16:15:01,311 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:15:01,311 - freqtrade.persistence - INFO - Updating trade (id=51) ...
2019-05-16 16:15:01,312 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now).
```
@gianlup is there a way to workaround this in the strategy? I ask that because you write code for #1904 issue (but if i well understand your code your hack prevent only buys on the same candle on the same pair ?). Many tks 4 help.
Yes, you can use the same code. It's an hacky way but it should prevents multiple buys in the same candle - no matter if it's the same pair or different one. 

Make sure to have `process_only_new_candles=1`.
no - and i am not sure that makes sense either ... for one, you should work on the strategy ...

However, once a trade is closed (via ROI or stoploss) - then that trade is over and does not really matter for future signals. We could (maybe) implement a "cooldown" period after stoplosses to prevent repetitive buying (which might tie into #1841) - however i'm not sure this isn't responsability of the strategy...

On the other hand - if a coin went down, chances are it'll come back up soonish (assuming no strong trend is present) - so buying shortly after that can make sense.

If your concern is regarding the buy in the middle of a candle (5m candles - should in theory buy only at 5 / 0 marks) - then `self.process_only_new_candles=True` in the strategy is your friend (which only analyzes when new candles arrive - not at the 2m mark). 

Note that this will also affect your sell-signal - but does NOT apply to ROI / stoploss.

I think @gaugau3000 is talking about buy signal used once. interval 5min, buy at 12:00, stoploss hit at 12:02 then 5sec after buys again ... bot does not have a memory of already used signal.

EDIT: sorry I didn't read "another pair". so my comment is unrelated unless "another pair" means same pair :D but another trade.
What can "another pair" mean in the question above?

@gaugau3000, could you illustrate the point in some more details?

@hroff-1902 yes i will try to explain better.

I have a 2% stop loss and only 1 max open trade my ticker interval is 5 minutes and the process only new candle is set to true.

The bot make a buy at 10:00 (BTC/ETH) -> stop loss is reached at 10:02 -> then the bot make (immediatly) a new buy an another pair (BTC/ETC) . But i don't want he do a new buy an BTC/ETC has it is too late.

@xmatthias 

> no - and i am not sure that makes sense either ... for one, you should work on the strategy ...

Yes i am sure i have to improve but my concern is just don't hold an asset too long when the market is agitated not to miss opportunities as i have only 1 max open trade.

> However, once a trade is closed (via ROI or stoploss) - then that trade is over and does not really matter for future signals. We could (maybe) implement a "cooldown" period after stoplosses to prevent repetitive buying (which might tie into #1841) - however i'm not sure this isn't responsability of the strategy...

Yes i fully agree with you. My concern is just when there is a buy on the middle of a candle an another pair . For info the process only new candle is set to true.

> On the other hand - if a coin went down, chances are it'll come back up soonish (assuming no strong trend is present) - so buying shortly after that can make sense.

I am not successful with trends strategies :-( so the strategy is only a buy on oversold. If it buy 1 minutes later it's too late (i have plot many times backtest results). I have even disable rate limit to win couples of seconds :-) . 

> If your concern is regarding the buy in the middle of a candle (5m candles - should in theory buy only at 5 / 0 marks) - then self.process_only_new_candles=True in the strategy is your friend (which only analyzes when new candles arrive - not at the 2m mark).

I have activated but it seems that if  there is a buy signal on two pairs and it buy one pair and the stop loss is reached before the end of the candle it performs a new buy on the other pair.

> Note that this will also affect your sell-signal - but does NOT apply to ROI / stoploss.
I have no sell signal :-) but it affect the sell signal only if it based on tick data ?

Many tks

I think @gaugau3000 is right, I've also noted this behaviour in the past but I forgot about it.

Let's say we have `5m, max_open_trades=1, process_only_new_candles=1` and 2 pairs ETH/BTC, LTC/BTC:
- At 10:00 **both** pairs signal to buy. ETH/BTC is before in the whitelist so the bot buys it.
- The trade goes wrong and the SL is reached at 10:02, so it sells ETH.
- Immediately after the bot search for a new possible trade and since `_last_candle_seen_per_pair` is not set for the pair LTC/BTC and the candle is the same as before (we remove the last partial candle) the bot buys LTC.

Maybe this behaviour is not wrong for some strategies, but we can consider to make it configurable. 
i'm not sure why `_last_candle_seen_per_pair` would not be set - it bought at 10:00 - and part of creating the buy-signal is setting this flag (`interface.py - analyze_ticker`).

The same method is called when generating the sell signal - so even with a delay (buy at 10:00, sell at 10:07) should not trigger this (since at 10:05 the pair was elaborated for sell signals).


>and part of creating the buy-signal is setting this flag (interface.py - analyze_ticker)

Yes, but it is set only for ETH/BTC. If you follow the code back in `freqtradebot.py` you will note that if a buy signal is executed the loop over whitelist will not be completed - so LTC/BTC will not have a value for `_last_candle_seen_per_pair` at 10:00.

https://github.com/freqtrade/freqtrade/blob/175fc8591e1d6619f891b4136c7adae106272125/freqtrade/freqtradebot.py#L290 
yes - but the above is for buying the same pair - not a different pair ... (but yes - terminating the loop is "unfortunate" at best - wrong at worst - depending on the view) - as it'll also cause "earlier" pairs to be evaluated far more often than "later" pairs.

I think gaugau300 is referring to buying a different pair, not the same.

>The bot make a buy at 10:00 (BTC/ETH) -> stop loss is reached at 10:02 -> then the bot make (immediatly) a new buy an another pair (BTC/ETC) .
Happened just few hours ago. Interval is 2h, so all buy signals are relative to 16:00. 
Config: `max_open_trades=1, process_only_new_candles=1`.

```
2019-05-16 16:00:10,352 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:00:10,353 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:00:13,864 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now)
2019-05-16 16:00:13,865 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:00:13,865 - freqtrade.persistence - INFO - Updating trade (id=49) ...
2019-05-16 16:00:13,865 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=just now).

2019-05-16 16:02:46,138 - freqtrade.freqtradebot - INFO - executed sell, reason: SellType.STOP_LOSS
2019-05-16 16:02:50,830 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=2 minutes ago)
2019-05-16 16:02:50,831 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=2 minutes ago) failed: myTrade-Dict empty found
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - Updating trade (id=49) ...
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - Marking Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=closed) as closed as the trade is fulfilled and found no open orders for it.
2019-05-16 16:02:50,831 - freqtrade.persistence - INFO - MARKET_SELL has been fulfilled for Trade(id=49, pair=SKY/BTC, amount=1219.51219512, open_rate=0.00024600, open_since=closed).

2019-05-16 16:02:56,832 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:02:56,832 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:03:00,837 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now)
2019-05-16 16:03:00,837 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:03:00,838 - freqtrade.persistence - INFO - Updating trade (id=50) ...
2019-05-16 16:03:00,838 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=just now).

2019-05-16 16:14:46,593 - freqtrade.freqtradebot - INFO - executed sell, reason: SellType.TRAILING_STOP_LOSS
2019-05-16 16:14:51,298 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=11 minutes ago)
2019-05-16 16:14:51,298 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=11 minutes ago) failed: myTrade-Dict empty found
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - Updating trade (id=50) ...
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - Marking Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=closed) as closed as the trade is fulfilled and found no open orders for it.
2019-05-16 16:14:51,298 - freqtrade.persistence - INFO - MARKET_SELL has been fulfilled for Trade(id=50, pair=ETH/BTC, amount=8.75426771, open_rate=0.03426900, open_since=closed).

2019-05-16 16:14:56,605 - freqtrade.freqtradebot - INFO - Buy signal found: about create a new trade with stake_amount: 0.3 ...
2019-05-16 16:14:56,606 - freqtrade.freqtradebot - INFO - Using Last Ask / Last Price
2019-05-16 16:15:01,311 - freqtrade.freqtradebot - INFO - Found open order for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now)
2019-05-16 16:15:01,311 - freqtrade.freqtradebot - INFO - Applying fee on amount for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now) failed: myTrade-Dict empty found
2019-05-16 16:15:01,311 - freqtrade.persistence - INFO - Updating trade (id=51) ...
2019-05-16 16:15:01,312 - freqtrade.persistence - INFO - LIMIT_BUY has been fulfilled for Trade(id=51, pair=XEM/BTC, amount=24077.04654896, open_rate=0.00001246, open_since=just now).
```
@gianlup is there a way to workaround this in the strategy? I ask that because you write code for #1904 issue (but if i well understand your code your hack prevent only buys on the same candle on the same pair ?). Many tks 4 help.
Yes, you can use the same code. It's an hacky way but it should prevents multiple buys in the same candle - no matter if it's the same pair or different one. 

Make sure to have `process_only_new_candles=1`.

Resolving patch:
diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py
--- a/freqtrade/freqtradebot.py
+++ b/freqtrade/freqtradebot.py
@@ -105,13 +105,12 @@ def startup(self) -> None:
             # Adjust stoploss if it was changed
             Trade.stoploss_reinitialization(self.strategy.stoploss)
 
-    def process(self) -> bool:
+    def process(self) -> None:
         """
         Queries the persistence layer for open trades and handles them,
         otherwise a new trade is created.
         :return: True if one or more trades has been created or closed, False otherwise
         """
-        state_changed = False
 
         # Check whether markets have to be reloaded
         self.exchange._reload_markets()
@@ -138,19 +137,17 @@ def process(self) -> bool:
 
         # First process current opened trades
         for trade in trades:
-            state_changed |= self.process_maybe_execute_sell(trade)
+            self.process_maybe_execute_sell(trade)
 
         # Then looking for buy opportunities
         if len(trades) < self.config['max_open_trades']:
-            state_changed = self.process_maybe_execute_buy()
+            self.process_maybe_execute_buy()
 
         if 'unfilledtimeout' in self.config:
             # Check and handle any timed out open orders
             self.check_handle_timedout()
             Trade.session.flush()
 
-        return state_changed
-
     def _extend_whitelist_with_trades(self, whitelist: List[str], trades: List[Any]):
         """
         Extend whitelist with pairs from open trades
@@ -259,11 +256,12 @@ def _get_min_pair_stake_amount(self, pair: str, price: float) -> Optional[float]
         amount_reserve_percent = max(amount_reserve_percent, 0.5)
         return min(min_stake_amounts) / amount_reserve_percent
 
-    def create_trade(self) -> bool:
+    def create_trades(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
-        :return: True if a trade object has been created and persisted, False otherwise
+        Checks the implemented trading strategy for buy-signals, using the active pair whitelist.
+        If a pair triggers the buy_signal a new trade record gets created.
+        Checks pairs as long as the open trade count is below `max_open_trades`.
+        :return: True if at least one trade has been created.
         """
         interval = self.strategy.ticker_interval
         whitelist = copy.deepcopy(self.active_pair_whitelist)
@@ -282,15 +280,16 @@ def create_trade(self) -> bool:
             logger.info("No currency pair in whitelist, but checking to sell open trades.")
             return False
 
+        buycount = 0
         # running get_signal on historical data fetched
         for _pair in whitelist:
             (buy, sell) = self.strategy.get_signal(
                 _pair, interval, self.dataprovider.ohlcv(_pair, self.strategy.ticker_interval))
 
-            if buy and not sell:
+            if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']:
                 stake_amount = self._get_trade_stake_amount(_pair)
                 if not stake_amount:
-                    return False
+                    continue
 
                 logger.info(f"Buy signal found: about create a new trade with stake_amount: "
                             f"{stake_amount} ...")
@@ -300,12 +299,13 @@ def create_trade(self) -> bool:
                 if (bidstrat_check_depth_of_market.get('enabled', False)) and\
                         (bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0):
                     if self._check_depth_of_market_buy(_pair, bidstrat_check_depth_of_market):
-                        return self.execute_buy(_pair, stake_amount)
+                        buycount += self.execute_buy(_pair, stake_amount)
                     else:
-                        return False
-                return self.execute_buy(_pair, stake_amount)
+                        continue
 
-        return False
+                buycount += self.execute_buy(_pair, stake_amount)
+
+        return buycount > 0
 
     def _check_depth_of_market_buy(self, pair: str, conf: Dict) -> bool:
         """
@@ -429,21 +429,17 @@ def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = N
 
         return True
 
-    def process_maybe_execute_buy(self) -> bool:
+    def process_maybe_execute_buy(self) -> None:
         """
         Tries to execute a buy trade in a safe way
         :return: True if executed
         """
         try:
             # Create entity and execute trade
-            if self.create_trade():
-                return True
-
-            logger.info('Found no buy signals for whitelisted currencies. Trying again..')
-            return False
+            if not self.create_trades():
+                logger.info('Found no buy signals for whitelisted currencies. Trying again...')
         except DependencyException as exception:
             logger.warning('Unable to create trade: %s', exception)
-            return False
 
     def process_maybe_execute_sell(self, trade: Trade) -> bool:
         """
diff --git a/freqtrade/worker.py b/freqtrade/worker.py
--- a/freqtrade/worker.py
+++ b/freqtrade/worker.py
@@ -127,11 +127,10 @@ def _throttle(self, func: Callable[..., Any], min_secs: float, *args, **kwargs)
         time.sleep(duration)
         return result
 
-    def _process(self) -> bool:
+    def _process(self) -> None:
         logger.debug("========================================")
-        state_changed = False
         try:
-            state_changed = self.freqtrade.process()
+            self.freqtrade.process()
         except TemporaryError as error:
             logger.warning(f"Error: {error}, retrying in {constants.RETRY_TIMEOUT} seconds...")
             time.sleep(constants.RETRY_TIMEOUT)
@@ -144,10 +143,6 @@ def _process(self) -> bool:
             })
             logger.exception('OperationalException. Stopping trader ...')
             self.freqtrade.state = State.STOPPED
-            # TODO: The return value of _process() is not used apart tests
-            # and should (could) be eliminated later. See PR #1689.
-#            state_changed = True
-        return state_changed
 
     def _reconfigure(self) -> None:
         """


Test patch:
diff --git a/freqtrade/tests/rpc/test_rpc.py b/freqtrade/tests/rpc/test_rpc.py
--- a/freqtrade/tests/rpc/test_rpc.py
+++ b/freqtrade/tests/rpc/test_rpc.py
@@ -44,7 +44,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None:
     with pytest.raises(RPCException, match=r'.*no active trade*'):
         rpc._rpc_trade_status()
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     results = rpc._rpc_trade_status()
     assert {
         'trade_id': 1,
@@ -116,7 +116,7 @@ def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None:
     with pytest.raises(RPCException, match=r'.*no active order*'):
         rpc._rpc_status_table()
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     result = rpc._rpc_status_table()
     assert 'instantly' in result['Since'].all()
     assert 'ETH/BTC' in result['Pair'].all()
@@ -151,7 +151,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
     rpc = RPC(freqtradebot)
     rpc._fiat_converter = CryptoToFiatConverter()
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     assert trade
 
@@ -208,7 +208,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
         rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     # Simulate fulfilled LIMIT_BUY order for trade
     trade.update(limit_buy_order)
@@ -222,7 +222,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
     trade.close_date = datetime.utcnow()
     trade.is_open = False
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     # Simulate fulfilled LIMIT_BUY order for trade
     trade.update(limit_buy_order)
@@ -292,7 +292,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
     rpc = RPC(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     # Simulate fulfilled LIMIT_BUY order for trade
     trade.update(limit_buy_order)
@@ -536,7 +536,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
     msg = rpc._rpc_forcesell('all')
     assert msg == {'result': 'Created sell orders for all open trades.'}
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     msg = rpc._rpc_forcesell('all')
     assert msg == {'result': 'Created sell orders for all open trades.'}
 
@@ -570,7 +570,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
     assert cancel_order_mock.call_count == 1
     assert trade.amount == filled_amount
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.filter(Trade.id == '2').first()
     amount = trade.amount
     # make an limit-buy open trade, if there is no 'filled', don't sell it
@@ -589,7 +589,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
     assert cancel_order_mock.call_count == 2
     assert trade.amount == amount
 
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     # make an limit-sell open trade
     mocker.patch(
         'freqtrade.exchange.Exchange.get_order',
@@ -622,7 +622,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
     rpc = RPC(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     assert trade
 
@@ -660,7 +660,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None:
     assert counts["current"] == 0
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     counts = rpc._rpc_count()
     assert counts["current"] == 1
 
diff --git a/freqtrade/tests/rpc/test_rpc_apiserver.py b/freqtrade/tests/rpc/test_rpc_apiserver.py
--- a/freqtrade/tests/rpc/test_rpc_apiserver.py
+++ b/freqtrade/tests/rpc/test_rpc_apiserver.py
@@ -275,7 +275,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets):
     assert rc.json["max"] == 1.0
 
     # Create some test data
-    ftbot.create_trade()
+    ftbot.create_trades()
     rc = client_get(client, f"{BASE_URI}/count")
     assert_response(rc)
     assert rc.json["current"] == 1.0
@@ -329,7 +329,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li
     assert len(rc.json) == 1
     assert rc.json == {"error": "Error querying _profit: no closed trade"}
 
-    ftbot.create_trade()
+    ftbot.create_trades()
     trade = Trade.query.first()
 
     # Simulate fulfilled LIMIT_BUY order for trade
@@ -418,7 +418,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
     assert_response(rc, 502)
     assert rc.json == {'error': 'Error querying _status: no active trade'}
 
-    ftbot.create_trade()
+    ftbot.create_trades()
     rc = client_get(client, f"{BASE_URI}/status")
     assert_response(rc)
     assert len(rc.json) == 1
@@ -548,7 +548,7 @@ def test_api_forcesell(botclient, mocker, ticker, fee, markets):
     assert_response(rc, 502)
     assert rc.json == {"error": "Error querying _forcesell: invalid argument"}
 
-    ftbot.create_trade()
+    ftbot.create_trades()
 
     rc = client_post(client, f"{BASE_URI}/forcesell",
                      data='{"tradeid": "1"}')
diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py
--- a/freqtrade/tests/rpc/test_rpc_telegram.py
+++ b/freqtrade/tests/rpc/test_rpc_telegram.py
@@ -192,7 +192,7 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
 
     # Create some test data
     for _ in range(3):
-        freqtradebot.create_trade()
+        freqtradebot.create_trades()
 
     telegram._status(bot=MagicMock(), update=update)
     assert msg_mock.call_count == 1
@@ -240,7 +240,7 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
     msg_mock.reset_mock()
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     # Trigger status while we have a fulfilled order for the open trade
     telegram._status(bot=MagicMock(), update=update)
 
@@ -292,7 +292,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
     msg_mock.reset_mock()
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
 
     telegram._status_table(bot=MagicMock(), update=update)
 
@@ -308,6 +308,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
 def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
                       limit_sell_order, markets, mocker) -> None:
     patch_exchange(mocker)
+    default_conf['max_open_trades'] = 1
     mocker.patch(
         'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price',
         return_value=15000.0
@@ -331,7 +332,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
     telegram = Telegram(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     assert trade
 
@@ -357,9 +358,9 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
 
     # Reset msg_mock
     msg_mock.reset_mock()
+    freqtradebot.config['max_open_trades'] = 2
     # Add two other trades
-    freqtradebot.create_trade()
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
 
     trades = Trade.query.all()
     for trade in trades:
@@ -438,7 +439,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
     msg_mock.reset_mock()
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
 
     # Simulate fulfilled LIMIT_BUY order for trade
@@ -733,7 +734,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
     telegram = Telegram(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -784,7 +785,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
     telegram = Telegram(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
 
     # Decrease the price and sell it
     mocker.patch.multiple(
@@ -832,14 +833,13 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker
         markets=PropertyMock(return_value=markets),
         validate_pairs=MagicMock(return_value={})
     )
-
+    default_conf['max_open_trades'] = 4
     freqtradebot = FreqtradeBot(default_conf)
     patch_get_signal(freqtradebot, (True, False))
     telegram = Telegram(freqtradebot)
 
     # Create some test data
-    for _ in range(4):
-        freqtradebot.create_trade()
+    freqtradebot.create_trades()
     rpc_mock.reset_mock()
 
     update.message.text = '/forcesell all'
@@ -983,7 +983,7 @@ def test_performance_handle(default_conf, update, ticker, fee,
     telegram = Telegram(freqtradebot)
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     trade = Trade.query.first()
     assert trade
 
@@ -1028,7 +1028,7 @@ def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> Non
     freqtradebot.state = State.RUNNING
 
     # Create some test data
-    freqtradebot.create_trade()
+    freqtradebot.create_trades()
     msg_mock.reset_mock()
     telegram._count(bot=MagicMock(), update=update)
 
diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py
--- a/freqtrade/tests/test_freqtradebot.py
+++ b/freqtrade/tests/test_freqtradebot.py
@@ -253,13 +253,13 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf,
     assert result == default_conf['stake_amount'] / conf['max_open_trades']
 
     # create one trade, order amount should be 'balance / (max_open_trades - num_open_trades)'
-    freqtrade.create_trade()
+    freqtrade.execute_buy('ETH/BTC', result)
 
     result = freqtrade._get_trade_stake_amount('LTC/BTC')
     assert result == default_conf['stake_amount'] / (conf['max_open_trades'] - 1)
 
     # create 2 trades, order amount should be None
-    freqtrade.create_trade()
+    freqtrade.execute_buy('LTC/BTC', result)
 
     result = freqtrade._get_trade_stake_amount('XRP/BTC')
     assert result is None
@@ -301,6 +301,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, markets, caplog, mocker,
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     patch_edge(mocker)
+    edge_conf['max_open_trades'] = float('inf')
 
     # Strategy stoploss is -0.1 but Edge imposes a stoploss at -0.2
     # Thus, if price falls 21%, stoploss should be triggered
@@ -325,7 +326,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, markets, caplog, mocker,
     freqtrade.active_pair_whitelist = ['NEO/BTC']
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.update(limit_buy_order)
     #############################################
@@ -341,6 +342,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, markets,
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     patch_edge(mocker)
+    edge_conf['max_open_trades'] = float('inf')
 
     # Strategy stoploss is -0.1 but Edge imposes a stoploss at -0.2
     # Thus, if price falls 15%, stoploss should not be triggered
@@ -365,7 +367,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, markets,
     freqtrade.active_pair_whitelist = ['NEO/BTC']
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.update(limit_buy_order)
     #############################################
@@ -379,6 +381,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker,
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     default_conf['stake_amount'] = 0.0000098751
+    default_conf['max_open_trades'] = 2
     mocker.patch.multiple(
         'freqtrade.exchange.Exchange',
         get_ticker=ticker,
@@ -388,7 +391,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker,
     )
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
 
     assert trade is not None
@@ -396,7 +399,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker,
     assert trade.is_open
     assert trade.open_date is not None
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.order_by(Trade.id.desc()).first()
 
     assert trade is not None
@@ -519,7 +522,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
     assert result == min(8, 2 * 2) / 0.9
 
 
-def test_create_trade(default_conf, ticker, limit_buy_order, fee, markets, mocker) -> None:
+def test_create_trades(default_conf, ticker, limit_buy_order, fee, markets, mocker) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     mocker.patch.multiple(
@@ -534,7 +537,7 @@ def test_create_trade(default_conf, ticker, limit_buy_order, fee, markets, mocke
     whitelist = deepcopy(default_conf['exchange']['pair_whitelist'])
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade is not None
@@ -552,8 +555,8 @@ def test_create_trade(default_conf, ticker, limit_buy_order, fee, markets, mocke
     assert whitelist == default_conf['exchange']['pair_whitelist']
 
 
-def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order,
-                                      fee, markets, mocker) -> None:
+def test_create_trades_no_stake_amount(default_conf, ticker, limit_buy_order,
+                                       fee, markets, mocker) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     patch_wallet(mocker, free=default_conf['stake_amount'] * 0.5)
@@ -568,11 +571,11 @@ def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order,
     patch_get_signal(freqtrade)
 
     with pytest.raises(DependencyException, match=r'.*stake amount.*'):
-        freqtrade.create_trade()
+        freqtrade.create_trades()
 
 
-def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order,
-                                     fee, markets, mocker) -> None:
+def test_create_trades_minimal_amount(default_conf, ticker, limit_buy_order,
+                                      fee, markets, mocker) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     buy_mock = MagicMock(return_value={'id': limit_buy_order['id']})
@@ -587,13 +590,13 @@ def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     rate, amount = buy_mock.call_args[1]['rate'], buy_mock.call_args[1]['amount']
     assert rate * amount >= default_conf['stake_amount']
 
 
-def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_order,
-                                             fee, markets, mocker) -> None:
+def test_create_trades_too_small_stake_amount(default_conf, ticker, limit_buy_order,
+                                              fee, markets, mocker) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     buy_mock = MagicMock(return_value={'id': limit_buy_order['id']})
@@ -609,11 +612,11 @@ def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_ord
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    assert not freqtrade.create_trade()
+    assert not freqtrade.create_trades()
 
 
-def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order,
-                                    fee, markets, mocker) -> None:
+def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order,
+                                     fee, markets, mocker) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     mocker.patch.multiple(
@@ -630,12 +633,12 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    assert not freqtrade.create_trade()
+    assert not freqtrade.create_trades()
     assert freqtrade._get_trade_stake_amount('ETH/BTC') is None
 
 
-def test_create_trade_no_pairs_let(default_conf, ticker, limit_buy_order, fee,
-                                   markets, mocker, caplog) -> None:
+def test_create_trades_no_pairs_let(default_conf, ticker, limit_buy_order, fee,
+                                    markets, mocker, caplog) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     mocker.patch.multiple(
@@ -650,13 +653,13 @@ def test_create_trade_no_pairs_let(default_conf, ticker, limit_buy_order, fee,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    assert freqtrade.create_trade()
-    assert not freqtrade.create_trade()
+    assert freqtrade.create_trades()
+    assert not freqtrade.create_trades()
     assert log_has("No currency pair in whitelist, but checking to sell open trades.", caplog)
 
 
-def test_create_trade_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee,
-                                            markets, mocker, caplog) -> None:
+def test_create_trades_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee,
+                                             markets, mocker, caplog) -> None:
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     mocker.patch.multiple(
@@ -670,11 +673,11 @@ def test_create_trade_no_pairs_in_whitelist(default_conf, ticker, limit_buy_orde
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    assert not freqtrade.create_trade()
+    assert not freqtrade.create_trades()
     assert log_has("Whitelist is empty.", caplog)
 
 
-def test_create_trade_no_signal(default_conf, fee, mocker) -> None:
+def test_create_trades_no_signal(default_conf, fee, mocker) -> None:
     default_conf['dry_run'] = True
 
     patch_RPCManager(mocker)
@@ -690,7 +693,56 @@ def test_create_trade_no_signal(default_conf, fee, mocker) -> None:
 
     Trade.query = MagicMock()
     Trade.query.filter = MagicMock()
-    assert not freqtrade.create_trade()
+    assert not freqtrade.create_trades()
+
+
+@pytest.mark.parametrize("max_open", range(0, 5))
+def test_create_trades_multiple_trades(default_conf, ticker,
+                                       fee, markets, mocker, max_open) -> None:
+    patch_RPCManager(mocker)
+    patch_exchange(mocker)
+    default_conf['max_open_trades'] = max_open
+    mocker.patch.multiple(
+        'freqtrade.exchange.Exchange',
+        get_ticker=ticker,
+        buy=MagicMock(return_value={'id': "12355555"}),
+        get_fee=fee,
+        markets=PropertyMock(return_value=markets)
+    )
+    freqtrade = FreqtradeBot(default_conf)
+    patch_get_signal(freqtrade)
+
+    freqtrade.create_trades()
+
+    trades = Trade.get_open_trades()
+    assert len(trades) == max_open
+
+
+def test_create_trades_preopen(default_conf, ticker, fee, markets, mocker) -> None:
+    patch_RPCManager(mocker)
+    patch_exchange(mocker)
+    default_conf['max_open_trades'] = 4
+    mocker.patch.multiple(
+        'freqtrade.exchange.Exchange',
+        get_ticker=ticker,
+        buy=MagicMock(return_value={'id': "12355555"}),
+        get_fee=fee,
+        markets=PropertyMock(return_value=markets)
+    )
+    freqtrade = FreqtradeBot(default_conf)
+    patch_get_signal(freqtrade)
+
+    # Create 2 existing trades
+    freqtrade.execute_buy('ETH/BTC', default_conf['stake_amount'])
+    freqtrade.execute_buy('NEO/BTC', default_conf['stake_amount'])
+
+    assert len(Trade.get_open_trades()) == 2
+
+    # Create 2 new trades using create_trades
+    assert freqtrade.create_trades()
+
+    trades = Trade.get_open_trades()
+    assert len(trades) == 4
 
 
 def test_process_trade_creation(default_conf, ticker, limit_buy_order,
@@ -711,8 +763,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order,
     trades = Trade.query.filter(Trade.is_open.is_(True)).all()
     assert not trades
 
-    result = freqtrade.process()
-    assert result is True
+    freqtrade.process()
 
     trades = Trade.query.filter(Trade.is_open.is_(True)).all()
     assert len(trades) == 1
@@ -744,8 +795,7 @@ def test_process_exchange_failures(default_conf, ticker, markets, mocker) -> Non
     worker = Worker(args=None, config=default_conf)
     patch_get_signal(worker.freqtrade)
 
-    result = worker._process()
-    assert result is False
+    worker._process()
     assert sleep_mock.has_calls()
 
 
@@ -763,8 +813,7 @@ def test_process_operational_exception(default_conf, ticker, markets, mocker) ->
 
     assert worker.state == State.RUNNING
 
-    result = worker._process()
-    assert result is False
+    worker._process()
     assert worker.state == State.STOPPED
     assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]['status']
 
@@ -786,13 +835,14 @@ def test_process_trade_handling(
 
     trades = Trade.query.filter(Trade.is_open.is_(True)).all()
     assert not trades
-    result = freqtrade.process()
-    assert result is True
+    freqtrade.process()
+
     trades = Trade.query.filter(Trade.is_open.is_(True)).all()
     assert len(trades) == 1
 
-    result = freqtrade.process()
-    assert result is False
+    # Nothing happened ...
+    freqtrade.process()
+    assert len(trades) == 1
 
 
 def test_process_trade_no_whitelist_pair(
@@ -834,11 +884,10 @@ def test_process_trade_no_whitelist_pair(
     ))
 
     assert pair not in freqtrade.active_pair_whitelist
-    result = freqtrade.process()
+    freqtrade.process()
     assert pair in freqtrade.active_pair_whitelist
     # Make sure each pair is only in the list once
     assert len(freqtrade.active_pair_whitelist) == len(set(freqtrade.active_pair_whitelist))
-    assert result is True
 
 
 def test_process_informative_pairs_added(default_conf, ticker, markets, mocker) -> None:
@@ -1078,7 +1127,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
     # Fourth case: when stoploss is set and it is hit
     # should unset stoploss_order_id and return true
     # as a trade actually happened
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.is_open = True
     trade.open_order_id = None
@@ -1153,7 +1202,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
 
     patch_get_signal(freqtrade)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.is_open = True
     trade.open_order_id = None
@@ -1243,7 +1292,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c
     # setting stoploss_on_exchange_interval to 60 seconds
     freqtrade.strategy.order_types['stoploss_on_exchange_interval'] = 60
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.is_open = True
     trade.open_order_id = None
@@ -1286,7 +1335,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
     patch_RPCManager(mocker)
     patch_exchange(mocker)
     patch_edge(mocker)
-
+    edge_conf['max_open_trades'] = float('inf')
     mocker.patch.multiple(
         'freqtrade.exchange.Exchange',
         get_ticker=MagicMock(return_value={
@@ -1324,7 +1373,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
 
     freqtrade.active_pair_whitelist = freqtrade.edge.adjust(freqtrade.active_pair_whitelist)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     trade.is_open = True
     trade.open_order_id = None
@@ -1388,21 +1437,19 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
                                                 stop_price=0.00002344 * 0.99)
 
 
-def test_process_maybe_execute_buy(mocker, default_conf) -> None:
+def test_process_maybe_execute_buy(mocker, default_conf, caplog) -> None:
     freqtrade = get_patched_freqtradebot(mocker, default_conf)
 
-    mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(return_value=True))
-    assert freqtrade.process_maybe_execute_buy()
-
-    mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(return_value=False))
-    assert not freqtrade.process_maybe_execute_buy()
+    mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trades', MagicMock(return_value=False))
+    freqtrade.process_maybe_execute_buy()
+    assert log_has('Found no buy signals for whitelisted currencies. Trying again...', caplog)
 
 
 def test_process_maybe_execute_buy_exception(mocker, default_conf, caplog) -> None:
     freqtrade = get_patched_freqtradebot(mocker, default_conf)
 
     mocker.patch(
-        'freqtrade.freqtradebot.FreqtradeBot.create_trade',
+        'freqtrade.freqtradebot.FreqtradeBot.create_trades',
         MagicMock(side_effect=DependencyException)
     )
     freqtrade.process_maybe_execute_buy()
@@ -1589,7 +1636,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -1629,7 +1676,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
     patch_get_signal(freqtrade, value=(True, True))
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     # Buy and Sell triggering, so doing nothing ...
     trades = Trade.query.all()
@@ -1638,7 +1685,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
 
     # Buy is triggering, so buying ...
     patch_get_signal(freqtrade, value=(True, False))
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trades = Trade.query.all()
     nb_trades = len(trades)
     assert nb_trades == 1
@@ -1685,7 +1732,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
     patch_get_signal(freqtrade, value=(True, False))
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.is_open = True
@@ -1717,7 +1764,7 @@ def test_handle_trade_experimental(
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.is_open = True
@@ -1745,7 +1792,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order,
     patch_get_signal(freqtrade)
 
     # Create trade and sell it
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2085,7 +2132,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2131,7 +2178,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets,
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2180,7 +2227,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2237,7 +2284,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee,
 
     freqtrade.strategy.order_types['stoploss_on_exchange'] = True
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     Trade.session = MagicMock()
@@ -2284,7 +2331,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf,
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2336,7 +2383,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf,
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     freqtrade.process_maybe_execute_sell(trade)
     assert trade
@@ -2388,7 +2435,7 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2435,7 +2482,7 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
     patch_get_signal(freqtrade)
 
     # Create some test data
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade
@@ -2491,7 +2538,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2522,7 +2569,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2553,7 +2600,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, market
     patch_get_signal(freqtrade)
     freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple(
             sell_flag=False, sell_type=SellType.NONE))
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2584,7 +2631,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2614,7 +2661,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, m
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2646,7 +2693,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog,
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
     trade = Trade.query.first()
     assert freqtrade.handle_trade(trade) is False
 
@@ -2699,7 +2746,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2757,7 +2804,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2820,7 +2867,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -2879,7 +2926,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order,
     patch_get_signal(freqtrade)
     freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     trade.update(limit_buy_order)
@@ -3136,7 +3183,7 @@ def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee,
     whitelist = deepcopy(default_conf['exchange']['pair_whitelist'])
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade is not None
@@ -3170,7 +3217,7 @@ def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_o
     # Save state of current whitelist
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade is None
@@ -3276,7 +3323,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order
     freqtrade = FreqtradeBot(default_conf)
     patch_get_signal(freqtrade)
 
-    freqtrade.create_trade()
+    freqtrade.create_trades()
 
     trade = Trade.query.first()
     assert trade