den4ik2003

Untitled

Mar 14th, 2025
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.72 KB | None | 0 0
  1. import asyncio
  2. import logging
  3. import os
  4. import json
  5. import subprocess
  6. import signal
  7. import psutil
  8. import time
  9. from datetime import datetime, timezone, timedelta
  10. from pathlib import Path
  11. from aiogram.types import Message
  12. from aiogram.enums import ParseMode
  13. from aiogram import Bot, Dispatcher, types
  14. from aiogram.filters.command import Command
  15. from aiogram import F
  16. from aiogram.exceptions import TelegramBadRequest
  17. from apscheduler.schedulers.asyncio import AsyncIOScheduler
  18.  
  19. logging.basicConfig(level=logging.INFO)
  20.  
  21. scheduler = AsyncIOScheduler()
  22. bot = Bot(token="7030520224:AAEnyKFkIsgS6QzVnexn3EiWM9Dlgb3WBPY")
  23. dp = Dispatcher()
  24.  
  25. def parse_clients_json():
  26.     with open('clients.json', 'r') as clients_f:
  27.         chat_ids = json.loads(''.join(clients_f.readlines()).replace(' ', '').replace('\n', ''))
  28.         return chat_ids
  29.  
  30. chat_ids = parse_clients_json()
  31.  
  32. # chat_ids = {
  33. #     -4567096432: ["DOR", "DAG", "KRU", "LTX", "ABDS", "GHUB", "IMARO", "SENDOR", "AEROBUD", "OBORTECH", "VGX", "CHAMP", "CHEX", "RBX", "MEI", "DOGA", "SOLAR", "$SX"], # managing group
  34. #     -1002150192437: ["DOR", "DAG", "KRU", "LTX", "ABDS", "GHUB", "IMARO", "SENDOR", "AEROBUD", "OBORTECH", "VGX", "CHAMP", "CHEX", "RBX", "MEI", "DOGA", "SOLAR", "$SX"], # managing group
  35. #     -4147360362: ["DAG","IMARO", "$SX"], # test group
  36. #     # client groups
  37. #     -4531845094: ["DAG"],
  38. #     -4573489347: ["GHUB"],
  39. #     -1002385516473: ["ABDS"],
  40. #     -1002404653479: ["KRU"],
  41. #     -4537296744: ["DOR"],
  42. #     -4541252605: ["LTX"],
  43. #     -4742454014: ["AEROBUD"],
  44. #     -4560694856: ["IMARO"],
  45. #     -4743728721: ["OBORTECH"],
  46. #     -1002264729612: ["VGX"],
  47. #     -4679815932: ["CHAMP"],
  48. #     -4770925676: ["CHEX"],
  49. #     -4626936453: ["RBX"],
  50. #     -4788418340: ["MEI"],
  51. #     -4663628175: ["DOGA"],
  52. #     -4747537835: ["SOLAR"],
  53. #     -4770221167: ["$SX"]
  54. # }
  55.  
  56. timezones = {
  57.     -4788418340: timedelta(hours=9),
  58.     # -1002150192437: timedelta(hours=3),
  59. }
  60.  
  61. path_to_mm_balances_dir = '/mnt/mm_telemetry'
  62. path_to_volume_balances_dir = '/mnt/volume_telemetry'
  63. balance_state = {}
  64. prev_wide_spread = {}
  65. stopped = []
  66.  
  67. @dp.message(Command("liquidity_volume"))
  68. async def volume_balances(message: types.Message):
  69.     files_path = [path_to_volume_balances_dir + '/' + file.name for file in Path(path_to_volume_balances_dir).iterdir() if file.is_file()]
  70.     trades_size = {}
  71.  
  72.     for balance_file in files_path:
  73.         name = balance_file.split('/')[-1]
  74.  
  75.         if str(message.chat.id) not in chat_ids:
  76.             await message.answer("Your chat is not in whitelist")
  77.             return
  78.  
  79.         is_clients_coin = False            
  80.         for coin in chat_ids[str(message.chat.id)]:
  81.             if coin.lower() == name.split('_')[0].lower():
  82.                 is_clients_coin = True
  83.                 break
  84.         if not is_clients_coin:
  85.             continue
  86.  
  87.         total_trades, last_time = await calculate_private_trades(balance_file)
  88.         if total_trades == -1 and last_time == -1: # decode error
  89.             continue
  90.         if last_time != 0:
  91.             last_time = str(datetime.fromtimestamp(int(last_time / 1000)))
  92.         trades_size[name] = f'\nliquidity_volume (24h): {round(total_trades, 2)}\nearliest 24h trade time: {last_time}\n'
  93.  
  94.     trades_answer = ''
  95.     for name in sorted(trades_size.keys(), key=lambda s: s.lower()):
  96.         print_name = ''
  97.         parse_name = name.replace('-', ' ').replace('_', ' ').split(' ')
  98.         if len(parse_name) == 2:
  99.             print_name += parse_name[0].upper() + " " + parse_name[1]
  100.         elif len(parse_name) == 3:
  101.             print_name += (parse_name[0] + parse_name[1]).upper() + " " + parse_name[2]
  102.         elif len(parse_name) == 4:
  103.             print_name += (parse_name[0] + parse_name[1]).upper() + " " + parse_name[2] + parse_name[3]
  104.  
  105.         trades_answer += f'{print_name}:{trades_size[name]}\n'
  106.  
  107.     await message.answer(trades_answer)
  108.  
  109.  
  110. @dp.message(Command("volume_balances"))
  111. async def volume_balances(message: types.Message):
  112.     files_path = [path_to_volume_balances_dir + '/' + file.name for file in Path(path_to_volume_balances_dir).iterdir() if file.is_file()]
  113.     balances = {}
  114.     trades_size = {}
  115.  
  116.     for balance_file in files_path:
  117.         p = subprocess.Popen(['tail', '-20', balance_file],shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  118.         res, err = p.communicate()
  119.         if not err:
  120.             name = balance_file.split('/')[-1]
  121.  
  122.             if str(message.chat.id) not in chat_ids:
  123.                 await message.answer("Your chat is not in whitelist")
  124.                 return
  125.  
  126.             is_clients_coin = False
  127.             symbol_name = '_'.join(name.split('_')[:2])
  128.             base_asset = symbol_name.split('_')[0]
  129.             quote_asset = symbol_name.split('_')[1]
  130.             for coin in chat_ids[str(message.chat.id)]:
  131.                 if coin.upper() == base_asset:
  132.                     is_clients_coin = True
  133.                     break
  134.             if not is_clients_coin:
  135.                 continue
  136.  
  137.             decoded = res.decode().split('\n')[::-1]
  138.             for line in decoded:
  139.                 splitted = line.split(' ')
  140.  
  141.                 if len(splitted) < 3:
  142.                     continue
  143.  
  144.                 if splitted[1] == 'balance':
  145.                     tz = timezone(timezones.get(message.chat.id, timedelta(hours=0)))
  146.                     time = datetime.fromtimestamp(int(int(splitted[0]) / 1000), tz)
  147.                     try:
  148.                         info_dict = json.loads(''.join(splitted[2:]).replace("'", '"'))
  149.                     except Exception as e:
  150.                         print(e)
  151.                         continue
  152.                     base, quote = float(info_dict['base']), float(info_dict['quote'])
  153.                     balances[name] = f"\ntime: {str(time)}\n{base_asset}: {base}\n{quote_asset}: {quote}\n"
  154.  
  155.         else:
  156.             print(err.decode())
  157.  
  158.     answers = []
  159.     balances_answer = ''
  160.     for name in sorted(balances.keys(), key=lambda s: s.lower()):
  161.         z = name.split('_')
  162.         parse_name = '/'.join(z[:2]) + ' ' + '_'.join(z[2:])
  163.         balances_answer += f'{parse_name}:{balances[name]}\n'
  164.  
  165.     await message.answer(balances_answer)
  166.  
  167.  
  168. async def calculate_private_trades(balance_file):
  169.     grep_command = ['grep', 'private_trades', balance_file]
  170.     tail_command = ['tail', '-n', '100000']
  171.  
  172.     with subprocess.Popen(grep_command, stdout=subprocess.PIPE) as grep_process:
  173.         with subprocess.Popen(tail_command, stdin=grep_process.stdout, stdout=subprocess.PIPE) as tail_process:
  174.             res, err = tail_process.communicate()
  175.             if not err:
  176.                 decoded = res.decode().split('\n')[::-1]
  177.             else:
  178.                 print(err.decode())
  179.                 return -1, -1
  180.  
  181.     total = 0
  182.     critical_time = int(time.time() * 1000) - 86400000
  183.     last_time = 0
  184.     for line in decoded:
  185.         splitted = line.split(' ')
  186.  
  187.         if len(splitted) < 3:
  188.             continue
  189.  
  190.         if (int(splitted[0]) < critical_time):
  191.             break
  192.  
  193.         if splitted[1] == 'private_trades': # на всякий случай проверка
  194.             try:
  195.                 trades = eval(''.join(splitted[2:]).replace("'", '"'))
  196.             except Exception as e:
  197.                 print(e)
  198.                 continue
  199.             if len(trades) == 0:
  200.                 continue
  201.  
  202.             last_time = int(splitted[0])
  203.             total += float(trades[0]['price']) * float(trades[0]['quantity'])
  204.  
  205.     return total, last_time
  206.  
  207. @dp.message(Command("mm_balances"))
  208. async def mm_balance(message: types.Message):
  209.     files_path = [path_to_mm_balances_dir + '/' + file.name for file in Path(path_to_mm_balances_dir).iterdir() if file.is_file()]
  210.     balances = {}
  211.  
  212.     for balance_file in files_path:
  213.         p = subprocess.Popen(['tail', '-20', balance_file],shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  214.         res, err = p.communicate()
  215.         if not err:
  216.             name = balance_file.split('/')[-1]
  217.  
  218.             if str(message.chat.id) not in chat_ids:
  219.                 await message.answer("Your chat is not in whitelist")
  220.                 return
  221.  
  222.             is_clients_coin = False
  223.             symbol_name = '_'.join(name.split('_')[:2])
  224.             base_asset = symbol_name.split('_')[0]
  225.             quote_asset = symbol_name.split('_')[1]
  226.             for coin in chat_ids[str(message.chat.id)]:
  227.                 if coin == base_asset:
  228.                     is_clients_coin = True
  229.                     break
  230.             if not is_clients_coin:
  231.                 continue
  232.  
  233.             decoded = res.decode().split('\n')[::-1]
  234.             for line in decoded:
  235.                 splitted = line.split(' ')
  236.  
  237.                 if len(splitted) < 3:
  238.                     continue
  239.  
  240.                 if splitted[1] == 'balance':
  241.                     tz = timezone(timezones.get(message.chat.id, timedelta(hours=0)))
  242.                     time = datetime.fromtimestamp(int(int(splitted[0]) / 1000), tz)
  243.                     try:
  244.                         info_dict = json.loads(''.join(splitted[2:]).replace("'", '"'))
  245.                     except Exception as e:
  246.                         continue
  247.                     base, quote = float(info_dict['base']), float(info_dict['quote'])
  248.                     balances[name] = f"\ntime: {str(time)}\n{base_asset}: {base}\n{quote_asset}: {quote}\n"
  249.  
  250.         else:
  251.             print(err.decode())
  252.  
  253.     answers = []
  254.     balances_answer = ''
  255.     for name in sorted(balances.keys(), key=lambda s: s.lower()):
  256.         # print_name = ''
  257.         # parse_name = name.replace('-', ' ').replace('_', ' ').split(' ')
  258.         # if len(parse_name) == 2:
  259.         #     print_name += parse_name[0].upper() + " " + parse_name[1]
  260.         # elif len(parse_name) == 3:
  261.         #     print_name += (parse_name[0] + parse_name[1]).upper() + " " + parse_name[2]
  262.         z = name.split('_')
  263.         parse_name = '/'.join(z[:2]) + ' ' + '_'.join(z[2:])
  264.         balances_answer += f'{parse_name}:{balances[name]}\n'
  265.  
  266.     await message.answer(balances_answer)
  267.  
  268.  
  269. @dp.message(Command("cashout_balances"))
  270. async def cashout_balances(message: types.Message):
  271.     files_path = ['/mnt/tb_telemetry/' + file.name for file in Path('/mnt/tb_telemetry').iterdir() if file.is_file()]
  272.     side_tb_files_path = ['/mnt/side_tb_telemetry/' + file.name for file in Path('/mnt/side_tb_telemetry').iterdir() if file.is_file()]
  273.     balances = {}
  274.     trades_size = {}
  275.  
  276.     for balance_file in files_path:
  277.         p = subprocess.Popen(['tail', '-20', balance_file],shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  278.         res, err = p.communicate()
  279.         if not err:
  280.             name = balance_file.split('/')[-1]
  281.             isfuck = False
  282.             if 'FUCK' in name.upper():
  283.                 name = name[:-4] + 'USDT'
  284.                 isfuck = True
  285.  
  286.             if str(message.chat.id) not in chat_ids:
  287.                 await message.answer("Your chat is not in whitelist")
  288.                 return
  289.  
  290.             is_clients_coin = False
  291.             symbol_name = '_'.join(name.split('_')[:2])
  292.             base_asset = symbol_name.split('_')[0]
  293.             quote_asset = symbol_name.split('_')[1]
  294.  
  295.             for coin in chat_ids[str(message.chat.id)]:
  296.                 if coin.upper() == base_asset:
  297.                     if isfuck ^ ('FUCK' in chat_ids[str(message.chat.id)]):
  298.                         continue
  299.                     is_clients_coin = True
  300.                     break
  301.             if not is_clients_coin:
  302.                 continue
  303.  
  304.             decoded = res.decode().split('\n')[::-1]
  305.             for line in decoded:
  306.                 splitted = line.split(' ')
  307.  
  308.                 if len(splitted) < 3:
  309.                     continue
  310.  
  311.                 if splitted[1] == 'balance':
  312.                     tz = timezone(timezones.get(message.chat.id, timedelta(hours=0)))
  313.                     time = datetime.fromtimestamp(int(int(splitted[0]) / 1000), tz)
  314.                     try:
  315.                         info_dict = json.loads(''.join(splitted[2:]).replace("'", '"'))
  316.                     except Exception as e:
  317.                         print(e)
  318.                         continue
  319.                     base, quote = float(info_dict['base']), float(info_dict['quote'])
  320.                     balances[name] = f"\ntime: {str(time)}\n{base_asset}: {base}\n{quote_asset}: {quote}\n"
  321.  
  322.         else:
  323.             print(err.decode())
  324.  
  325.     for balance_file in side_tb_files_path:
  326.         p = subprocess.Popen(['tail', '-20', balance_file],shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  327.         res, err = p.communicate()
  328.         if not err:
  329.             name = balance_file.split('/')[-1]
  330.  
  331.             if str(message.chat.id) not in chat_ids:
  332.                 await message.answer("Your chat is not in whitelist")
  333.                 return
  334.  
  335.             is_clients_coin = False
  336.             symbol_name = name.split('.')[0]
  337.             base_asset = symbol_name.split('_')[0]
  338.             quote_asset = symbol_name.split('_')[1]
  339.             market_name = name.split('.')[1]
  340.             user_name = name.split('.')[2]
  341.             print(symbol_name + '.' + user_name)
  342.             unified_name = symbol_name + '.' + market_name
  343.             if len(chat_ids[str(message.chat.id)]) > 1:
  344.                 unified_name += '.' + user_name
  345.  
  346.             for coin in chat_ids[str(message.chat.id)]:
  347.                 if coin == symbol_name + '.' + user_name:
  348.                     is_clients_coin = True
  349.                     break
  350.             if not is_clients_coin:
  351.                 continue
  352.  
  353.             decoded = res.decode().split('\n')[::-1]
  354.             for line in decoded:
  355.                 splitted = line.split(' ')
  356.  
  357.                 if len(splitted) < 3:
  358.                     continue
  359.  
  360.                 if splitted[1] == 'balance':
  361.                     tz = timezone(timezones.get(message.chat.id, timedelta(hours=0)))
  362.                     time = datetime.fromtimestamp(int(int(splitted[0]) / 1000), tz)
  363.                     try:
  364.                         info_dict = json.loads(''.join(splitted[2:]).replace("'", '"'))
  365.                     except Exception as e:
  366.                         print(e)
  367.                         continue
  368.                     base, quote = float(info_dict['base']), float(info_dict['quote'])
  369.                     balances[unified_name] = f"\ntime: {str(time)}\n{base_asset}: {base}\n{quote_asset}: {quote}\n"
  370.  
  371.         else:
  372.             print(err.decode())
  373.  
  374.     answers = []
  375.     balances_answer = ''
  376.     for name in sorted(balances.keys(), key=lambda s: s.lower()):
  377.         v = name.split('.')
  378.         z = v[0].split('_')
  379.         parse_name = '/'.join(z[:2]) + (' ' + v[1] if len(v) > 1 else '')
  380.         if len(v) > 2:
  381.             parse_name += f' ({v[2]})'
  382.         balances_answer += f'{parse_name}:{balances[name]}\n'
  383.  
  384.     await message.answer(balances_answer)
  385.  
  386.  
  387. @dp.message(F.text.lower().contains('add_token_'))
  388. async def handler(message: Message):
  389.     current_chat_id = str(message.chat.id)
  390.     token_name = message.text.split('_')[2].upper()
  391.  
  392.     if '<' in token_name and '>' in token_name:
  393.         token_name = token_name[1:-1]      
  394.  
  395.     if current_chat_id in chat_ids:
  396.         if token_name in chat_ids[current_chat_id]:
  397.             await message.reply(f"{token_name} have already been added")
  398.             return
  399.         chat_ids[current_chat_id].append(token_name)
  400.     else:
  401.         chat_ids[current_chat_id] = [token_name]
  402.  
  403.     with open('clients.json', 'w') as clients_f:
  404.         clients_f.write(json.dumps(chat_ids))
  405.  
  406.     await message.reply(f"{token_name} was successfully added")
  407.    
  408.    
  409. @dp.message(F.text.lower().contains('delete_token_'))
  410. async def handler(message: Message):
  411.     current_chat_id = str(message.chat.id)
  412.     token_name = message.text.split('_')[2].upper()
  413.  
  414.     if '<' in token_name and '>' in token_name:
  415.         token_name = token_name[1:-1]      
  416.  
  417.     if current_chat_id in chat_ids:
  418.         if token_name not in chat_ids[current_chat_id]:
  419.             await message.reply(f"{token_name} not in tokens list")
  420.             return
  421.         chat_ids[current_chat_id].remove(token_name)    
  422.     else:
  423.         await message.reply(f"Your chat is not in chat ids")
  424.         return
  425.  
  426.     with open('clients.json', 'w') as clients_f:
  427.         clients_f.write(json.dumps(chat_ids))
  428.  
  429.     await message.reply(f"{token_name} was successfully deleted")
  430.    
  431.  
  432. @dp.message(F.text)
  433. async def bad_message(message: Message): # нельзя поднимать эту функцию выше!
  434.     print(message.chat.id)
  435.     # await message.answer("I don't understand you")
  436.  
  437.  
  438. async def main():
  439.     await dp.start_polling(bot)
  440.  
  441. if __name__ == "__main__":
  442.     asyncio.run(main())
Add Comment
Please, Sign In to add comment