diff --git a/app.py b/app.py index 44b4cfb..8e11687 100644 --- a/app.py +++ b/app.py @@ -3,23 +3,28 @@ import os from kraken_bot.KrakenBot import KrakenBot from kraken_bot.LinearRegression import LinearRegression +from kraken_bot.MyStrategy import MyStrategy from dotenv import load_dotenv load_dotenv() logger = logging.getLogger(__name__) +model = LinearRegression( + r_value_target = float(os.getenv('R_VALUE_TARGET')) + ) +strategy = MyStrategy( + investment_count = int(os.getenv('INVESTMENT_COUNT')), + investment_volume = float(os.getenv('INVESTMENT_VOLUME')) + ) bot = KrakenBot( token = os.getenv('KRAKEN_API_TOKEN'), secret = os.getenv('KRAKEN_API_SEC'), tier = 'Pro', - investment_count = int(os.getenv('INVESTMENT_COUNT')), - investment_volume = float(os.getenv('INVESTMENT_VOLUME')) - ) -model = LinearRegression( - r_value_target = float(os.getenv('R_VALUE_TARGET')) + model = model, + trading_strategy = strategy ) if __name__ == '__main__': - bot.update() - bot.trade(model) + bot.update(full=True) + bot.execute() diff --git a/kraken_bot/KrakenBot.py b/kraken_bot/KrakenBot.py index 18770ef..41010f3 100644 --- a/kraken_bot/KrakenBot.py +++ b/kraken_bot/KrakenBot.py @@ -7,62 +7,15 @@ import time from pykrakenapi import KrakenAPI class KrakenBot(KrakenAPI): - class KrakenOrder(): - def __init__(self, ordertype, type, pair, userref=None, volume=None, price=None, price2=None, trigger=None, leverage=None, - oflags=None, timeinforce=None, starttm=0, expiretm=0, close_ordertype=None, close_price=None, close_price2=None, - deadline=None, validate=True, otp=None): - self.ordertype = ordertype - self.type = type - self.pair = pair - self.userref = userref - self.volume = volume - self.price = price - self.price2 = price2 - self.trigger = trigger - self.leverage = leverage - self.oflags = oflags - self.timeinforce = timeinforce - self.starttm = starttm - self.expiretm = expiretm - self.close_ordertype = close_ordertype - self.close_price = close_price - self.close_price2 = close_price2 - self.deadline = deadline - self.validate = validate - self.otp = otp - - def __str__(self): - return str({ - 'ordertype': self.ordertype, - 'type': self.type, - 'pair': self.pair, - 'userref': self.userref, - 'volume': self.volume, - 'price': self.price, - 'price2': self.price2, - 'trigger': self.trigger, - 'leverage': self.leverage, - 'oflags': self.oflags, - 'timeinforce': self.timeinforce, - 'starttm': self.starttm, - 'expiretm': self.expiretm, - 'close_ordertype': self.close_ordertype, - 'close_price': self.close_price, - 'close_price2': self.close_price2, - 'deadline': self.deadline, - 'validate': self.validate, - 'otp': self.otp - }) - - def __init__(self, token, secret, tier, investment_count, investment_volume): - self.investment_count = investment_count - self.investment_volume = investment_volume + def __init__(self, token, secret, tier, model, trading_strategy): + self.model = model + self.trading_strategy = trading_strategy self.log = logging.getLogger(__name__) self.log.setLevel( getattr(logging, os.getenv('LOG_LEVEL', 'INFO'), logging.INFO) ) super().__init__(krakenex.API(token, secret), tier=tier) - self.update() + self.update(full=True) def _delay_factor(self): self.log.debug(f"_delay_factor") @@ -74,12 +27,26 @@ class KrakenBot(KrakenAPI): self._delay_factor() self.tradable_asset_pairs = self.get_tradable_asset_pairs(info, pair) + def _filter_tradable_asset_pairs(self): + self.log.debug(f"_filter_tradable_asset_pairs") + self.tradable_asset_pairs = self.tradable_asset_pairs[ + (self.tradable_asset_pairs.quote == 'ZUSD') & + (self.tradable_asset_pairs.status == 'online') + ] + def _update_account_balance(self, otp=None): - self.log.debug(f"update_account_balance: otp={otp}") + self.log.debug(f"_update_account_balance: otp={otp}") self._delay_factor() self.account_balance = self.get_account_balance(otp) self.log.debug(self.account_balance) + def _filter_account_balance(self): + self.log.debug(f"_filter_account_balance") + self.account_balance = self.account_balance[ + (self.account_balance.vol > 0) + ] + self.log.debug(self.account_balance) + def _update_trade_balance(self, aclass='currency', asset='ZUSD', otp=None): self.log.debug(f"update_trade_balance: aclass={aclass}, asset={asset}, otp={otp}") self._delay_factor() @@ -91,6 +58,14 @@ class KrakenBot(KrakenAPI): self._delay_factor() return self.get_ohlc_data(pair, interval, since, ascending) + def _update_ohlc_data(self): + self.log.debug(f"_update_ohlc_data") + self.ohlc_data = { + asset_pair: self._get_ohlc_data( + asset_pair, self.model.interval, self.model.since(), self.model.ascending + ) for asset_pair in self.tradable_asset_pairs.index + } + def _add_standard_order(self, order): self.log.debug(f"add_standard_order: order={order}") self._delay_factor() @@ -101,46 +76,27 @@ class KrakenBot(KrakenAPI): self.log.info(order) self.update() - def update(self): - self.log.debug(f"update") + def update(self, full=False): + self.log.debug(f"update: full={full}") self._update_tradable_asset_pairs() + self._filter_tradable_asset_pairs() self._update_account_balance() + self._filter_account_balance() self._update_trade_balance() + if full: + self._update_ohlc_data() + self.model.update( + self.tradable_asset_pairs, + self.ohlc_data + ) + self.trading_strategy.update( + self.tradable_asset_pairs, + self.ohlc_data, + self.model.analysis, + self.account_balance + ) - def trade(self, model): - self.log.debug(f"trade") - model.update( - self.tradable_asset_pairs, - { - asset_pair: self._get_ohlc_data( - asset_pair, model.interval, model.since(), model.ascending - ) for asset_pair in self.tradable_asset_pairs.index - } - ) - for asset in self.account_balance[(self.account_balance.index != 'ZUSD') & (self.account_balance.vol > 0)].index: - market = self.tradable_asset_pairs[ - (self.tradable_asset_pairs.base == asset) & - (self.tradable_asset_pairs.quote == 'ZUSD') - ].iloc[0] - if market.altname not in model.analysis.index: - self._add_standard_order(self.KrakenOrder( - ordertype = 'market', - type = 'sell', - pair = market.altname, - volume = self.account_balance.loc[asset].vol, - validate = False - )) - while ((len(self.account_balance[self.account_balance.vol > 0]) - 1 < self.investment_count) & - (self.account_balance.loc['ZUSD'].vol > self.investment_volume)): - for market in model.analysis.index: - if self.tradable_asset_pairs.loc[market].base not in self.account_balance[self.account_balance.vol > 0].index: - ohlc, last = self._get_ohlc_data(market) - volume = self.investment_volume / ohlc.iloc[-1].close - self._add_standard_order(self.KrakenOrder( - ordertype = 'market', - type = 'buy', - pair = market, - volume = volume, - validate = False - )) - break + def execute(self): + self.log.debug(f"execute") + for order in self.trading_strategy.orders: + self._add_standard_order(order) diff --git a/kraken_bot/KrakenOrder.py b/kraken_bot/KrakenOrder.py index 3817f17..e58a0db 100644 --- a/kraken_bot/KrakenOrder.py +++ b/kraken_bot/KrakenOrder.py @@ -1,6 +1,6 @@ class KrakenOrder(): def __init__(self, ordertype, type, pair, userref=None, volume=None, price=None, price2=None, trigger=None, leverage=None, - oflags=None, timeinforce=None, starttm=0, expiretm=0, closeordertype=None, close_price=None, close_price2=None, + oflags=None, timeinforce=None, starttm=0, expiretm=0, close_ordertype=None, close_price=None, close_price2=None, deadline=None, validate=True, otp=None): self.ordertype = ordertype self.type = type @@ -15,32 +15,33 @@ class KrakenOrder(): self.timeinforce = timeinforce self.starttm = starttm self.expiretm = expiretm - self.closeordertype = closeordertype + self.close_ordertype = close_ordertype self.close_price = close_price - self.close_price2 = clowe_price2 + self.close_price2 = close_price2 self.deadline = deadline self.validate = validate self.otp = otp def __str__(self): return str({ - 'ordertype': self.ordertype - 'type': self.type - 'pair': self.pair - 'userref': self.userref - 'volume': self.volume - 'price': self.price - 'price2': self.price2 - 'trigger': self.trigger - 'leverage': self.leverage - 'oflags': self.oflags - 'timeinforce': self.timeinforce - 'starttm': self.starttm - 'expiretm': self.expiretm - 'closeordertype': self.closeordertype - 'close_price': self.close_price - 'close_price2': self.clowe_price2 - 'deadline': self.deadline - 'validate': self.validate + 'ordertype': self.ordertype, + 'type': self.type, + 'pair': self.pair, + 'userref': self.userref, + 'volume': self.volume, + 'price': self.price, + 'price2': self.price2, + 'trigger': self.trigger, + 'leverage': self.leverage, + 'oflags': self.oflags, + 'timeinforce': self.timeinforce, + 'starttm': self.starttm, + 'expiretm': self.expiretm, + 'close_ordertype': self.close_ordertype, + 'close_price': self.close_price, + 'close_price2': self.close_price2, + 'deadline': self.deadline, + 'validate': self.validate, 'otp': self.otp }) + diff --git a/kraken_bot/MyStrategy.py b/kraken_bot/MyStrategy.py new file mode 100644 index 0000000..059f712 --- /dev/null +++ b/kraken_bot/MyStrategy.py @@ -0,0 +1,41 @@ +from kraken_bot.TradingStrategy import TradingStrategy +from kraken_bot.KrakenOrder import KrakenOrder + +class MyStrategy(TradingStrategy): + def __init__(self, investment_count, investment_volume): + super().__init__(investment_count, investment_volume) + + def update(self, tradable_asset_pairs, ohlc_data, market_analysis, account_balance): + self.orders = [] + investment_count = len(account_balance) - 1 + for asset in account_balance[(account_balance.index != 'ZUSD')].index: + market = tradable_asset_pairs[ + (tradable_asset_pairs.base == asset) & + (tradable_asset_pairs.quote == 'ZUSD') + ].iloc[0] + if market.altname not in market_analysis.index: + self.orders.append(KrakenOrder( + ordertype = 'market', + type = 'sell', + pair = market.altname, + volume = account_balance.loc[asset].vol, + validate = False + )) + investment_count -= 1 + new_investments = [] + while investment_count < self.investment_count: + for market in market_analysis.index: + base = tradable_asset_pairs.loc[market].base + if base not in account_balance.index and base not in new_investments: + ohlc, last = ohlc_data[market] + volume = self.investment_volume / ohlc.iloc[-2].close + self.orders.append(KrakenOrder( + ordertype = 'market', + type = 'buy', + pair = market, + volume = volume, + validate = False + )) + new_investments.append(base) + investment_count += 1 + break diff --git a/kraken_bot/TradingStrategy.py b/kraken_bot/TradingStrategy.py new file mode 100644 index 0000000..1b48089 --- /dev/null +++ b/kraken_bot/TradingStrategy.py @@ -0,0 +1,12 @@ +from abc import ABC, abstractmethod +from kraken_bot.KrakenOrder import KrakenOrder + +class TradingStrategy(ABC): + def __init__(self, investment_count, investment_volume): + self.investment_count = investment_count + self.investment_volume = investment_volume + self.orders = [] + + @abstractmethod + def update(self, tradable_asset_pairs, ohlc_data, market_analysis, account_balance): + pass