add feature multithreading for create trade with Dask distributed
This commit is contained in:
parent
77935b833b
commit
15d33c1478
@ -12,9 +12,10 @@ from typing import Any, Callable, Dict, List, Optional
|
|||||||
import arrow
|
import arrow
|
||||||
import requests
|
import requests
|
||||||
from cachetools import TTLCache, cached
|
from cachetools import TTLCache, cached
|
||||||
|
from dask.distributed import as_completed
|
||||||
|
|
||||||
from freqtrade import (DependencyException, OperationalException,
|
from freqtrade import (DependencyException, OperationalException,
|
||||||
TemporaryError, __version__, constants, persistence)
|
TemporaryError, __version__, constants, persistence, multithreading)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPCManager, RPCMessageType
|
from freqtrade.rpc import RPCManager, RPCMessageType
|
||||||
@ -64,6 +65,10 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
persistence.init(self.config)
|
persistence.init(self.config)
|
||||||
|
|
||||||
|
if self.config['multithreading']['enabled']:
|
||||||
|
global client
|
||||||
|
client = multithreading.init(self.config)
|
||||||
|
|
||||||
# Set initial application state
|
# Set initial application state
|
||||||
initial_state = self.config.get('initial_state')
|
initial_state = self.config.get('initial_state')
|
||||||
|
|
||||||
@ -360,6 +365,12 @@ class FreqtradeBot(object):
|
|||||||
amount_reserve_percent = max(amount_reserve_percent, 0.5)
|
amount_reserve_percent = max(amount_reserve_percent, 0.5)
|
||||||
return min(min_stake_amounts)/amount_reserve_percent
|
return min(min_stake_amounts)/amount_reserve_percent
|
||||||
|
|
||||||
|
def get_history_and_signal(self, pair, interval):
|
||||||
|
history = self.exchange.get_candle_history(pair, interval)
|
||||||
|
signal = self.strategy.get_signal(pair, interval, history)
|
||||||
|
result = {'signal': signal, 'pair': pair}
|
||||||
|
return result
|
||||||
|
|
||||||
def create_trade(self) -> bool:
|
def create_trade(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks the implemented trading indicator(s) for a randomly picked pair,
|
Checks the implemented trading indicator(s) for a randomly picked pair,
|
||||||
@ -387,6 +398,30 @@ class FreqtradeBot(object):
|
|||||||
if not whitelist:
|
if not whitelist:
|
||||||
raise DependencyException('No currency pairs in whitelist')
|
raise DependencyException('No currency pairs in whitelist')
|
||||||
|
|
||||||
|
if self.config['multithreading']['enabled']: # Multithreaded LOOP
|
||||||
|
loop_start_time = time.time()
|
||||||
|
signals = client.map(self.get_history_and_signal, whitelist, interval=interval)
|
||||||
|
for future, result in as_completed(signals, with_results=True):
|
||||||
|
(buy, sell) = result['signal']
|
||||||
|
_pair = result['pair']
|
||||||
|
if buy and not sell:
|
||||||
|
bidstrat_check_depth_of_market = self.config.get('bid_strategy', {}).\
|
||||||
|
get('check_depth_of_market', {})
|
||||||
|
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):
|
||||||
|
self.execute_buy(_pair, stake_amount)
|
||||||
|
else:
|
||||||
|
self.execute_buy(_pair, stake_amount)
|
||||||
|
|
||||||
|
client.restart() # restart workers to prevent side effects of memory leaks
|
||||||
|
|
||||||
|
total_time = (time.time() - loop_start_time)
|
||||||
|
pairs_number = len(whitelist)
|
||||||
|
print("Done gathering histories and checking signals for " + str(pairs_number) + " \
|
||||||
|
pairs of whitelist in " + str(total_time) + " seconds")
|
||||||
|
|
||||||
|
else: # Synchronous single threaded LOOP
|
||||||
# Pick pair based on buy signals
|
# Pick pair based on buy signals
|
||||||
for _pair in whitelist:
|
for _pair in whitelist:
|
||||||
thistory = self.exchange.get_candle_history(_pair, interval)
|
thistory = self.exchange.get_candle_history(_pair, interval)
|
||||||
|
18
freqtrade/multithreading.py
Normal file
18
freqtrade/multithreading.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
"""
|
||||||
|
This module contains the class to use the dask module
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Dict
|
||||||
|
from dask.distributed import Client
|
||||||
|
|
||||||
|
|
||||||
|
def init(config: Dict) -> object:
|
||||||
|
"""
|
||||||
|
Initialise Dask Distributed Client
|
||||||
|
"""
|
||||||
|
workers_number = config['multithreading']['workers_number']
|
||||||
|
client = Client(processes=False, threads_per_worker=1, n_workers=workers_number)
|
||||||
|
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
@ -127,6 +127,10 @@ def default_conf():
|
|||||||
"NEO/BTC"
|
"NEO/BTC"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"multithreading": {
|
||||||
|
"enabled": False,
|
||||||
|
"workers_number": 4
|
||||||
|
},
|
||||||
"telegram": {
|
"telegram": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"token": "token",
|
"token": "token",
|
||||||
|
11
freqtrade/tests/test_multithreading.py
Normal file
11
freqtrade/tests/test_multithreading.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from freqtrade import (multithreading)
|
||||||
|
|
||||||
|
|
||||||
|
def test_client_init():
|
||||||
|
# Check if create a Dask Client
|
||||||
|
default_conf = {}
|
||||||
|
default_conf.update({
|
||||||
|
'multithreading': {'use_multithreading': True, 'workers_number': 4}
|
||||||
|
})
|
||||||
|
client = multithreading.init(default_conf)
|
||||||
|
assert (str(type(client))) == "<class 'distributed.client.Client'>"
|
Loading…
Reference in New Issue
Block a user