tailwind #9
84
main.py
84
main.py
@ -485,92 +485,34 @@
|
||||
# if __name__ == "__main__":
|
||||
# asyncio.run(Screen.wrapper(main))
|
||||
import asyncio
|
||||
from typing import List
|
||||
import os
|
||||
|
||||
from bfxapi import Position
|
||||
import dotenv
|
||||
|
||||
from bfxbot import BfxBot
|
||||
import dotenv
|
||||
import os
|
||||
import bfxapi
|
||||
|
||||
from bfxbot.currency import Symbol
|
||||
from bfxbot.models import Strategy, SymbolStatus, PositionState, Event, EventKind
|
||||
from bfxbot.utils import TAKER_FEE, net_pl_percentage
|
||||
from bfxbot.models import PositionState
|
||||
from strategy import TrailingStopStrategy
|
||||
|
||||
dotenv.load_dotenv()
|
||||
API_KEY = os.getenv("API_KEY")
|
||||
API_SECRET = os.getenv("API_SECRET")
|
||||
|
||||
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
|
||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET)
|
||||
strategy = TrailingStopStrategy()
|
||||
bot.set_strategy(Symbol.BTC, strategy)
|
||||
eh = bot.event_handler(Symbol.BTC)
|
||||
|
||||
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
|
||||
@eh.on_state(PositionState.PROFIT)
|
||||
def on_min_profit(ss, pw):
|
||||
print("Minimum profit!")
|
||||
|
||||
async def main():
|
||||
API_KEY = os.getenv("API_KEY")
|
||||
API_SECRET = os.getenv("API_SECRET")
|
||||
|
||||
if API_KEY == None:
|
||||
print("API_KEY is not set! Set the var in the .env file.")
|
||||
return
|
||||
|
||||
if API_SECRET == None:
|
||||
print("API_SECRET is not set! Set the var in the .env file.")
|
||||
return
|
||||
|
||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET)
|
||||
strategy = TrailingStopStrategy()
|
||||
bot.set_strategy(Symbol.BTC, strategy)
|
||||
|
||||
await bot.start()
|
||||
|
||||
eh = bot.event_handler(Symbol.BTC)
|
||||
|
||||
while True:
|
||||
print("WAITING...")
|
||||
await bot.update()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
93
strategy.py
Normal file
93
strategy.py
Normal file
@ -0,0 +1,93 @@
|
||||
from typing import List
|
||||
|
||||
import sympy.abc
|
||||
from sympy import Point, solve
|
||||
|
||||
from bfxbot.models import Strategy, PositionState, SymbolStatus, Event, EventKind
|
||||
from bfxbot.utils import TAKER_FEE, net_pl_percentage
|
||||
|
||||
|
||||
class Position(object):
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.profit_loss_percentage = None
|
||||
|
||||
pass
|
||||
|
||||
class SquaredTrailingStop:
|
||||
def __init__(self, p_min: Point, p_max: Point):
|
||||
a = sympy.abc.a
|
||||
b = sympy.abc.b
|
||||
c = sympy.abc.c
|
||||
|
||||
self.p_min = p_min
|
||||
self.p_max = p_max
|
||||
|
||||
e1 = 2 * a * (p_max.x + b)
|
||||
e2 = a * (p_min.x + b)**2 + c - p_min.y
|
||||
e3 = a * (p_max.x + b)**2 + c - p_max.y
|
||||
|
||||
s = solve([e1, e2, e3])[0]
|
||||
|
||||
self.a, self.b, self.c = s[a], s[b], s[c]
|
||||
|
||||
def y(self, x):
|
||||
def inter_y(x):
|
||||
return self.a * (x + self.b)**2 + self.c
|
||||
|
||||
if x < self.p_min.x:
|
||||
return self.p_min.y
|
||||
elif x > self.p_max.x:
|
||||
return self.p_max.y
|
||||
else:
|
||||
return inter_y(x)
|
||||
|
||||
def profit(self, x):
|
||||
if x < self.p_min.x:
|
||||
return 0
|
||||
return x - self.y(x)
|
||||
|
||||
class TrailingStopStrategy(Strategy):
|
||||
BREAK_EVEN_PERC = TAKER_FEE
|
||||
MIN_PROFIT_PERC = BREAK_EVEN_PERC + 0.3
|
||||
GOOD_PROFIT_PERC = MIN_PROFIT_PERC * 2.5
|
||||
MAX_LOSS_PERC = -3.75
|
||||
OFFER_PERC = 0.005
|
||||
|
||||
TRAILING_STOP = SquaredTrailingStop(Point(MIN_PROFIT_PERC, MIN_PROFIT_PERC/3*2), Point(GOOD_PROFIT_PERC, 0.1))
|
||||
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user