Merge branch 'wohlgemuth' of https://github.com/berlinguyinca/freqtrade into wohlgemuth
This commit is contained in:
commit
39368baffd
@ -40,7 +40,7 @@ due to demand, it is possible to have a default stop loss, when you are in the r
|
||||
the system will utilize a new stop loss, which can be a different value. For example your default stop loss is 5%, but once you are in the
|
||||
black, it will be changed to be only a 1% stop loss
|
||||
|
||||
this can be configured in the main confiuration file, the following way:
|
||||
this can be configured in the main configuration file, the following way:
|
||||
|
||||
```
|
||||
"trailing_stop": {
|
||||
|
@ -62,10 +62,10 @@ class Analyze(object):
|
||||
'close': 'last',
|
||||
'volume': 'max',
|
||||
})
|
||||
frame.drop(frame.tail(1).index, inplace=True) # eliminate partial candle
|
||||
frame.drop(frame.tail(1).index, inplace=True) # eliminate partial candle
|
||||
return frame
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
|
||||
def populate_indicators(self, dataframe: DataFrame, pair: str = None) -> DataFrame:
|
||||
"""
|
||||
Adds several different TA indicators to the given DataFrame
|
||||
|
||||
@ -73,23 +73,23 @@ class Analyze(object):
|
||||
you are using. Let uncomment only the indicator you are using in your strategies
|
||||
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
|
||||
"""
|
||||
return self.strategy.populate_indicators(dataframe=dataframe)
|
||||
return self.strategy.advise_indicators(dataframe=dataframe, pair=pair)
|
||||
|
||||
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
|
||||
def populate_buy_trend(self, dataframe: DataFrame, pair: str = None) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the buy signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
return self.strategy.populate_buy_trend(dataframe=dataframe)
|
||||
return self.strategy.advise_buy(dataframe=dataframe, pair=pair)
|
||||
|
||||
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame:
|
||||
def populate_sell_trend(self, dataframe: DataFrame, pair: str = None) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the sell signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
return self.strategy.populate_sell_trend(dataframe=dataframe)
|
||||
return self.strategy.advise_sell(dataframe=dataframe, pair=pair)
|
||||
|
||||
def get_ticker_interval(self) -> str:
|
||||
"""
|
||||
@ -98,16 +98,17 @@ class Analyze(object):
|
||||
"""
|
||||
return self.strategy.ticker_interval
|
||||
|
||||
def analyze_ticker(self, ticker_history: List[Dict]) -> DataFrame:
|
||||
def analyze_ticker(self, ticker_history: List[Dict], pair: str) -> DataFrame:
|
||||
"""
|
||||
Parses the given ticker history and returns a populated DataFrame
|
||||
add several TA indicators and buy signal to it
|
||||
:return DataFrame with ticker data and indicator data
|
||||
"""
|
||||
|
||||
dataframe = self.parse_ticker_dataframe(ticker_history)
|
||||
dataframe = self.populate_indicators(dataframe)
|
||||
dataframe = self.populate_buy_trend(dataframe)
|
||||
dataframe = self.populate_sell_trend(dataframe)
|
||||
dataframe = self.populate_indicators(dataframe, pair)
|
||||
dataframe = self.populate_buy_trend(dataframe, pair)
|
||||
dataframe = self.populate_sell_trend(dataframe, pair)
|
||||
return dataframe
|
||||
|
||||
def get_signal(self, pair: str, interval: str) -> Tuple[bool, bool]:
|
||||
@ -123,7 +124,7 @@ class Analyze(object):
|
||||
return False, False
|
||||
|
||||
try:
|
||||
dataframe = self.analyze_ticker(ticker_hist)
|
||||
dataframe = self.analyze_ticker(ticker_hist, pair)
|
||||
except ValueError as error:
|
||||
logger.warning(
|
||||
'Unable to analyze ticker for pair %s: %s',
|
||||
|
@ -156,7 +156,7 @@ class FreqtradeBot(object):
|
||||
state_changed |= self.process_maybe_execute_sell(trade)
|
||||
|
||||
# Then looking for buy opportunities
|
||||
if (self.config['disable_buy']):
|
||||
if (self.config.get('disable_buy', False)):
|
||||
logger.info('Buy disabled...')
|
||||
else:
|
||||
if len(trades) < self.config['max_open_trades']:
|
||||
@ -250,7 +250,7 @@ class FreqtradeBot(object):
|
||||
balance = self.config['bid_strategy']['ask_last_balance']
|
||||
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
|
||||
|
||||
if self.config['bid_strategy']['use_book_order']:
|
||||
if self.config['bid_strategy'].get('use_book_order', False):
|
||||
logger.info('Getting price from Order Book')
|
||||
orderBook = exchange.get_order_book(pair)
|
||||
orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0]
|
||||
@ -444,14 +444,14 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
|
||||
if self.config.get('experimental', {}).get('use_sell_signal'):
|
||||
(buy, sell) = self.analyze.get_signal(trade.pair, self.analyze.get_ticker_interval())
|
||||
|
||||
if self.config['ask_strategy']['use_book_order']:
|
||||
if 'ask_strategy' in self.config and self.config['ask_strategy'].get('use_book_order', False):
|
||||
logger.info('Using order book for selling...')
|
||||
orderBook = exchange.get_order_book(trade.pair)
|
||||
# logger.debug('Order book %s',orderBook)
|
||||
orderBook_min = self.config['ask_strategy']['book_order_min']
|
||||
orderBook_max = self.config['ask_strategy']['book_order_max']
|
||||
for i in range(orderBook_min, orderBook_max+1):
|
||||
orderBook_rate = orderBook['asks'][i-1][0]
|
||||
for i in range(orderBook_min, orderBook_max + 1):
|
||||
orderBook_rate = orderBook['asks'][i - 1][0]
|
||||
# if orderbook has higher rate (high profit),
|
||||
# use orderbook, otherwise just use sell rate
|
||||
if (sell_rate < orderBook_rate):
|
||||
@ -502,7 +502,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
|
||||
ordertime = arrow.get(order['datetime']).datetime
|
||||
|
||||
# Check if trade is still actually open
|
||||
if (int(order['filled']) == 0) and (order['status'] == 'open'):
|
||||
if order['status'] == 'open':
|
||||
if order['side'] == 'buy' and ordertime < buy_timeoutthreashold:
|
||||
self.handle_timedout_limit_buy(trade, order)
|
||||
elif order['side'] == 'sell' and ordertime < sell_timeoutthreashold:
|
||||
|
@ -2,12 +2,12 @@
|
||||
IStrategy interface
|
||||
This module defines the interface to apply for strategies
|
||||
"""
|
||||
import warnings
|
||||
from typing import Dict
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from abc import ABC
|
||||
from pandas import DataFrame
|
||||
|
||||
|
||||
class IStrategy(ABC):
|
||||
"""
|
||||
Interface for freqtrade strategies
|
||||
@ -19,30 +19,71 @@ class IStrategy(ABC):
|
||||
ticker_interval -> str: value of the ticker interval to use for the strategy
|
||||
"""
|
||||
|
||||
# associated minimal roi
|
||||
minimal_roi: Dict
|
||||
|
||||
# associated stoploss
|
||||
stoploss: float
|
||||
|
||||
# associated ticker interval
|
||||
ticker_interval: str
|
||||
|
||||
@abstractmethod
|
||||
def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
|
||||
"""
|
||||
Populate indicators that will be used in the Buy and Sell strategy
|
||||
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
|
||||
:return: a Dataframe with all mandatory indicators for the strategies
|
||||
"""
|
||||
warnings.warn("deprecated - please replace this method with advise_indicators!", DeprecationWarning)
|
||||
return dataframe
|
||||
|
||||
@abstractmethod
|
||||
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the buy signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
warnings.warn("deprecated - please replace this method with advise_buy!", DeprecationWarning)
|
||||
dataframe.loc[(), 'buy'] = 0
|
||||
return dataframe
|
||||
|
||||
@abstractmethod
|
||||
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the sell signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with sell column
|
||||
"""
|
||||
warnings.warn("deprecated - please replace this method with advise_sell!", DeprecationWarning)
|
||||
dataframe.loc[(), 'sell'] = 0
|
||||
return dataframe
|
||||
|
||||
def advise_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
|
||||
"""
|
||||
|
||||
This wraps around the internal method
|
||||
|
||||
Populate indicators that will be used in the Buy and Sell strategy
|
||||
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
|
||||
:param pair: The currently traded pair
|
||||
:return: a Dataframe with all mandatory indicators for the strategies
|
||||
"""
|
||||
return self.populate_indicators(dataframe)
|
||||
|
||||
def advise_buy(self, dataframe: DataFrame, pair: str) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the buy signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:param pair: The currently traded pair
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
|
||||
return self.populate_buy_trend(dataframe)
|
||||
|
||||
def advise_sell(self, dataframe: DataFrame, pair: str) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the sell signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:param pair: The currently traded pair
|
||||
:return: DataFrame with sell column
|
||||
"""
|
||||
return self.populate_sell_trend(dataframe)
|
||||
|
@ -40,6 +40,7 @@ class StrategyResolver(object):
|
||||
self.strategy: IStrategy = self._load_strategy(strategy_name,
|
||||
extra_dir=config.get('strategy_path'))
|
||||
|
||||
|
||||
# Set attributes
|
||||
# Check if we need to override configuration
|
||||
if 'minimal_roi' in config:
|
||||
@ -125,7 +126,7 @@ class StrategyResolver(object):
|
||||
|
||||
strategy_name = os.path.splitext(name)[0]
|
||||
|
||||
print("stored downloaded stat at: {}".format(temp))
|
||||
# print("stored downloaded stat at: {}".format(temp))
|
||||
# register temp path with the bot
|
||||
abs_paths.insert(0, temp.absolute())
|
||||
|
||||
|
@ -16,7 +16,7 @@ def load_dataframe_pair(pairs):
|
||||
dataframe = ld[pairs[0]]
|
||||
|
||||
analyze = Analyze({'strategy': 'DefaultStrategy'})
|
||||
dataframe = analyze.analyze_ticker(dataframe)
|
||||
dataframe = analyze.analyze_ticker(dataframe, pairs[0])
|
||||
return dataframe
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user