Zscore_Crypto / app.py
gjin10969
initialize
c834155
import pandas as pd
import numpy as np
import ccxt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import time
import json
from datetime import datetime
import pytz
import telepot
import os
# Constants
BOT_TOKEN = '6787349532:AAGSwuiEJeykI2rQgsoB8C_iXZYKYuJyoOM' # Replace with your bot token
CHAT_ID = '-4284060853' # Replace with your chat ID
bot = telepot.Bot(BOT_TOKEN)
# Prompt for the symbol
symbols = ['ADA/USDT', 'ATOM/USDT', 'XRP/USDT']
timeframes = ['1h', '4h']
# Directories to save images
base_directory = '../zscore'
image_directory = os.path.join(base_directory, 'images')
os.makedirs(image_directory, exist_ok=True)
# Initialize Binance Futures API
binance = ccxt.bybit({
'options': {'defaultType': 'future'}, # Specify futures
})
def fetch_and_calculate_zscore(symbol, timeframe, limit=200, rolling_window=30):
# Fetch OHLCV data
data = binance.fetch_ohlcv(symbol, timeframe=timeframe, limit=limit)
df = pd.DataFrame(data, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
# Convert timestamp to UTC datetime format
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True)
# Calculate rolling mean, std, and Z-Score
df['mean'] = df['close'].rolling(window=rolling_window).mean()
df['std'] = df['close'].rolling(window=rolling_window).std()
df['z_score'] = (df['close'] - df['mean']) / df['std']
# Initialize signal columns
df['buy_signal'] = 0
df['sell_signal'] = 0
# Variables to track thresholds
in_sell_signal = False
in_buy_signal = False
signal_triggered = False # Track if any signal was triggered
# Iterate through the dataframe to track signals
for i in range(1, len(df)):
current_z = df.loc[i, 'z_score']
previous_z = df.loc[i - 1, 'z_score']
# Handle Z-score crossing extreme thresholds for sell signal
if not in_sell_signal:
if current_z > 1.85 and previous_z <= 1.85:
in_sell_signal = True
# Handle Z-score crossing extreme thresholds for buy signal
if not in_buy_signal:
if current_z < -1.85 and previous_z >= -1.85:
in_buy_signal = True
# Keep the signal active if the Z-score remains within the range
if in_sell_signal:
if 1 <= current_z <= 1.85:
df.loc[i, 'sell_signal'] = 1
signal_triggered = True
elif current_z < 1:
in_sell_signal = False
if in_buy_signal:
if -1.85 <= current_z <= -1:
df.loc[i, 'buy_signal'] = 1
signal_triggered = True
elif current_z > -1:
in_buy_signal = False
return df
utc_time = datetime.utcnow()
philippine_tz = pytz.timezone('Asia/Manila')
philippine_time = pytz.utc.localize(utc_time).astimezone(philippine_tz)
formatted_ph_time = philippine_time.strftime("%Y-%m-%d %H:%M:%S")
# Function to update signals in JSON with real-time Z-Score
def update_signal_json(symbol, df, timeframe, json_data):
latest_data = df.iloc[-1]
signal_entry = {
"symbol": symbol,
"time_frame": timeframe,
"date_and_time": latest_data['timestamp'].strftime("%Y-%m-%d %H:%M:%S"),
"realtime_ph_time": formatted_ph_time,
"current_price": latest_data['close'],
"zscore": latest_data['z_score']
}
json_data = [entry for entry in json_data if not (entry['symbol'] == symbol and entry['time_frame'] == timeframe)]
json_data.append(signal_entry)
return json_data
# Function to plot data for a single symbol including BTCDOM and BTC
def plot_data(pair_df, btcdom_df, btc_df, symbol, timeframe, ax):
ax.clear()
# Plot Z-Scores for all pairs
ax.plot(btcdom_df['timestamp'], btcdom_df['z_score'], label="BTCDOM/USDT Z-Score", color='blue', linestyle='-')
ax.plot(pair_df['timestamp'], pair_df['z_score'], label=f"{symbol} Z-Score", color='orange', linestyle='-')
ax.plot(btc_df['timestamp'], btc_df['z_score'], label="BTC/USDT Z-Score", color='gray', linestyle='-')
# Add thresholds
ax.axhline(y=2, color='red', linestyle='--', label='Overbought Threshold')
ax.axhline(y=-2, color='green', linestyle='--', label='Oversold Threshold')
# Plot Buy and Sell signals for the pair
ax.scatter(pair_df[pair_df['buy_signal'] == 1]['timestamp'], pair_df[pair_df['buy_signal'] == 1]['z_score'],
marker='^', color='green', label=f"{symbol} Buy Signal")
ax.scatter(pair_df[pair_df['sell_signal'] == 1]['timestamp'], pair_df[pair_df['sell_signal'] == 1]['z_score'],
marker='v', color='red', label=f"{symbol} Sell Signal")
# Format plot
ax.set_title(f"Z-Scores Signals {timeframe} for {symbol}", fontsize=16)
ax.set_xlabel("Time (UTC)", fontsize=12)
ax.set_ylabel("Z-Score", fontsize=12)
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d %H:%M"))
ax.legend(loc="upper left")
ax.grid(True)
plt.xticks(rotation=45)
# Real-time monitoring
def run_real_time():
json_data = []
try:
with open('signals.json', 'r') as file:
json_data = json.load(file)
except FileNotFoundError:
pass
while True:
for timeframe in timeframes:
btcdom_symbol = 'ETH/USDT'
btc_symbol = 'BTC/USDT'
btcdom_df = fetch_and_calculate_zscore(btcdom_symbol, timeframe)
btc_df = fetch_and_calculate_zscore(btc_symbol, timeframe)
# Send announcement message for the timeframe
message = f"{timeframe} time frame for {', '.join(symbols)}"
bot.sendMessage(chat_id=CHAT_ID, text=message)
media_group = []
for symbol in symbols:
pair_df = fetch_and_calculate_zscore(symbol, timeframe)
# Update JSON for the pair, BTCDOM, and BTC
json_data = update_signal_json(symbol, pair_df, timeframe, json_data)
json_data = update_signal_json(btcdom_symbol, btcdom_df, timeframe, json_data)
json_data = update_signal_json(btc_symbol, btc_df, timeframe, json_data)
# Create a new figure for each symbol and timeframe
fig, ax = plt.subplots(figsize=(14, 7))
plot_data(pair_df, btcdom_df, btc_df, symbol, timeframe, ax)
plt.tight_layout()
# Save image to the 'images' directory
image_path = os.path.join(image_directory, f"{symbol.lower().replace('/', '_')}_{timeframe}.png")
plt.savefig(image_path)
plt.close(fig) # Close the figure to free memory
# Add image to media group
media_group.append({'media': open(image_path, 'rb'), 'type': 'photo'})
# Send the media group to Telegram
try:
bot.sendMediaGroup(
chat_id=CHAT_ID,
media=media_group,
disable_notification=True
)
print("Images uploaded successfully.")
except Exception as e:
print(f"Failed to send media group for {timeframe} to Telegram: {e}")
# Save updated JSON for both timeframes
with open('signals.json', 'w') as file:
json.dump(json_data, file, indent=4)
time.sleep(60) # Wait for 60 seconds before next update
# Run the real-time system
run_real_time()