54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
from typing import List
|
|
|
|
from bfxapi import Position
|
|
|
|
from bfxbot.models import Strategy, PositionState, SymbolStatus, Event, EventKind
|
|
from bfxbot.utils import TAKER_FEE, net_pl_percentage
|
|
|
|
|
|
class TrailingStopStrategy(Strategy):
|
|
BREAK_EVEN_PERC = TAKER_FEE
|
|
MIN_PROFIT_PERC = TAKER_FEE * 2.5
|
|
GOOD_PROFIT_PERC = MIN_PROFIT_PERC * 1.5
|
|
MAX_LOSS_PERC = -3.75
|
|
OFFER_PERC = 0.01
|
|
|
|
TRAIL_STOP_PERCENTAGES = {
|
|
PositionState.MINIMUM_PROFIT: 0.27,
|
|
PositionState.PROFIT: 0.14
|
|
}
|
|
|
|
def position_on_tick(self, position: Position, ss: SymbolStatus) -> (PositionState, List[Event]):
|
|
events = []
|
|
|
|
pl_perc = net_pl_percentage(position.profit_loss_percentage, TAKER_FEE)
|
|
prev = ss.previous_position_w(position.id)
|
|
|
|
if pl_perc > self.GOOD_PROFIT_PERC:
|
|
state = PositionState.PROFIT
|
|
elif self.MIN_PROFIT_PERC <= pl_perc < self.GOOD_PROFIT_PERC:
|
|
state = PositionState.MINIMUM_PROFIT
|
|
elif 0.0 <= pl_perc < self.MIN_PROFIT_PERC:
|
|
state = PositionState.BREAK_EVEN
|
|
elif self.MAX_LOSS_PERC < pl_perc < 0.0:
|
|
state = PositionState.LOSS
|
|
else:
|
|
state = PositionState.CRITICAL
|
|
|
|
if not prev or prev.state == state:
|
|
return state, events
|
|
|
|
if state ==PositionState.PROFIT:
|
|
events.append(Event(EventKind.REACHED_GOOD_PROFIT, position.id, ss.current_tick))
|
|
elif state == PositionState.MINIMUM_PROFIT:
|
|
events.append(Event(EventKind.REACHED_MIN_PROFIT, position.id, ss.current_tick))
|
|
elif state == PositionState.BREAK_EVEN:
|
|
events.append(Event(EventKind.REACHED_BREAK_EVEN, position.id, ss.current_tick))
|
|
elif state== PositionState.LOSS:
|
|
events.append(Event(EventKind.REACHED_LOSS, position.id, ss.current_tick))
|
|
else:
|
|
events.append(Event(EventKind.REACHED_MAX_LOSS, position.id, ss.current_tick))
|
|
events.append(Event(EventKind.CLOSE_POSITION, position.id, ss.current_tick))
|
|
|
|
return state, events
|