import gradio as gr import random from PIL import Image import numpy as np import os import matplotlib.pyplot as plt from io import BytesIO import base64 # Candlestick patterns data candlestick_patterns = [ { "name": "Doji", "image": "doji.png", "signal": "neutral", "explanation": "A Doji forms when the opening and closing prices are virtually equal. It represents indecision in the market and can signal a potential reversal or continuation depending on previous price action." }, { "name": "Hammer", "image": "hammer.png", "signal": "buy", "explanation": "The Hammer is a bullish reversal pattern that forms during a downtrend. It has a small body at the top with a long lower shadow (at least twice the size of the body). This indicates that sellers drove prices down during the session but buyers were able to push the price back up by closing." }, { "name": "Shooting Star", "image": "shooting_star.png", "signal": "sell", "explanation": "The Shooting Star is a bearish reversal pattern that forms during an uptrend. It has a small body at the bottom with a long upper shadow. This signals that buyers pushed prices up during the session, but sellers took control and drove the price back down." }, { "name": "Bullish Engulfing", "image": "bullish_engulfing.png", "signal": "buy", "explanation": "A Bullish Engulfing pattern forms when a small bearish candle is followed by a larger bullish candle that completely 'engulfs' the previous day's body. This indicates strong buying pressure and often signals a bullish reversal." }, { "name": "Bearish Engulfing", "image": "bearish_engulfing.png", "signal": "sell", "explanation": "A Bearish Engulfing pattern forms when a small bullish candle is followed by a larger bearish candle that completely 'engulfs' the previous day's body. This indicates strong selling pressure and often signals a bearish reversal." }, { "name": "Morning Star", "image": "morning_star.png", "signal": "buy", "explanation": "The Morning Star is a bullish reversal pattern consisting of three candles: a large bearish candle, followed by a small-bodied candle (star) that gaps down, followed by a large bullish candle that closes above the midpoint of the first candle. This shows a shift from selling to buying pressure." }, { "name": "Evening Star", "image": "evening_star.png", "signal": "sell", "explanation": "The Evening Star is a bearish reversal pattern consisting of three candles: a large bullish candle, followed by a small-bodied candle (star) that gaps up, followed by a large bearish candle that closes below the midpoint of the first candle. This shows a shift from buying to selling pressure." }, { "name": "Three White Soldiers", "image": "three_white_soldiers.png", "signal": "buy", "explanation": "The Three White Soldiers pattern consists of three consecutive bullish candles, each opening within the previous candle's body and closing above the previous candle's high. It signals strong buying pressure and often indicates a bullish reversal." } ] # Generate placeholder images (since we don't have actual images) def generate_candlestick_image(pattern_name): fig, ax = plt.subplots(figsize=(6, 3)) # Different patterns have different appearances if pattern_name == "Doji": # Create a doji candlestick (open/close at same level) plt.plot([1], [50], 'ro', markersize=10) plt.plot([1], [30], '_', markersize=20, color='black') plt.plot([1], [70], '_', markersize=20, color='black') plt.plot([1, 1], [30, 70], 'k-') elif pattern_name == "Hammer": # Create a hammer candlestick plt.bar([1], [5], bottom=[45], width=0.4, color='green') plt.plot([1.2], [30], '_', markersize=20, color='black') plt.plot([1.2, 1.2], [30, 50], 'k-') elif pattern_name == "Shooting Star": # Create a shooting star candlestick plt.bar([1], [5], bottom=[45], width=0.4, color='red') plt.plot([1.2], [70], '_', markersize=20, color='black') plt.plot([1.2, 1.2], [50, 70], 'k-') elif pattern_name == "Bullish Engulfing": # First candle (small bearish) plt.bar([0.7], [5], bottom=[50], width=0.4, color='red') plt.plot([0.7, 0.7], [45, 55], 'k-') # Second candle (large bullish engulfing) plt.bar([1.3], [15], bottom=[40], width=0.4, color='green') plt.plot([1.3, 1.3], [35, 60], 'k-') elif pattern_name == "Bearish Engulfing": # First candle (small bullish) plt.bar([0.7], [5], bottom=[50], width=0.4, color='green') plt.plot([0.7, 0.7], [45, 55], 'k-') # Second candle (large bearish engulfing) plt.bar([1.3], [15], bottom=[40], width=0.4, color='red') plt.plot([1.3, 1.3], [35, 60], 'k-') elif pattern_name == "Morning Star": # First candle (large bearish) plt.bar([0.5], [10], bottom=[50], width=0.3, color='red') plt.plot([0.5, 0.5], [48, 62], 'k-') # Second candle (small doji) plt.bar([1], [2], bottom=[45], width=0.3, color='gray') plt.plot([1, 1], [44, 48], 'k-') # Third candle (large bullish) plt.bar([1.5], [10], bottom=[43], width=0.3, color='green') plt.plot([1.5, 1.5], [40, 55], 'k-') elif pattern_name == "Evening Star": # First candle (large bullish) plt.bar([0.5], [10], bottom=[45], width=0.3, color='green') plt.plot([0.5, 0.5], [43, 57], 'k-') # Second candle (small doji) plt.bar([1], [2], bottom=[58], width=0.3, color='gray') plt.plot([1, 1], [57, 61], 'k-') # Third candle (large bearish) plt.bar([1.5], [10], bottom=[45], width=0.3, color='red') plt.plot([1.5, 1.5], [43, 57], 'k-') elif pattern_name == "Three White Soldiers": # Three consecutive bullish candles plt.bar([0.5], [7], bottom=[40], width=0.3, color='green') plt.plot([0.5, 0.5], [38, 50], 'k-') plt.bar([1], [7], bottom=[47], width=0.3, color='green') plt.plot([1, 1], [45, 57], 'k-') plt.bar([1.5], [7], bottom=[54], width=0.3, color='green') plt.plot([1.5, 1.5], [52, 64], 'k-') plt.title(f"{pattern_name} Pattern") plt.xlim(0, 2) plt.ylim(20, 80) plt.axis('off') plt.tight_layout() # Convert plot to image buf = BytesIO() plt.savefig(buf, format='png') plt.close(fig) buf.seek(0) img = Image.open(buf) return img # Function to generate quiz questions def generate_questions(num_questions=10): questions = [] for i in range(num_questions): pattern_index = i % len(candlestick_patterns) current_pattern = candlestick_patterns[pattern_index] # Create options (all patterns except the correct one) other_options = [p["name"] for p in candlestick_patterns if p["name"] != current_pattern["name"]] # Randomly select 3 incorrect options random.shuffle(other_options) shuffled_options = other_options[:3] # Add the correct answer and shuffle again shuffled_options.append(current_pattern["name"]) random.shuffle(shuffled_options) questions.append({ "pattern": current_pattern, "options": shuffled_options, "correct_answer": current_pattern["name"] }) return questions # Quiz state (will be managed in session state) class QuizState: def __init__(self): self.reset() def reset(self): self.questions = generate_questions(10) self.current_question_index = 0 self.score = 0 self.answered = False self.selected_option = None self.is_complete = False # Initialize quiz state quiz_state = QuizState() def get_current_question(): return quiz_state.questions[quiz_state.current_question_index] def create_interface(): with gr.Blocks(css=""" .container { max-width: 800px; margin: 0 auto; } .header { background-color: #4338ca; color: white; padding: 20px; border-radius: 10px; text-align: center; margin-bottom: 20px; } .quiz-container { background-color: white; border-radius: 8px; padding: 20px; margin-bottom: 20px; } .option { background-color: #f3f4f6; border: 2px solid #e2e8f0; border-radius: 8px; padding: 15px; margin-bottom: 10px; cursor: pointer; } .option:hover { background-color: #e2e8f0; } .correct { border-color: #10b981; background-color: rgba(16, 185, 129, 0.1); } .incorrect { border-color: #ef4444; background-color: rgba(239, 68, 68, 0.1); } .selected { border-color: #4338ca; background-color: rgba(67, 56, 202, 0.1); } .explanation { background-color: #f1f5f9; border-left: 4px solid #4338ca; padding: 15px; border-radius: 0 8px 8px 0; margin-bottom: 20px; } .signal { display: inline-block; padding: 6px 12px; border-radius: 4px; color: white; font-weight: bold; margin-bottom: 10px; } .buy { background-color: #10b981; } .sell { background-color: #ef4444; } .neutral { background-color: #6b7280; } .cash-reward { background-color: #fbbf24; color: #1f2937; padding: 10px 20px; border-radius: 8px; font-size: 24px; font-weight: bold; display: inline-block; margin: 20px 0; } """) as demo: gr.HTML("""
Test your knowledge of candlestick patterns and earn reward points!