Merge remote-tracking branch 'origin/StopLossSupport' into wohlgemuth

This commit is contained in:
Gert Wohlgemuth 2018-05-11 14:30:13 -07:00
commit b9dcb100d3
2 changed files with 68 additions and 2 deletions

View File

@ -14,7 +14,6 @@ from freqtrade.exchange import get_ticker_history
from freqtrade.persistence import Trade
from freqtrade.strategy.resolver import StrategyResolver
logger = logging.getLogger(__name__)
@ -31,6 +30,7 @@ class Analyze(object):
Analyze class contains everything the bot need to determine if the situation is good for
buying or selling.
"""
def __init__(self, config: dict) -> None:
"""
Init Analyze
@ -195,10 +195,29 @@ class Analyze(object):
:return True if bot should sell at current rate
"""
current_profit = trade.calc_profit_percent(current_rate)
if self.strategy.stoploss is not None and current_profit < self.strategy.stoploss:
if trade.stop_loss is None:
# initially adjust the stop loss to the base value
trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss)
# evaluate if the stoploss was hit
if self.strategy.stoploss is not None and trade.stop_loss >= current_rate:
# just for debugging
if 'trailing_stop' in self.config and self.config['trailing_stop']:
print(
"HIT STOP: current price at {:.6f}, stop loss is {:.6f}, "
"initial stop loss was at {:.6f}, trade opened at {:.6f}".format(
current_rate, trade.stop_loss, trade.initial_stop_loss, trade.open_rate))
print("trailing stop saved us: {:.6f}".format(trade.stop_loss - trade.initial_stop_loss))
logger.debug('Stop loss hit.')
return True
# update the stop loss afterwards, after all by definition it's supposed to be hanging
if 'trailing_stop' in self.config and self.config['trailing_stop']:
trade.adjust_stop_loss(current_rate, self.strategy.stoploss)
# Check if time matches and current rate is above threshold
time_diff = (current_time.timestamp() - trade.open_date.timestamp()) / 60
for duration, threshold in self.strategy.minimal_roi.items():

View File

@ -95,6 +95,9 @@ class Trade(_DECL_BASE):
open_date = Column(DateTime, nullable=False, default=datetime.utcnow)
close_date = Column(DateTime)
open_order_id = Column(String)
stop_loss = Column(Float, nullable=False, default=0.0) # absolute value of the stop loss
initial_stop_loss = Column(Float, nullable=False, default=0.0) # absolute value of the initial stop loss
max_rate = Column(Float, nullable=False, default=0.0) # absolute value of the highest reached price
def __repr__(self):
return 'Trade(id={}, pair={}, amount={:.8f}, open_rate={:.8f}, open_since={})'.format(
@ -105,6 +108,50 @@ class Trade(_DECL_BASE):
arrow.get(self.open_date).humanize() if self.is_open else 'closed'
)
def adjust_stop_loss(self, current_price, stoploss):
"""
this adjusts the stop loss to it's most recently observed
setting
:param current_price:
:param stoploss:
:return:
"""
new_loss = Decimal(current_price * (1 - abs(stoploss)))
# keeping track of the highest observed rate for this trade
if self.max_rate is None:
self.max_rate = current_price
else:
if current_price > self.max_rate:
self.max_rate = current_price
# no stop loss assigned yet
if self.stop_loss is None:
logger.debug("assigning new stop loss")
self.stop_loss = new_loss
self.initial_stop_loss = new_loss
# evaluate if the stop loss needs to be updated
else:
if new_loss > self.stop_loss: # stop losses only walk up, never down!
self.stop_loss = new_loss
logger.debug("adjusted stop loss")
else:
logger.debug("keeping current stop loss")
print(
"{} - current price {:.6f}, bought at {:.6f} and calculated "
"stop loss is at: {:.6f} initial stop at {:.6f}. trailing stop loss saved us: {:.6f} "
"and max observed rate was {:.6f}".format(
self.pair, current_price, self.open_rate,
self.initial_stop_loss,
self.stop_loss, self.stop_loss - self.initial_stop_loss,
self.max_rate
))
def update(self, order: Dict) -> None:
"""
Updates this entity with amount and actual open/close rates.