Skip to content

Commit

Permalink
improve notification logic
Browse files Browse the repository at this point in the history
  • Loading branch information
asavinov committed Sep 30, 2023
1 parent b276675 commit 382cd03
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 43 deletions.
5 changes: 4 additions & 1 deletion configs/config-sample-v0.6.dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@
"buy_notify_threshold": 0.1,
"sell_notify_threshold": -0.1,
"trade_icon_step": 0.05,
"notify_frequency_minutes": 1
"notify_frequency_minutes": 1,
"notify_signal": true,
"notify_transaction": true,
"notify_diagram": false
}
},

Expand Down
2 changes: 1 addition & 1 deletion service/App.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def load_last_transaction():
return t_dict


def load_all_transaction():
def load_all_transactions():
transaction_file = Path("transactions.txt")
df = pd.read_csv(transaction_file, names="timestamp,price,profit,status".split(","), header=None)
df['timestamp'] = pd.to_datetime(df['timestamp'], format='ISO8601')
Expand Down
55 changes: 20 additions & 35 deletions service/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
import logging
log = logging.getLogger('notifier')

logging.getLogger('PIL').setLevel(logging.WARNING)
logging.getLogger('matplotlib').setLevel(logging.WARNING)

transaction_file = Path("transactions.txt")


async def send_message():
async def send_signal_message():
symbol = App.config["symbol"]

status = App.status
Expand Down Expand Up @@ -103,15 +106,7 @@ async def send_message():
log.error(f"Error sending notification: {e}")


async def send_transaction_message():
#
# Send transaction notification (if any)
# Note that we assume that transactions may happen only if notifications are sent
#
transaction = await simulate_trade() # Here we check additional conditions (in addition to signaling)

if not transaction:
return
async def send_transaction_message(transaction):

profit, profit_percent, profit_descr, profit_percent_descr = await generate_transaction_stats()

Expand Down Expand Up @@ -160,6 +155,9 @@ async def send_transaction_message():


async def simulate_trade():
"""
Very simple trade strategy where we only buy and sell using the whole available amount
"""
symbol = App.config["symbol"]

status = App.status
Expand Down Expand Up @@ -243,45 +241,30 @@ async def generate_transaction_stats():
return profit, profit_percent, profit_descr, profit_percent_descr


async def send_diagram():
async def send_diagram(freq, nrows):
"""
Produce a line chart based on latest data and send it to the channel.
"""
symbol = App.config["symbol"]
signal = App.signal
description = App.config.get("description", "")
close_time = signal.get('close_time')
:param freq: Aggregation interval 'H' - hour.
:param nrows: Time range (x axis) of the diagram, for example, 1 week 168 hours, 2 weeks 336 hours
"""
model = App.config["signal_model"]

buy_signal_threshold = model.get("parameters", {}).get("buy_signal_threshold", 0)
sell_signal_threshold = model.get("parameters", {}).get("sell_signal_threshold", 0)

# Examples: every hour (say, 0th minute or 15th minute), every day (0th hour, 2nd hour etc.)
# If daily, then parameter is hour no., and we check that hour is this hour AND all lower params are 0 (minutes, seconds etc.)

# If hourly, then parameter is minute (or 0), and we check that current minute is 0 AND all other are 0 (but in our case we do not need this because maximum freq is 1 min)
if close_time.minute != 0:
return

#notify_frequency_minutes = 2
#if (close_time.minute % notify_frequency_minutes) != 0:
# return

#
# Prepare data to be visualized
#
freq = 'H'
nrows = 2*7*24 # 1 week 168 hours, 2 weeks 336 hours

# Get main df with high, low, close for the symbol.
df_ohlc = App.feature_df[['open', 'high', 'low', 'close']]
df_ohlc = resample_ohlc_data(df_ohlc.reset_index(), freq, nrows, buy_signal_column=None, sell_signal_column=None)

# Get transaction data.
df_t = load_all_transaction() # timestamp,price,profit,status
df_t = load_all_transactions() # timestamp,price,profit,status
df_t['buy_long'] = df_t['status'].apply(lambda x: True if isinstance(x, str) and x == 'BUY' else False)
df_t['sell_long'] = df_t['status'].apply(lambda x: True if isinstance(x, str) and x == 'SELL' else False)
df_t = df_t[df_t.timestamp >= df_ohlc.timestamp.min()] # select only transactions for the last time
transactions_exist = len(df_t) > 0

if transactions_exist:
Expand All @@ -298,8 +281,13 @@ async def send_diagram():
# Load score
score_exists = False

symbol = App.config["symbol"]
title = f"$\\bf{{{symbol}}}$"

description = App.config.get("description", "")
if description:
title += ": " + description

fig = generate_chart(
df, title,
buy_signal_column="buy_long" if transactions_exist else None,
Expand All @@ -314,8 +302,6 @@ async def send_diagram():
im_bytes = buf.getvalue() # Get complete content (while read returns from current position)
img_data = im_bytes

msg_txt = f""

#
# Send image
#
Expand All @@ -325,12 +311,11 @@ async def send_diagram():
files = {'photo': img_data}
payload = {
'chat_id': chat_id,
'caption': msg_txt,
'caption': f"", # Currently no text
'parse_mode': 'markdown'
}

try:
# https://core.telegram.org/bots/api#sendphoto
url = 'https://api.telegram.org/bot' + bot_token + '/sendPhoto'
req = requests.post(url=url, data=payload, files=files)
response = req.json()
Expand Down
22 changes: 16 additions & 6 deletions service/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,22 @@ async def main_task():
if "trade" in App.config.get("actions", {}):
trade_task = App.loop.create_task(main_trader_task())

if "notify" in App.config.get("actions", {}):
await send_message()
await send_transaction_message()

if "diagram" in App.config.get("actions", {}):
await send_diagram()
notification_model = App.config.get("signal_model", {}).get("notification", {})

if notification_model.get("notify_signal"):
await send_signal_message()

if notification_model.get("notify_transaction"):
transaction = await simulate_trade()
if transaction:
await send_transaction_message(transaction)

if notification_model.get("notify_diagram"):
close_time = App.signal.get('close_time')
if close_time.hour == 0 and close_time.minute == 0: # Every day
await send_diagram(freq='H', nrows=2*7*24) # 2 previous weeks with hourly aggregation
elif close_time.minute == 0: # Every hour
pass

return

Expand Down

0 comments on commit 382cd03

Please sign in to comment.