Post log messages to Matrix #6
@ -4,3 +4,8 @@ KRAKEN_API_SEC =
|
|||||||
R_VALUE_TARGET =
|
R_VALUE_TARGET =
|
||||||
INVESTMENT_COUNT =
|
INVESTMENT_COUNT =
|
||||||
INVESTMENT_VOLUME =
|
INVESTMENT_VOLUME =
|
||||||
|
LOG_LEVEL =
|
||||||
|
MATRIX_HOMESERVER_ADDRESS =
|
||||||
|
MATRIX_USER_ID =
|
||||||
|
MATRIX_USER_PASSWORD =
|
||||||
|
MATRIX_ROOM_ID =
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
# Kraken bot
|
||||||
|
|
||||||
|
A Python bot for day-trading cryptocurrencies on the Kraken exchange.
|
29
app.py
29
app.py
@ -1,32 +1,19 @@
|
|||||||
import logging
|
import asyncio
|
||||||
import os
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from kraken_bot.KrakenBot import KrakenBot
|
from kraken_bot.KrakenBot import KrakenBot
|
||||||
from kraken_bot.LinearRegression import LinearRegression
|
from kraken_bot.LinearRegression import LinearRegression
|
||||||
from kraken_bot.HighLowCutoff import HighLowCutoff
|
from kraken_bot.MyStrategy import MyStrategy
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
model = LinearRegression(
|
|
||||||
r_value_target = float(os.getenv('R_VALUE_TARGET'))
|
|
||||||
)
|
|
||||||
strategy = HighLowCutoff(
|
|
||||||
investment_count = int(os.getenv('INVESTMENT_COUNT')),
|
|
||||||
investment_volume = float(os.getenv('INVESTMENT_VOLUME')),
|
|
||||||
target_gain = float(os.getenv('TARGET_GAIN')),
|
|
||||||
max_loss = float(os.getenv('MAX_LOSS'))
|
|
||||||
)
|
|
||||||
bot = KrakenBot(
|
bot = KrakenBot(
|
||||||
token = os.getenv('KRAKEN_API_TOKEN'),
|
|
||||||
secret = os.getenv('KRAKEN_API_SEC'),
|
|
||||||
tier = 'Pro',
|
tier = 'Pro',
|
||||||
model = model,
|
model = LinearRegression(),
|
||||||
trading_strategy = strategy
|
trading_strategy = MyStrategy()
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bot.update(full=True)
|
asyncio.run(bot.update(full=True))
|
||||||
bot.execute()
|
asyncio.run(bot.execute())
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import krakenex
|
import krakenex
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import scipy
|
import scipy
|
||||||
import sys
|
import sys
|
||||||
@ -7,16 +6,14 @@ import time
|
|||||||
|
|
||||||
from pykrakenapi import KrakenAPI
|
from pykrakenapi import KrakenAPI
|
||||||
|
|
||||||
|
from kraken_bot.MatrixLogger import MatrixLogger
|
||||||
|
|
||||||
class KrakenBot(KrakenAPI):
|
class KrakenBot(KrakenAPI):
|
||||||
def __init__(self, token, secret, tier, model, trading_strategy):
|
def __init__(self, tier, model, trading_strategy):
|
||||||
self.model = model
|
self.model = model
|
||||||
self.trading_strategy = trading_strategy
|
self.trading_strategy = trading_strategy
|
||||||
self.log = logging.getLogger(__name__)
|
self.log = MatrixLogger(str(self.__class__.__name__))
|
||||||
self.log.setLevel(
|
super().__init__(krakenex.API(os.getenv('KRAKEN_API_TOKEN'), os.getenv('KRAKEN_API_SEC')), tier=tier)
|
||||||
getattr(logging, os.getenv('LOG_LEVEL', 'INFO'), logging.INFO)
|
|
||||||
)
|
|
||||||
self.log.addHandler(logging.StreamHandler(sys.stdout))
|
|
||||||
super().__init__(krakenex.API(token, secret), tier=tier)
|
|
||||||
self.update(full=True)
|
self.update(full=True)
|
||||||
|
|
||||||
def _delay_factor(self):
|
def _delay_factor(self):
|
||||||
@ -75,7 +72,7 @@ class KrakenBot(KrakenAPI):
|
|||||||
order.ordertype, order.type, order.pair, order.userref, order.volume, order.price, order.price2, order.trigger,
|
order.ordertype, order.type, order.pair, order.userref, order.volume, order.price, order.price2, order.trigger,
|
||||||
order.leverage, order.oflags, order.timeinforce, order.starttm, order.expiretm, order.close_ordertype,
|
order.leverage, order.oflags, order.timeinforce, order.starttm, order.expiretm, order.close_ordertype,
|
||||||
order.close_price, order.close_price2, order.deadline, order.validate, order.otp)
|
order.close_price, order.close_price2, order.deadline, order.validate, order.otp)
|
||||||
self.log.info(order)
|
self.log.info(f"Added order to %{order.type} %{order.volume} on {order.pair}")
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def update(self, full=False):
|
def update(self, full=False):
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import pandas
|
import pandas
|
||||||
|
|
||||||
from kraken_bot.Model import Model
|
|
||||||
from scipy.stats import linregress
|
from scipy.stats import linregress
|
||||||
|
|
||||||
|
from kraken_bot.Model import Model
|
||||||
|
|
||||||
class LinearRegression(Model):
|
class LinearRegression(Model):
|
||||||
def __init__(self, r_value_target):
|
def __init__(self):
|
||||||
self.r_value_target = r_value_target
|
self.r_value_target = float(os.getenv('R_VALUE_TARGET'))
|
||||||
self.log = logging.getLogger(__name__)
|
|
||||||
self.log.setLevel(
|
|
||||||
getattr(logging, os.getenv('LOG_LEVEL', 'INFO'), logging.INFO)
|
|
||||||
)
|
|
||||||
self.analysis = pandas.DataFrame({})
|
self.analysis = pandas.DataFrame({})
|
||||||
super().__init__(
|
super().__init__(
|
||||||
interval = 1,
|
interval = 1,
|
||||||
@ -54,5 +50,4 @@ class LinearRegression(Model):
|
|||||||
) for asset_pair in self._filter_asset_pairs(tradable_asset_pairs).index
|
) for asset_pair in self._filter_asset_pairs(tradable_asset_pairs).index
|
||||||
}).transpose()
|
}).transpose()
|
||||||
))
|
))
|
||||||
self.log.info(f"Completed linear regression analysis of OHLC market data")
|
self.log.debug(self.analysis)
|
||||||
self.log.info(self.analysis)
|
|
||||||
|
62
kraken_bot/MatrixLogger.py
Normal file
62
kraken_bot/MatrixLogger.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from nio import AsyncClient, MatrixRoom, RoomMessageText
|
||||||
|
|
||||||
|
class MatrixHandler(logging.Handler):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
eric marked this conversation as resolved
Outdated
|
|||||||
|
self.address = os.getenv('MATRIX_HOMESERVER_ADDRESS')
|
||||||
|
self.user_id = os.getenv('MATRIX_USER_ID')
|
||||||
|
self.user_password = os.getenv('MATRIX_USER_PASSWORD')
|
||||||
|
self.room_id = os.getenv('MATRIX_ROOM_ID')
|
||||||
|
self.device_id = os.getenv('MATRIX_DEVICE_ID')
|
||||||
|
|
||||||
|
def message_callback(self, room: MatrixRoom, event: RoomMessageText) -> None:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def send_to_matrix(self, record):
|
||||||
|
client = AsyncClient(self.address, self.user_id)
|
||||||
|
await client.login(self.user_password, self.device_id)
|
||||||
|
client.add_event_callback(self.message_callback, RoomMessageText)
|
||||||
|
await client.room_send(
|
||||||
|
self.room_id,
|
||||||
|
message_type='m.room.message',
|
||||||
|
content={'msgtype': 'm.text', 'body': self.formatter.format(record)}
|
||||||
|
)
|
||||||
|
|
||||||
|
def emit(self, record):
|
||||||
|
asyncio.run(self.send_to_matrix(record))
|
||||||
|
|
||||||
|
class MatrixLogger:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.log = logging.getLogger(name)
|
||||||
|
self.log.setLevel(os.getenv('LOG_LEVEL', 'INFO'))
|
||||||
|
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(os.getenv('LOG_LEVEL', 'INFO'))
|
||||||
|
console_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s'))
|
||||||
|
|
||||||
|
matrix_handler = MatrixHandler()
|
||||||
|
matrix_handler.setLevel(os.getenv('LOG_LEVEL', 'INFO'))
|
||||||
|
matrix_handler.setFormatter(logging.Formatter('%(levelname)s - %(name)s - %(message)s'))
|
||||||
|
|
||||||
|
self.log.addHandler(console_handler)
|
||||||
|
self.log.addHandler(matrix_handler)
|
||||||
|
|
||||||
|
def debug(self, message):
|
||||||
|
self.log.debug(message)
|
||||||
|
|
||||||
|
def info(self, message):
|
||||||
|
self.log.info(message)
|
||||||
|
|
||||||
|
def warning(self, message):
|
||||||
|
self.log.warning(message)
|
||||||
|
|
||||||
|
def error(self, message):
|
||||||
|
self.log.error(message)
|
||||||
|
|
||||||
|
def critical(self, message):
|
||||||
|
self.log.critical(message)
|
||||||
|
|
@ -1,9 +1,12 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
from kraken_bot.MatrixLogger import MatrixLogger
|
||||||
|
|
||||||
class Model(ABC):
|
class Model(ABC):
|
||||||
def __init__(self, interval, ascending):
|
def __init__(self, interval, ascending):
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
self.ascending = ascending
|
self.ascending = ascending
|
||||||
|
self.log = MatrixLogger(self.__class__.__name__)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def since():
|
def since():
|
||||||
|
@ -2,8 +2,8 @@ from kraken_bot.TradingStrategy import TradingStrategy
|
|||||||
from kraken_bot.KrakenOrder import KrakenOrder
|
from kraken_bot.KrakenOrder import KrakenOrder
|
||||||
|
|
||||||
class MyStrategy(TradingStrategy):
|
class MyStrategy(TradingStrategy):
|
||||||
def __init__(self, investment_count, investment_volume):
|
def __init__(self):
|
||||||
super().__init__(investment_count, investment_volume)
|
super().__init__()
|
||||||
|
|
||||||
def update(self, tradable_asset_pairs, ohlc_data, market_analysis, account_balance):
|
def update(self, tradable_asset_pairs, ohlc_data, market_analysis, account_balance):
|
||||||
self.orders = []
|
self.orders = []
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from kraken_bot.KrakenOrder import KrakenOrder
|
|
||||||
|
from kraken_bot.MatrixLogger import MatrixLogger
|
||||||
|
|
||||||
class TradingStrategy(ABC):
|
class TradingStrategy(ABC):
|
||||||
def __init__(self, investment_count, investment_volume):
|
def __init__(self):
|
||||||
self.investment_count = investment_count
|
self.investment_count = int(os.getenv('INVESTMENT_COUNT'))
|
||||||
self.investment_volume = investment_volume
|
self.investment_volume = float(os.getenv('INVESTMENT_VOLUME'))
|
||||||
|
self.log = MatrixLogger(self.__class__.__name__)
|
||||||
self.orders = []
|
self.orders = []
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
krakenex
|
krakenex
|
||||||
|
matrix-nio
|
||||||
pykrakenapi
|
pykrakenapi
|
||||||
python-dotenv
|
python-dotenv
|
||||||
|
scipy
|
||||||
backtrader
|
backtrader
|
||||||
matplotlib
|
matplotlib
|
||||||
|
Loading…
Reference in New Issue
Block a user
AsyncClient
will need to be executed like so:As such, it will need to be instantiated and started elsewhere with the necessary values passed in via parameters.
The
HttpClient
was used instead. Fortunately, the interface was compatible.This is still an issue. The Matrix logger likely needs to be redesigned.