File size: 3,130 Bytes
21bb68b
 
 
 
 
 
 
 
 
a469221
21bb68b
 
 
 
a469221
21bb68b
a469221
21bb68b
a469221
 
21bb68b
 
 
 
a469221
21bb68b
a469221
21bb68b
a469221
 
21bb68b
 
 
 
a469221
 
 
21bb68b
 
a469221
21bb68b
a469221
 
 
 
 
 
 
 
 
 
 
21bb68b
a469221
21bb68b
a469221
21bb68b
a469221
21bb68b
 
a469221
21bb68b
a469221
21bb68b
 
a469221
21bb68b
 
 
 
 
 
a469221
21bb68b
 
a469221
21bb68b
 
 
 
 
 
 
 
a469221
 
21bb68b
a469221
21bb68b
 
 
a469221
21bb68b
a469221
 
21bb68b
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import pandas as pd
import mplfinance as mpf
from io import BytesIO
import base64
import matplotlib.pyplot as plt

def create_mplfinance_chart(df, ticker, predictions=None):
    """
    Creates a custom mplfinance candlestick chart and returns it as a base64 encoded image.
    Implements the exact layout: Candlestick + Volume + MACD + Stochastic.
    """
    if df.empty:
        return None

    # Define style - Yahoo style as requested
    mc = mpf.make_marketcolors(
        up='#00ff00', down='#ff0000',  # Green/Red candles
        wick='black',
        edge='black',
        volume='#00bfff',
        inherit=True
    )

    s = mpf.make_mpf_style(
        base_mpf_style='yahoo',
        marketcolors=mc,
        facecolor='white',
        edgecolor='black',
        gridcolor='lightgray',
        gridstyle='-',
        figcolor='white',
        rc={'axes.labelcolor': 'black',
            'xtick.color': 'black',
            'ytick.color': 'black',
            'figure.titlesize': 16,
            'axes.titlesize': 14,
            'axes.titleweight': 'bold'}
    )

    # Define panels: [Candlestick, Volume, MACD, Stochastic]
    apds = []
    
    # MACD Panel (Panel 2 - index 1 for addplot)
    # MACD Line
    apds.append(
        mpf.make_addplot(df['MACD'], color='#606060', panel=2, ylabel='MACD', secondary_y=False)
    )
    # Signal Line
    apds.append(
        mpf.make_addplot(df['MACD_signal'], color='#1f77b4', panel=2, secondary_y=False)
    )
    # Positive Histogram Bars
    apds.append(
        mpf.make_addplot(df['MACD_bar_positive'], type='bar', color='#4dc790', panel=2, width=0.8)
    )
    # Negative Histogram Bars
    apds.append(
        mpf.make_addplot(df['MACD_bar_negative'], type='bar', color='#fd6b6c', panel=2, width=0.8)
    )
    
    # Stochastic Panel (Panel 3 - index 2 for addplot)
    apds.append(
        mpf.make_addplot(df[['%D', '%SD', 'UL', 'DL']], panel=3, ylabel='Stoch (14,3)', ylim=[0, 100])
    )

    # Prediction overlay on main chart
    if predictions is not None and predictions.any():
        last_date = df.index[-1]
        future_index = pd.date_range(start=last_date, periods=len(predictions) + 1, freq=df.index.freq or 'D')[1:]
        future_series = pd.Series(predictions, index=future_index)
        
        apds.append(
            mpf.make_addplot(future_series, color='blue', linestyle='-.', width=2, marker='o', markersize=4)
        )

    # Plotting
    fig, axes = mpf.plot(
        df,
        type='candle',
        style=s,
        title=f'{ticker} Price Chart and Analysis',
        ylabel='Price (USD)',
        volume=True,
        addplot=apds,
        mav=(5, 20),  # Moving averages as requested
        figratio=(16, 9),
        figscale=1.5,
        panel_ratios=(3, 1, 3, 3),  # Ratio as requested
        returnfig=True
    )
    
    # Convert to Base64
    buf = BytesIO()
    fig.savefig(buf, format='png', bbox_inches='tight', dpi=100)
    plt.close(fig)
    image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8')
    
    return f'<img src="data:image/png;base64,{image_base64}" style="width: 100%; height: auto;">'