aidevhund commited on
Commit
47c13b8
·
verified ·
1 Parent(s): f85f5a3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +194 -0
app.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ import numpy as np
4
+ import torch
5
+ from PIL import Image
6
+ from transformers import (
7
+ DonutProcessor,
8
+ VisionEncoderDecoderModel,
9
+ pipeline
10
+ )
11
+ import json
12
+
13
+ class CryptoChartAnalyzer:
14
+ def __init__(self):
15
+ # Cihaz olarak CPU'yu kullanıyoruz
16
+ self.device = "cpu"
17
+
18
+ # Donut Model for Chart Understanding
19
+ self.processor = DonutProcessor.from_pretrained("naver-clova-ix/donut-base-finetuned-cord-v2")
20
+ self.donut_model = VisionEncoderDecoderModel.from_pretrained(
21
+ "naver-clova-ix/donut-base-finetuned-cord-v2"
22
+ ).to(self.device)
23
+
24
+ # Financial LLM Pipeline (CPU için)
25
+ self.fin_llm = pipeline(
26
+ "text-generation",
27
+ model="mistralai/Mistral-7B-Instruct-v0.2",
28
+ device=self.device
29
+ )
30
+
31
+ def detect_trend_lines(self, gray_img):
32
+ """Detect trend lines using OpenCV."""
33
+ edges = cv2.Canny(gray_img, 50, 150)
34
+ lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=50,
35
+ minLineLength=50, maxLineGap=10)
36
+ return len(lines) if lines is not None else 0
37
+
38
+ def detect_support_resistance(self, gray_img):
39
+ """Detect support and resistance levels."""
40
+ blur = cv2.GaussianBlur(gray_img, (5, 5), 0)
41
+ _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
42
+ contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
43
+ return len(contours)
44
+
45
+ def detect_fibonacci_levels(self, gray_img):
46
+ """Basic Fibonacci retracement detection (mock)."""
47
+ height, _ = gray_img.shape
48
+ levels = [0, 0.236, 0.382, 0.5, 0.618, 1]
49
+ return [int(height * level) for level in levels]
50
+
51
+ def detect_harmonic_patterns(self, img):
52
+ """Detect harmonic patterns in the chart (mock logic)."""
53
+ patterns = [{"pattern": "ABCD", "confidence": 0.85}, {"pattern": "Gartley", "confidence": 0.78}]
54
+ return patterns
55
+
56
+ def detect_chart_patterns(self, gray_img):
57
+ """Detect classic chart patterns: double top, double bottom, triangles."""
58
+ # Placeholder logic for detecting patterns
59
+ patterns = [
60
+ {"pattern": "Double Top", "confidence": 0.88},
61
+ {"pattern": "Double Bottom", "confidence": 0.81},
62
+ {"pattern": "Head and Shoulders", "confidence": 0.76},
63
+ {"pattern": "Symmetrical Triangle", "confidence": 0.83}
64
+ ]
65
+ return patterns
66
+
67
+ def detect_technical_features(self, image):
68
+ """Combine all detection methods."""
69
+ img = np.array(image)
70
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
71
+
72
+ return {
73
+ "trend_lines": self.detect_trend_lines(gray),
74
+ "key_levels": self.detect_support_resistance(gray),
75
+ "fibonacci_levels": self.detect_fibonacci_levels(gray),
76
+ "harmonic_patterns": self.detect_harmonic_patterns(img),
77
+ "chart_patterns": self.detect_chart_patterns(gray)
78
+ }
79
+
80
+ def analyze_chart_content(self, image):
81
+ """Analyze chart content using the Donut model."""
82
+ task_prompt = "<s_chart_analysis>"
83
+ prepared_img = self.processor(image, return_tensors="pt").pixel_values.to(self.device)
84
+
85
+ decoder_input_ids = self.processor.tokenizer(
86
+ task_prompt, add_special_tokens=False, return_tensors="pt"
87
+ ).input_ids.to(self.device)
88
+
89
+ outputs = self.donut_model.generate(
90
+ prepared_img,
91
+ decoder_input_ids=decoder_input_ids,
92
+ max_length=512,
93
+ early_stopping=True,
94
+ pad_token_id=self.processor.tokenizer.pad_token_id,
95
+ eos_token_id=self.processor.tokenizer.eos_token_id,
96
+ use_cache=True,
97
+ num_beams=3,
98
+ temperature=0.3,
99
+ output_scores=True
100
+ )
101
+
102
+ return self.processor.decode(outputs[0].squeeze().cpu().numpy())
103
+
104
+ def generate_analysis(self, image, question):
105
+ """Complete analysis pipeline."""
106
+ # Detect features
107
+ technical_features = self.detect_technical_features(image)
108
+ chart_description = self.analyze_chart_content(image)
109
+
110
+ # Prompt engineering for analysis
111
+ analysis_prompt = f"""
112
+ [ROLE] Senior Crypto Technical Analyst with 15 years of experience.
113
+ [CHART DESCRIPTION] {chart_description}
114
+ [TECHNICAL FEATURES]
115
+ - Trend Lines: {technical_features['trend_lines']}
116
+ - Key Levels: {technical_features['key_levels']}
117
+ - Fibonacci Levels: {technical_features['fibonacci_levels']}
118
+ - Harmonic Patterns: {technical_features['harmonic_patterns']}
119
+ - Chart Patterns: {technical_features['chart_patterns']}
120
+
121
+ [ANALYSIS TASKS]
122
+ 1. Detailed candlestick pattern analysis.
123
+ 2. Price action evaluation.
124
+ 3. Trend analysis with confidence levels.
125
+ 4. Support/Resistance levels identification.
126
+ 5. Risk/Reward ratio calculation.
127
+ 6. {question}
128
+
129
+ [RESPONSE FORMAT]
130
+ {{
131
+ "analysis": {{
132
+ "candlestick_patterns": [{{"pattern": "...", "location": "...", "confidence": 0.X}}],
133
+ "trend_analysis": {{"direction": "...", "strength": "...", "confidence": 0.X}},
134
+ "key_levels": {{"support": [...], "resistance": [...]}},
135
+ "price_action": "...",
136
+ "fibonacci_levels": [...],
137
+ "harmonic_patterns": [...],
138
+ "chart_patterns": [...]
139
+ }},
140
+ "forecast": {{
141
+ "short_term": "...",
142
+ "medium_term": "..."
143
+ }}
144
+ }}
145
+ """
146
+
147
+ # LLM analysis
148
+ response = self.fin_llm(
149
+ analysis_prompt,
150
+ max_new_tokens=1024,
151
+ temperature=0.2,
152
+ do_sample=True,
153
+ top_p=0.9
154
+ )[0]['generated_text']
155
+
156
+ # Attempt to parse JSON
157
+ try:
158
+ return json.loads(response)
159
+ except json.JSONDecodeError:
160
+ return {"error": "Failed to parse LLM response. Check the prompt or model output."}
161
+
162
+ # Initialize analyzer
163
+ analyzer = CryptoChartAnalyzer()
164
+
165
+ # Gradio Interface
166
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
167
+ gr.Markdown("# 🔥 **Crypto Technical Analysis Pro**")
168
+
169
+ with gr.Row():
170
+ with gr.Column():
171
+ image_input = gr.Image(type="pil", label="Upload Chart")
172
+ question_input = gr.Textbox(
173
+ label="Analysis Request",
174
+ value="Identify key reversal patterns and calculate potential price targets"
175
+ )
176
+ submit_btn = gr.Button("Analyze", variant="primary")
177
+
178
+ with gr.Column():
179
+ analysis_output = gr.JSON(label="Technical Analysis Report")
180
+
181
+ examples = [
182
+ ["sample_chart1.png", "Analyze bullish/bearish divergence in RSI"],
183
+ ["sample_chart2.jpg", "Identify head and shoulders pattern"]
184
+ ]
185
+
186
+ gr.Examples(examples=examples, inputs=[image_input, question_input])
187
+
188
+ submit_btn.click(
189
+ fn=analyzer.generate_analysis,
190
+ inputs=[image_input, question_input],
191
+ outputs=analysis_output
192
+ )
193
+
194
+ app.launch(debug=False)