Skip to content

Commit

Permalink
Adding dev config & start refactorign again
Browse files Browse the repository at this point in the history
  • Loading branch information
patbaumgartner committed Aug 16, 2021
1 parent 84e34c7 commit 8df8893
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 89 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

config.dev.yml

# Created by https://www.toptal.com/developers/gitignore/api/python,pycharm+all,intellij+all,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm+all,intellij+all,visualstudiocode

Expand Down
48 changes: 20 additions & 28 deletions alerter/BinancePumpAndDumpAlerter.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ def create_new_asset(symbol, chart_intervals):

for interval in chart_intervals:
asset[interval] = {}
asset[interval]["change_alert"] = 0
asset[interval]["change_top_report"] = 0
asset[interval]["change_current"] = 0
asset[interval]["change_last"] = 0

return asset
Expand Down Expand Up @@ -160,19 +159,20 @@ def update_all_monitored_assets_and_send_news_messages(
asset,
chart_intervals,
extract_interval,
outlier_intervals,
)

self.report_generator.send_pump_dump_message(
asset, chart_intervals, dump_enabled
asset,
chart_intervals,
outlier_intervals,
dump_enabled,
)

def calculate_asset_change(
self,
asset,
chart_intervals,
extract_interval,
outlier_intervals,
):
asset_length = len(asset["price"])

Expand All @@ -189,9 +189,8 @@ def calculate_asset_change(
interval,
)
break

