pátek 19. července 2024

BTC graph in terminal :) funny graph updated every second

 This Python script provides a real-time visual display of Bitcoin (BTC) price data using the `curses` library to create a terminal-based interface. Here’s a summary of its functionality:


1. **Price Fetching**: It fetches the latest BTC/USDT price from the Binance API.


2. **Indicators Calculation**:

   - **RSI (Relative Strength Index)**: Calculates and displays the RSI to gauge the price momentum.

   - **Bollinger Bands**: Computes and displays Bollinger Bands, which include the upper, middle, and lower bands, to analyze price volatility.


3. **Visualization**:

   - **Price Plot**: Plots the price changes as a line graph.

   - **Bollinger Bands**: Draws the Bollinger Bands on the graph.

   - **RSI**: Displays the RSI value at the bottom of the screen.


4. **Display Updates**: Continuously updates the graph and indicators every second and shows the current, maximum, and minimum prices at the top-right corner.


5. **Exit**: Allows the user to exit the program by pressing the 'q' key.


The script runs in a terminal environment and uses `curses` to handle real-time screen updates and user interactions.

import requests

import curses

import time

import numpy as np


# Function to get the latest BTC/USDT price from Binance

def get_btcusdt_price():

    url = 'https://api.binance.com/api/v3/ticker/price'

    params = {'symbol': 'BTCUSDT'}

    response = requests.get(url, params=params)

    data = response.json()

    return float(data['price'])


# Function to calculate RSI

def calculate_rsi(prices, period=14):

    if len(prices) < period:

        return 50  # Default RSI value when there's not enough data

    deltas = np.diff(prices)

    seed = deltas[:period]

    up = seed[seed >= 0].sum() / period

    down = -seed[seed < 0].sum() / period

    rs = up / down if down != 0 else 0

    rsi = 100 - (100 / (1 + rs))

    for delta in deltas[period:]:

        if delta > 0:

            upval = delta

            downval = 0

        else:

            upval = 0

            downval = -delta

        up = (up * (period - 1) + upval) / period

        down = (down * (period - 1) + downval) / period

        rs = up / down if down != 0 else 0

        rsi = 100 - (100 / (1 + rs))

    return rsi


# Function to calculate Bollinger Bands

def calculate_bollinger_bands(prices, period=20):

    if len(prices) < period:

        return None, None, None  # Not enough data

    sma = np.mean(prices[-period:])

    std = np.std(prices[-period:])

    upper_band = sma + (2 * std)

    middle_band = sma

    lower_band = sma - (2 * std)

    return upper_band, middle_band, lower_band


# Function to draw the RSI as a bar graph

def draw_rsi(stdscr, rsi, max_y, max_x):

    rsi_str = f'RSI: {rsi:.2f}'

    # Ensure the RSI display stays within screen bounds

    if max_x > len(rsi_str) + 2:

        stdscr.addstr(max_y - 1, max_x - len(rsi_str) - 2, rsi_str, curses.A_BOLD | curses.color_pair(5))


# Function to draw fixed Bollinger Bands with values

def draw_bollinger_bands(stdscr, prices, upper_band, middle_band, lower_band, max_y, min_price, price_range, max_x):

    if upper_band is not None and middle_band is not None and lower_band is not None:

        y_upper = max_y - 1 - int((upper_band - min_price) / price_range * (max_y - 1))

        y_middle = max_y - 1 - int((middle_band - min_price) / price_range * (max_y - 1))

        y_lower = max_y - 1 - int((lower_band - min_price) / price_range * (max_y - 1))


        # Draw upper band

        if 0 <= y_upper < max_y:

            upper_str = f'U: {upper_band:.2f}'

            try:

                stdscr.addstr(y_upper, 0, upper_str, curses.A_BOLD | curses.color_pair(1))

                upper_line = '#' * (max_x - len(upper_str) - 1)

                stdscr.addstr(y_upper, len(upper_str), upper_line, curses.color_pair(1))

            except curses.error:

                pass


        # Draw middle band

        if 0 <= y_middle < max_y:

            middle_str = f'M: {middle_band:.2f}'

            try:

                stdscr.addstr(y_middle, 0, middle_str, curses.A_BOLD | curses.color_pair(2))

                middle_line = '#' * (max_x - len(middle_str) - 1)

                stdscr.addstr(y_middle, len(middle_str), middle_line, curses.color_pair(2))

            except curses.error:

                pass


        # Draw lower band

        if 0 <= y_lower < max_y:

            lower_str = f'L: {lower_band:.2f}'

            try:

                stdscr.addstr(y_lower, 0, lower_str, curses.A_BOLD | curses.color_pair(3))

                lower_line = '#' * (max_x - len(lower_str) - 1)

                stdscr.addstr(y_lower, len(lower_str), lower_line, curses.color_pair(3))

            except curses.error:

                pass


# Function to initialize the screen and start drawing the graph

def draw_graph(stdscr):

    curses.curs_set(0)

    stdscr.nodelay(1)

    stdscr.timeout(1000)


    curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)

    curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)

    curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)

    curses.init_pair(4, curses.COLOR_YELLOW, curses.COLOR_BLACK)

    curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK)


    max_y, max_x = stdscr.getmaxyx()

    prices = []

    max_price = 0

    min_price = float('inf')


    while True:

        stdscr.clear()


        price = get_btcusdt_price()

        prices.append(price)


        if len(prices) > max_x - 2:

            prices.pop(0)


        max_price = max(prices)

        min_price = min(prices)


        price_range = max_price - min_price

        if price_range == 0:

            price_range = 1  # Prevent division by zero


        upper_band, middle_band, lower_band = calculate_bollinger_bands(prices)

        rsi = calculate_rsi(prices)


        # Draw Bollinger Bands

        draw_bollinger_bands(stdscr, prices, upper_band, middle_band, lower_band, max_y, min_price, price_range, max_x)

        # Draw RSI

        draw_rsi(stdscr, rsi, max_y, max_x)


        # Draw vertical lines for graph

        for i in range(min(max_x - 1, len(prices) - 1)):

            y1 = max_y - 1 - int((prices[i] - min_price) / price_range * (max_y - 1))

            y2 = max_y - 1 - int((prices[i + 1] - min_price) / price_range * (max_y - 1))

            if 0 <= y1 < max_y and 0 <= y2 < max_y:

                if y1 == y2:

                    stdscr.addch(y1, i, '-')

                elif y1 < y2:

                    for y in range(y1, y2 + 1):

                        stdscr.addch(y, i, '|')

                else:

                    for y in range(y2, y1 + 1):

                        stdscr.addch(y, i, '|')


        # Draw current price, max, and min prices at the top right corner

        current_price_str = f'Price: {price:.2f}'

        max_price_str = f'Max: {max_price:.2f}'

        min_price_str = f'Min: {min_price:.2f}'

        try:

            stdscr.addstr(1, max_x - len(current_price_str) - 2, current_price_str, curses.A_BOLD | curses.color_pair(4))

            stdscr.addstr(2, max_x - len(max_price_str) - 2, max_price_str, curses.A_BOLD | curses.color_pair(4))

            stdscr.addstr(3, max_x - len(min_price_str) - 2, min_price_str, curses.A_BOLD | curses.color_pair(4))

        except curses.error:

            pass


        stdscr.refresh()


        # Exit on 'q'

        if stdscr.getch() == ord('q'):

            break


def main():

    curses.wrapper(draw_graph)


if __name__ == "__main__":

    main()

0 komentářů:

hledej.me » Tykač

Google
 

počet návštěv blogu za posledních 7 dní

Oblíbené příspěvky

hledej.me