tailwind #9
@ -1,4 +1,4 @@
|
||||
from time import sleep
|
||||
import asyncio
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from bfxapi import Order
|
||||
@ -31,20 +31,20 @@ class BfxBot:
|
||||
for s in self.symbols:
|
||||
self.__status[s] = SymbolStatus(s)
|
||||
|
||||
def __position_wrapper_from_id(self, position_id) -> Optional[Tuple[PositionWrapper, SymbolStatus]]:
|
||||
def __position_wrapper_from_id(self, position_id) -> Tuple[Optional[PositionWrapper], Optional[SymbolStatus]]:
|
||||
for s in self.__status.values():
|
||||
pw = s.active_position_wrapper_from_id(position_id)
|
||||
|
||||
if pw:
|
||||
return pw, s
|
||||
return None
|
||||
return None, None
|
||||
|
||||
async def __update_status__(self):
|
||||
active_positions = await self.__bfx.get_active_position()
|
||||
|
||||
for symbol in self.__status:
|
||||
# updating tick
|
||||
self.__status[symbol].current_tick = self.__ticker.current_tick
|
||||
self.__status[symbol].__init_tick__(self.__ticker.current_tick)
|
||||
|
||||
# updating last price
|
||||
last_price = await self.__bfx.get_current_prices(symbol)
|
||||
@ -64,11 +64,11 @@ class BfxBot:
|
||||
self.__status[symbol].add_order(o)
|
||||
|
||||
# emitting new tick event
|
||||
## TODO: handle _on_new_tick() from Strategy
|
||||
# TODO: handle _on_new_tick() from Strategy
|
||||
await self.__status[symbol].add_event(Event(EventKind.NEW_TICK, self.__ticker.current_tick))
|
||||
|
||||
async def best_position_closing_price(self, position_id: int) -> Optional[float]:
|
||||
pw: Optional[PositionWrapper] = self.__position_wrapper_from_id(position_id)
|
||||
pw, _ = self.__position_wrapper_from_id(position_id)
|
||||
|
||||
if not pw:
|
||||
return None
|
||||
@ -105,7 +105,7 @@ class BfxBot:
|
||||
|
||||
if not open_orders:
|
||||
await self.__bfx.submit_order(pw.position.symbol, closing_price, amount, Order.Type.LIMIT)
|
||||
await ss.__add_event(Event(EventKind.ORDER_SUBMITTED, ss.current_tick))
|
||||
await ss.add_event(Event(EventKind.ORDER_SUBMITTED, ss.current_tick))
|
||||
|
||||
def set_strategy(self, symbol, strategy: Strategy):
|
||||
if symbol in self.__status:
|
||||
@ -129,6 +129,6 @@ class BfxBot:
|
||||
return self.__status[symbol]
|
||||
|
||||
async def update(self):
|
||||
sleep(self.__ticker.seconds)
|
||||
await asyncio.sleep(self.__ticker.seconds)
|
||||
self.__ticker.inc()
|
||||
await self.__update_status__()
|
||||
|
@ -120,6 +120,12 @@ class SymbolStatus:
|
||||
self.current_tick: int = 1
|
||||
self.strategy: Strategy = strategy
|
||||
|
||||
def __init_tick__(self, tick: int):
|
||||
self.current_tick = tick
|
||||
self.prices[self.current_tick] = None
|
||||
self.orders[self.current_tick] = []
|
||||
self.positions[self.current_tick] = []
|
||||
|
||||
async def add_event(self, event: Event):
|
||||
self.events.append(event)
|
||||
await self.eh.call_event(self, event)
|
||||
@ -158,9 +164,10 @@ class SymbolStatus:
|
||||
return next(filter(lambda x: x.position.id == pid, self.positions[self.current_tick - 1]))
|
||||
|
||||
def active_position_wrapper_from_id(self, position_id: int) -> Optional[PositionWrapper]:
|
||||
for pw in self.positions[self.current_tick]:
|
||||
if pw.position.id == position_id:
|
||||
return pw
|
||||
if self.current_tick in self.positions:
|
||||
for pw in self.positions[self.current_tick]:
|
||||
if pw.position.id == position_id:
|
||||
return pw
|
||||
return None
|
||||
|
||||
def set_tick_price(self, tick, price):
|
||||
@ -185,7 +192,7 @@ class SymbolStatus:
|
||||
for e in events:
|
||||
if not isinstance(e, Event):
|
||||
raise ValueError
|
||||
await self.add_event__(e)
|
||||
await self.add_event(e)
|
||||
|
||||
return pw
|
||||
|
||||
|
5
main.py
5
main.py
@ -89,8 +89,9 @@ def on_connect():
|
||||
###################################
|
||||
|
||||
@btc_eh.on_event(EventKind.CLOSE_POSITION)
|
||||
def on_close_position(event: Event, _):
|
||||
loop.run_until_complete(bot.close_position(event.metadata.position_id))
|
||||
async def on_close_position(event: Event, _):
|
||||
print("CLOSING!")
|
||||
await bot.close_position(event.metadata.position_id)
|
||||
|
||||
|
||||
@btc_eh.on_position_state(PositionState.PROFIT)
|
||||
|
@ -47,7 +47,7 @@ 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
|
||||
MAX_LOSS_PERC = -4.5
|
||||
|
||||
TRAILING_STOP = SquaredTrailingStop(Point(MIN_PROFIT_PERC, MIN_PROFIT_PERC / 3 * 2), Point(GOOD_PROFIT_PERC, 0.1))
|
||||
|
||||
@ -70,6 +70,7 @@ class TrailingStopStrategy(Strategy):
|
||||
elif self.MAX_LOSS_PERC < pl_perc < 0.0:
|
||||
state = PositionState.LOSS
|
||||
else:
|
||||
events.append(Event(EventKind.CLOSE_POSITION, ss.current_tick, event_metadata))
|
||||
state = PositionState.CRITICAL
|
||||
|
||||
pw = PositionWrapper(position, state=state, net_profit_loss=position.profit_loss,
|
||||
|
Loading…
Reference in New Issue
Block a user