# Gets change in % from last alert trigger.
price_delta = asset["price"][-1] - asset["price"][-data_points]
price_delta = asset["price"][-1] - asset["price"][-1-data_points]
change = price_delta / asset["price"][-1]
self.logger.debug(
"Calculated asset: %s for interval: %s with change: %s",
Expand All @@ -200,18 +199,11 @@ def calculate_asset_change(
change,
)

# Stores change for the interval into asset dict. Only used for top pump dump report.
asset[interval]["change_top_report"] = change

# Set last change for next interval iteration
asset[interval]["change_last"] = asset[interval]["change_alert"]
asset[interval]["change_last"] = asset[interval]["change_current"]

# If change is bigger than the outliers set it for reporting,
# else reset the value to not produce accidentally spam
if abs(change) >= outlier_intervals[interval]:
asset[interval]["change_alert"] = change
else:
asset[interval]["change_alert"] = 0
# Stores change for the current interval into asset dict.
asset[interval]["change_current"] = change

return asset

Expand All @@ -228,7 +220,7 @@ def reset_prices_data_when_due(

message = "Emptying price data to prevent memory errors."
self.logger.debug(message)
self.telegram.send_generic_message(message)
self.telegram.send_generic_message(message, is_alert_chat=True)

# Do not delete everything, only elements older than the last monitored interval
lastInterval = "1s"
Expand All @@ -238,7 +230,7 @@ def reset_prices_data_when_due(
data_points = int(chart_intervals[lastInterval]["value"] / extract_interval)

for asset in assets:
asset["price"] = asset["price"][-data_points:]
asset["price"] = asset["price"][-1-data_points:]

initial_time = current_time

Expand Down Expand Up @@ -339,15 +331,6 @@ def run(self):
while True:
start_loop_time = time.time()

self.initial_time = self.reset_prices_data_when_due(
self.initial_time,
start_loop_time,
self.reset_interval,
self.extract_interval,
filtered_assets,
self.chart_intervals,
)

exchange_assets = self.retrieve_exchange_assets(
self.api_url, self.retry_interval
)
Expand Down Expand Up @@ -383,6 +366,15 @@ def run(self):
self.no_of_reported_coins,
)

self.initial_time = self.reset_prices_data_when_due(
self.initial_time,
start_loop_time,
self.reset_interval,
self.extract_interval,
filtered_assets,
self.chart_intervals,
)

# Sleeps for the remainder of 1s, or loops through if extraction takes longer
end_loop_time = time.time()

Expand Down
34 changes: 16 additions & 18 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ chartIntervals:

# Values in % at which an alert is triggered. Ensure interval exists in chartIntervals as well.
outlierIntervals:
"1s": 0.01
"5s": 0.02
"15s": 0.03
"30s": 0.04
"1m": 0.05
"5m": 0.05
"15m": 0.07
"30m": 0.1
"1h": 0.15
"3h": 0.2
"6h": 0.25
"1s": 0.02
"5s": 0.05
"15s": 0.06
"30s": 0.08
"1m": 0.1
"5m": 0.10
"15m": 0.15
"30m": 0.20
"1h": 0.30
"3h": 0.4
"6h": 0.5

# Used for telegram bot updates

Expand Down Expand Up @@ -73,8 +73,6 @@ additionalStatsEnabled: True
noOfReportedCoins: 5
# Intervals for top pump and dump to be sent, ensure its in chartIntervals + outlierIntervals as well
topReportIntervals:
- 30m
- 1h
- 3h
- 6h

Expand All @@ -89,13 +87,13 @@ newsEmoji: ! "\U0001F4F0" # 📰

# If False we do not print unnecessary messages
debug: False
# Skip alert at higher timeframes when change % did not change value by threshold
alertSkipThreshold: 0.005
# Interval for clearing array to prevent MEM ERROR can handle up to 12h+ depending on system
resetInterval: 12h
# Skip alert at higher timeframes when change in % did not change value by threshold in percentage points
alertSkipThreshold: 0.75
# Interval for clearing array to prevent memory can handle up to 12h+ depending on system
resetInterval: 6h
# In the case of get price fail, this is the time delay before re-attempt
priceRetryInterval: 5s
# If telegram message fails to send, this is the time delay before re-attempt
telegramRetryInterval: 2s
telegramRetryInterval: 30s
# Disables checking and adding of new listing pairs
checkNewListingEnabled: True
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
# image: brianleect/binance-pump-alerts:latest
restart: "no"
environment:
- CONFIG_FILE=config.dev.yml
- TELEGRAM_TOKEN=${TELEGRAM_TOKEN}
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
- TELEGRAM_ALERT_CHAT_ID=${TELEGRAM_ALERT_CHAT_ID}
Expand Down
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e
process_config() {

# Please mount your own config file into the container for unsupported env parameters!
# Currently not supported config paramenters: chartIntervals, outlierIntervals, pairsOfInterest, watchlist, topReportIntervals
# Currently not supported config parameters: chartIntervals, outlierIntervals, pairsOfInterest, watchlist, topReportIntervals

if [[ -n $API_URL ]]; then
sed -i "s/apiUrl.*/apiUrl: ${API_URL}/" config.yml
Expand Down
11 changes: 10 additions & 1 deletion pumpAlerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@

# Read config
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
yaml_file = open(os.path.join(__location__, "config.yml"), "r", encoding="utf-8")
config_file = "config.yml"

# Using dev config while development
config_dev_file = "config.dev.yml"
if os.path.isfile(config_dev_file):
config_file = config_dev_file

yaml_file = open(os.path.join(__location__, config_file), "r", encoding="utf-8")

config = yaml.load(yaml_file, Loader=yaml.FullLoader)

# Define the log format
Expand All @@ -30,6 +38,7 @@
logger = logging.getLogger("binance-pump-alerts-app")

# Logg whole configuration during the startup
logger.info("Using config file: %s", config_file)
logger.debug("Config: %s", config)


Expand Down
90 changes: 49 additions & 41 deletions reporter/ReportGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,41 @@ def send_pump_dump_message(
self,
asset,
chart_intervals,
outlier_intervals,
dump_enabled=True,
):
tmpChange = 0
tmpInterval = 0
change_last = 0
change_biggest_delta = 0
interval_last = 0
no_of_alerts = 0
message = ""

for interval in chart_intervals:

change = asset[interval]["change_alert"]
change = asset[interval]["change_current"]

# Skip report if no outlier
if abs(change) < outlier_intervals[interval]:
self.logger.debug(
"Change for asset: %s for interval: %s is to low: %s. Skipping report creation.",
asset["symbol"],
interval,
change,
)
continue

# Remember biggest change of all intervals, to skip later notification
change_last = asset[interval]["change_last"]
change_delta = change - change_last

if abs(change_delta) > abs(change_biggest_delta):
change_biggest_delta = change_delta

# Remember the total number of alerts
no_of_alerts += 1
interval_last = interval

if change > 0:
tmpChange = change
tmpInterval = interval
no_of_alerts += 1
message += "{0} *[{1} Interval]* Change: _{2:.3f}%_ | Price: _{3:.10f}_\n".format(
self.pump_emoji,
interval,
Expand All @@ -81,49 +102,36 @@ def send_pump_dump_message(
)

if change < 0 and dump_enabled:
tmpChange = change
tmpInterval = interval
no_of_alerts += 1
message += "{0} *[{1} Interval]* Change: _{2:.3f}%_ | Price: _{3:.10f}_\n".format(
self.dump_emoji,
interval,
change * 100,
asset["price"][-1],
)

if no_of_alerts == 1:
# Skip alert if change is not big enough to avoid spam
if abs(change_biggest_delta) < (self.alert_skip_threshold / 100):
self.logger.debug(
"Change for asset: %s on all intervals is to low: %s. Skipping this alert report.",
asset["symbol"],
change_biggest_delta,
)
return

# Skipping notification if the change is to low and we are on higher intervals
change_last = asset[tmpInterval]["change_last"]
change_delta = tmpChange - change_last

if (
tmpChange != 0
and (abs(change_delta) < self.alert_skip_threshold)
and chart_intervals[tmpInterval]["value"] > 3
):
self.logger.warning(
"Change for asset: %s [%s] from %s to: %s is to low: %s. Skipping this alert.",
asset["symbol"],
tmpInterval,
tmpChange,
change_last,
change_delta,
)
return
if no_of_alerts == 1:

if tmpChange > 0:
if change_last > 0:
self.send_pump_message(
asset["symbol"],
tmpInterval,
tmpChange,
interval_last,
change_last,
asset["price"][-1],
)
if tmpChange < 0 and dump_enabled:
if change_last < 0 and dump_enabled:
self.send_dump_message(
asset["symbol"],
tmpInterval,
tmpChange,
interval_last,
change_last,
asset["price"][-1],
)

Expand Down Expand Up @@ -158,7 +166,7 @@ def send_top_pump_dump_statistics_report(
if top_pump_enabled:
pump_sorted_list = sorted(
assets,
key=lambda item: item[interval]["change_top_report"],
key=lambda item: item[interval]["change_current"],
reverse=True,
)[0:no_of_reported_coins]

Expand All @@ -168,13 +176,13 @@ def send_top_pump_dump_statistics_report(

for asset in pump_sorted_list:
message += "- {0}: _{1:.2f}_%\n".format(
asset["symbol"], asset[interval]["change_top_report"] * 100
asset["symbol"], asset[interval]["change_current"] * 100
)
message += "\n"

if top_dump_enabled:
dump_sorted_list = sorted(
assets, key=lambda item: item[interval]["change_top_report"]
assets, key=lambda item: item[interval]["change_current"]
)[0:no_of_reported_coins]

message += "{0} *Top {1} Dumps*\n".format(
Expand All @@ -183,7 +191,7 @@ def send_top_pump_dump_statistics_report(

for asset in dump_sorted_list:
message += "- {0}: _{1:.2f}_%\n".format(
asset["symbol"], asset[interval]["change_top_report"] * 100
asset["symbol"], asset[interval]["change_current"] * 100
)

if additional_stats_enabled:
Expand All @@ -199,12 +207,12 @@ def generate_additional_statistics_report(self, assets, interval):
sum_change = 0

for asset in assets:
if asset[interval]["change_top_report"] > 0:
if asset[interval]["change_current"] > 0:
up += 1
elif asset[interval]["change_top_report"] < 0:
elif asset[interval]["change_current"] < 0:
down += 1

sum_change += asset[interval]["change_top_report"]
sum_change += asset[interval]["change_current"]

avg_change = sum_change / len(assets)

Expand Down

0 comments on commit 8df8893

Please sign in to comment.