Spaces:
No application file
No application file
Upload 13 files
Browse files- __init__.py +0 -0
- app.py +37 -22
- chart_analyzer.py +29 -0
- generator_endpoint.py +13 -0
- indicator_generator.py +36 -0
- model_uploader.py +23 -0
- package-lock.json +27 -0
- package.json +5 -0
- pattern_generator.py +32 -0
- requirements.txt +16 -0
- update_space.py +19 -0
- vision_endpoint.py +10 -0
- vision_model.py +16 -0
__init__.py
ADDED
File without changes
|
app.py
CHANGED
@@ -1,32 +1,47 @@
|
|
1 |
import gradio as gr
|
2 |
-
from src.
|
3 |
-
import
|
|
|
|
|
|
|
4 |
|
5 |
-
def
|
6 |
-
|
|
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
2. Technical Indicators Analysis
|
11 |
-
3. Price Action Analysis
|
12 |
-
4. Volume Analysis
|
13 |
-
5. Future Price Predictions
|
14 |
-
Format the response in clear sections."""
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
20 |
)
|
21 |
|
22 |
-
return
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
interface = gr.Interface(
|
25 |
-
fn=
|
26 |
-
inputs=
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
)
|
31 |
|
32 |
-
interface.launch()
|
|
|
1 |
import gradio as gr
|
2 |
+
from src.analysis.chart_processor import ChartProcessor
|
3 |
+
from src.analysis.pattern_generator import PatternGenerator
|
4 |
+
from src.analysis.indicator_generator import IndicatorGenerator
|
5 |
+
from src.analysis.chart_analyzer import ChartAnalyzer
|
6 |
+
from src.data.market_data import MarketData
|
7 |
|
8 |
+
def analyze_full_chart(chart_image, symbol):
|
9 |
+
market_data = MarketData()
|
10 |
+
historical_data = market_data.fetch_ohlcv(symbol)
|
11 |
|
12 |
+
pattern_gen = PatternGenerator()
|
13 |
+
pattern_images = pattern_gen.generate_all_patterns(chart_image, historical_data)
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
+
indicator_gen = IndicatorGenerator()
|
16 |
+
indicator_charts = indicator_gen.generate_all_indicators(historical_data)
|
17 |
+
|
18 |
+
analyzer = ChartAnalyzer()
|
19 |
+
analysis_results = analyzer.analyze_full(
|
20 |
+
chart_image=chart_image,
|
21 |
+
pattern_images=pattern_images,
|
22 |
+
indicator_charts=indicator_charts,
|
23 |
+
historical_data=historical_data
|
24 |
)
|
25 |
|
26 |
+
return {
|
27 |
+
'pattern_analysis': analysis_results.patterns,
|
28 |
+
'indicator_analysis': analysis_results.indicators,
|
29 |
+
'predictions': analysis_results.predictions,
|
30 |
+
'interactive_charts': indicator_charts
|
31 |
+
}
|
32 |
|
33 |
interface = gr.Interface(
|
34 |
+
fn=analyze_full_chart,
|
35 |
+
inputs=[
|
36 |
+
gr.Image(type="pil", label="Chart Image"),
|
37 |
+
gr.Textbox(label="Symbol")
|
38 |
+
],
|
39 |
+
outputs=[
|
40 |
+
gr.Gallery(label="Pattern Overlays"),
|
41 |
+
gr.Gallery(label="Indicator Charts"),
|
42 |
+
gr.JSON(label="Analysis Results"),
|
43 |
+
gr.Plot(label="Interactive Indicators")
|
44 |
+
]
|
45 |
)
|
46 |
|
47 |
+
interface.launch()
|
chart_analyzer.py
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ollama
|
2 |
+
from src.model.vision_model import ChartVisionModel
|
3 |
+
|
4 |
+
class ChartAnalyzer:
|
5 |
+
def __init__(self):
|
6 |
+
self.vision_model = ChartVisionModel()
|
7 |
+
self.client = ollama.Client()
|
8 |
+
|
9 |
+
def analyze_full(self, chart_image, pattern_images, indicator_charts, historical_data):
|
10 |
+
vision_analysis = self.vision_model.analyze_chart(chart_image)
|
11 |
+
|
12 |
+
system_prompt = """Analyze this technical chart with all patterns and indicators:
|
13 |
+
1. Pattern Analysis (300+ patterns)
|
14 |
+
2. Indicator Analysis
|
15 |
+
3. Current Chart Analysis
|
16 |
+
4. Movement Predictions
|
17 |
+
Provide detailed analysis for each component."""
|
18 |
+
|
19 |
+
analysis = self.client.generate(
|
20 |
+
model="llama3.2-vision:latest",
|
21 |
+
prompt=system_prompt,
|
22 |
+
images=[chart_image] + pattern_images
|
23 |
+
)
|
24 |
+
|
25 |
+
return {
|
26 |
+
'patterns': self._analyze_patterns(pattern_images),
|
27 |
+
'indicators': self._analyze_indicators(indicator_charts),
|
28 |
+
'predictions': self._generate_predictions(analysis)
|
29 |
+
}
|
generator_endpoint.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from transformers import pipeline
|
3 |
+
|
4 |
+
app = FastAPI()
|
5 |
+
chart_generator = pipeline("text-generation", model="tmmdev/chart-generator")
|
6 |
+
|
7 |
+
@app.post("/generate")
|
8 |
+
async def generate_charts(data: dict):
|
9 |
+
charts = chart_generator(data)
|
10 |
+
return {
|
11 |
+
"interactive_charts": charts.charts,
|
12 |
+
"pattern_images": charts.patterns
|
13 |
+
}
|
indicator_generator.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ollama
|
2 |
+
from lightweight_charts import Chart
|
3 |
+
|
4 |
+
class IndicatorGenerator:
|
5 |
+
def __init__(self):
|
6 |
+
self.client = ollama.Client()
|
7 |
+
self.code_model = "codellama:latest"
|
8 |
+
self.indicators = [
|
9 |
+
'rsi', 'macd', 'bollinger_bands', 'moving_averages',
|
10 |
+
'stochastic', 'atr', 'volume_profile'
|
11 |
+
]
|
12 |
+
|
13 |
+
def generate_all_indicators(self, historical_data):
|
14 |
+
indicator_charts = []
|
15 |
+
for indicator in self.indicators:
|
16 |
+
# Generate code for indicator using CodeLlama
|
17 |
+
code_prompt = f"Generate Lightweight Charts code for {indicator} indicator with proper styling and configuration"
|
18 |
+
code_response = self.client.generate(
|
19 |
+
model=self.code_model,
|
20 |
+
prompt=code_prompt
|
21 |
+
)
|
22 |
+
|
23 |
+
# Create chart using generated code
|
24 |
+
chart = Chart()
|
25 |
+
chart.set(code_response) # Applies the generated configuration
|
26 |
+
chart.add_data(historical_data)
|
27 |
+
|
28 |
+
indicator_charts.append(chart)
|
29 |
+
|
30 |
+
return indicator_charts
|
31 |
+
|
32 |
+
def _create_indicator_chart(self, data, indicator_type):
|
33 |
+
chart = Chart()
|
34 |
+
# Specific indicator configurations using Lightweight Charts
|
35 |
+
chart.add_indicator(indicator_type, data)
|
36 |
+
return chart
|
model_uploader.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from huggingface_hub import HfApi, login
|
2 |
+
import ollama
|
3 |
+
|
4 |
+
def export_and_upload_models():
|
5 |
+
api = HfApi()
|
6 |
+
login()
|
7 |
+
|
8 |
+
# Export Ollama models
|
9 |
+
models = {
|
10 |
+
"llama3.2-vision": "tmmdev/chart-vision-analyzer",
|
11 |
+
"codellama": "tmmdev/chart-generator"
|
12 |
+
}
|
13 |
+
|
14 |
+
for model_name, repo_id in models.items():
|
15 |
+
# Export model from Ollama
|
16 |
+
model_path = ollama.export(model_name)
|
17 |
+
|
18 |
+
# Upload to HF
|
19 |
+
api.upload_folder(
|
20 |
+
folder_path=model_path,
|
21 |
+
repo_id=repo_id,
|
22 |
+
repo_type="model"
|
23 |
+
)
|
package-lock.json
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ai",
|
3 |
+
"lockfileVersion": 3,
|
4 |
+
"requires": true,
|
5 |
+
"packages": {
|
6 |
+
"": {
|
7 |
+
"dependencies": {
|
8 |
+
"lightweight-charts": "^5.0.1"
|
9 |
+
}
|
10 |
+
},
|
11 |
+
"node_modules/fancy-canvas": {
|
12 |
+
"version": "2.1.0",
|
13 |
+
"resolved": "https://registry.npmjs.org/fancy-canvas/-/fancy-canvas-2.1.0.tgz",
|
14 |
+
"integrity": "sha512-nifxXJ95JNLFR2NgRV4/MxVP45G9909wJTEKz5fg/TZS20JJZA6hfgRVh/bC9bwl2zBtBNcYPjiBE4njQHVBwQ==",
|
15 |
+
"license": "MIT"
|
16 |
+
},
|
17 |
+
"node_modules/lightweight-charts": {
|
18 |
+
"version": "5.0.1",
|
19 |
+
"resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-5.0.1.tgz",
|
20 |
+
"integrity": "sha512-JjqI+Uoxuw/XESn6BeBp+o8kxa+CgvkbM7edhoarJ5KRjY1INqi0Hvahn88Q8Ou5sfckHbTGGKrM2lQQYsuH5A==",
|
21 |
+
"license": "Apache-2.0",
|
22 |
+
"dependencies": {
|
23 |
+
"fancy-canvas": "2.1.0"
|
24 |
+
}
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
package.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"dependencies": {
|
3 |
+
"lightweight-charts": "^5.0.1"
|
4 |
+
}
|
5 |
+
}
|
pattern_generator.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ollama
|
2 |
+
from lightweight_charts import Chart
|
3 |
+
|
4 |
+
class PatternGenerator:
|
5 |
+
def __init__(self):
|
6 |
+
self.client = ollama.Client()
|
7 |
+
self.code_model = "codellama:latest"
|
8 |
+
self.patterns = [
|
9 |
+
'head_and_shoulders', 'double_top', 'double_bottom',
|
10 |
+
'triangle', 'channel', 'fibonacci', 'wedge', 'flag',
|
11 |
+
'pennant', 'cup_and_handle', 'rounding_bottom'
|
12 |
+
# Will expand to 300+ patterns
|
13 |
+
]
|
14 |
+
|
15 |
+
def generate_all_patterns(self, chart_image, historical_data):
|
16 |
+
pattern_charts = []
|
17 |
+
for pattern in self.patterns:
|
18 |
+
# Generate pattern drawing code using CodeLlama
|
19 |
+
code_prompt = f"Generate Lightweight Charts code to draw {pattern} pattern with proper styling and technical analysis markers"
|
20 |
+
code_response = self.client.generate(
|
21 |
+
model=self.code_model,
|
22 |
+
prompt=code_prompt
|
23 |
+
)
|
24 |
+
|
25 |
+
# Create chart with pattern overlay
|
26 |
+
chart = Chart()
|
27 |
+
chart.set(code_response)
|
28 |
+
chart.add_data(historical_data)
|
29 |
+
|
30 |
+
pattern_charts.append(chart)
|
31 |
+
|
32 |
+
return pattern_charts
|
requirements.txt
CHANGED
@@ -5,3 +5,19 @@ python-ollama>=0.1.0
|
|
5 |
Pillow>=10.0.0
|
6 |
huggingface-hub>=0.19.0
|
7 |
python-dotenv>=1.0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
Pillow>=10.0.0
|
6 |
huggingface-hub>=0.19.0
|
7 |
python-dotenv>=1.0.0
|
8 |
+
fastapi
|
9 |
+
uvicorn
|
10 |
+
gradio
|
11 |
+
huggingface-hub
|
12 |
+
transformers
|
13 |
+
torch
|
14 |
+
lightweight-charts
|
15 |
+
pandas
|
16 |
+
numpy
|
17 |
+
requests
|
18 |
+
python-multipart
|
19 |
+
ollama
|
20 |
+
python-dotenv
|
21 |
+
plotly
|
22 |
+
opencv-python
|
23 |
+
pillow
|
update_space.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from huggingface_hub import HfApi, login
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
import os
|
4 |
+
|
5 |
+
def update_space_repo():
|
6 |
+
load_dotenv()
|
7 |
+
api = HfApi()
|
8 |
+
login() # Will use HF_TOKEN from environment
|
9 |
+
|
10 |
+
api.upload_folder(
|
11 |
+
folder_path=".",
|
12 |
+
repo_id="tmmdev/chart-analyzer",
|
13 |
+
repo_type="space"
|
14 |
+
)
|
15 |
+
|
16 |
+
print("✨ Space updated successfully!")
|
17 |
+
|
18 |
+
if __name__ == "__main__":
|
19 |
+
update_space_repo()
|
vision_endpoint.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, File
|
2 |
+
from transformers import pipeline
|
3 |
+
|
4 |
+
app = FastAPI()
|
5 |
+
vision_model = pipeline("image-analysis", model="tmmdev/chart-vision-analyzer")
|
6 |
+
|
7 |
+
@app.post("/analyze")
|
8 |
+
async def analyze_chart(image: File):
|
9 |
+
analysis = vision_model(image)
|
10 |
+
return {"analysis": analysis}
|
vision_model.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ollama
|
2 |
+
from PIL import Image
|
3 |
+
|
4 |
+
class ChartVisionModel:
|
5 |
+
def __init__(self):
|
6 |
+
self.client = ollama.Client()
|
7 |
+
self.model = "llava:34b" # Using LLaVA for vision analysis
|
8 |
+
|
9 |
+
def analyze_chart(self, image):
|
10 |
+
response = self.client.generate(
|
11 |
+
model=self.model,
|
12 |
+
prompt="Analyze this technical chart in detail",
|
13 |
+
images=[image]
|
14 |
+
)
|
15 |
+
return response
|
16 |
+
|