diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 6cfabd5..0cbcb9c 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 69b1eb0..34e26a2 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 5c208b3..88b957d 100644 --- a/config/settings.py +++ b/config/settings.py @@ -49,11 +49,7 @@ CSRF_COOKIE_SAMESITE = "None" # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', 'django.contrib.sessions', - 'django.contrib.messages', 'django.contrib.staticfiles', 'core', 'signals', @@ -64,8 +60,6 @@ MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', # Disable X-Frame-Options middleware to allow Flatlogic preview iframes. # 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] @@ -82,8 +76,6 @@ TEMPLATES = [ 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', # IMPORTANT: do not remove – injects PROJECT_DESCRIPTION/PROJECT_IMAGE_URL and cache-busting timestamp 'core.context_processors.project_context', ], @@ -99,36 +91,15 @@ WSGI_APPLICATION = 'config.wsgi.application' DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': os.getenv('DB_NAME', ''), - 'USER': os.getenv('DB_USER', ''), - 'PASSWORD': os.getenv('DB_PASS', ''), - 'HOST': os.getenv('DB_HOST', '127.0.0.1'), - 'PORT': os.getenv('DB_PORT', '3306'), - 'OPTIONS': { - 'charset': 'utf8mb4', - }, - }, + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } } # Password validation # https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] # Internationalization diff --git a/config/urls.py b/config/urls.py index c19926c..ad15eb0 100644 --- a/config/urls.py +++ b/config/urls.py @@ -14,13 +14,11 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.contrib import admin from django.urls import include, path from django.conf import settings from django.conf.urls.static import static urlpatterns = [ - path("admin/", admin.site.urls), path("", include("core.urls")), path("api/", include("signals.urls")), ] diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 6867ddf..2788716 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..4a9172d 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}{{ project_name }}{% endblock %} +{% block title %}Trading Signal: {{ active_symbol }}{% endblock %} {% block head %} @@ -8,11 +8,15 @@ {% endblock %} {% block content %} +
+ +
+ + + +
+
+
-
-

Analyzing your requirements and generating your app…

-
- Loading… -
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

+ +
+

{{ active_symbol }}

+

{{ signal }}

- -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/core/views.py b/core/views.py index c9aed12..b7c5e23 100644 --- a/core/views.py +++ b/core/views.py @@ -1,25 +1,25 @@ -import os -import platform - -from django import get_version as django_version from django.shortcuts import render -from django.utils import timezone - +from signals.engine import generate_signal def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() + """ + Renders the home page with a trading signal for the active symbol. + """ + # 1. ACTIVE SYMBOL STATE: Get symbol from URL parameter, default to BTC/USDT + symbol = request.GET.get('symbol', 'BTC/USDT').upper() + + try: + # 3. BACKEND INTEGRATION: Generate signal for the active symbol + signal = generate_signal(symbol) + except Exception as e: + signal = f'Error: {e}' + + # A list of symbols for the dropdown selector + available_symbols = ['BTC/USDT', 'ETH/USDT', 'XRP/USDT', 'LTC/USDT', 'ADA/USDT', 'SOL/USDT', 'DOGE/USDT'] context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), + 'active_symbol': symbol, + 'signal': signal, + 'available_symbols': available_symbols, } return render(request, "core/index.html", context) diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000..4df9b4e Binary files /dev/null and b/db.sqlite3 differ diff --git a/requirements.txt b/requirements.txt index c494051..2c24186 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ Django==5.2.7 -mysqlclient==2.2.7 python-dotenv==1.1.1 ccxt +pandas diff --git a/signals/__pycache__/engine.cpython-311.pyc b/signals/__pycache__/engine.cpython-311.pyc index 5cec905..af028bd 100644 Binary files a/signals/__pycache__/engine.cpython-311.pyc and b/signals/__pycache__/engine.cpython-311.pyc differ diff --git a/signals/engine.py b/signals/engine.py index 87e665a..b7ef68d 100644 --- a/signals/engine.py +++ b/signals/engine.py @@ -3,8 +3,32 @@ import ccxt import pandas as pd def get_ohlcv(symbol, timeframe): - exchange = ccxt.binance() - ohlcv = exchange.fetch_ohlcv(symbol, timeframe) + exchange = ccxt.kraken() + # Symbol mapping for Kraken + symbol_map = { + 'BTC/USDT': 'BTC/USD', + 'ETH/USDT': 'ETH/USD', + 'XRP/USDT': 'XRP/USD', + 'LTC/USDT': 'LTC/USD', + 'ADA/USDT': 'ADA/USD', + 'SOL/USDT': 'SOL/USD', + 'DOGE/USDT': 'DOGE/USD', + } + + try: + # First, try the original symbol + ohlcv = exchange.fetch_ohlcv(symbol, timeframe) + except ccxt.BadSymbol: + # If the symbol is not found, try the mapped symbol + mapped_symbol = symbol_map.get(symbol) + if mapped_symbol: + try: + ohlcv = exchange.fetch_ohlcv(mapped_symbol, timeframe) + except ccxt.ExchangeError as e: + raise Exception(f"Could not fetch data for {symbol} or {mapped_symbol} from Kraken: {e})") + else: + raise Exception(f"Symbol {symbol} not found on Kraken and no mapping available.") + df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms') return df diff --git a/trading/__init__.py b/trading/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trading/__pycache__/__init__.cpython-311.pyc b/trading/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 6094d67..0000000 Binary files a/trading/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/trading/__pycache__/admin.cpython-311.pyc b/trading/__pycache__/admin.cpython-311.pyc deleted file mode 100644 index deb7627..0000000 Binary files a/trading/__pycache__/admin.cpython-311.pyc and /dev/null differ diff --git a/trading/__pycache__/apps.cpython-311.pyc b/trading/__pycache__/apps.cpython-311.pyc deleted file mode 100644 index b122138..0000000 Binary files a/trading/__pycache__/apps.cpython-311.pyc and /dev/null differ diff --git a/trading/__pycache__/models.cpython-311.pyc b/trading/__pycache__/models.cpython-311.pyc deleted file mode 100644 index 3ad8e50..0000000 Binary files a/trading/__pycache__/models.cpython-311.pyc and /dev/null differ diff --git a/trading/__pycache__/signals.cpython-311.pyc b/trading/__pycache__/signals.cpython-311.pyc deleted file mode 100644 index 072687e..0000000 Binary files a/trading/__pycache__/signals.cpython-311.pyc and /dev/null differ diff --git a/trading/admin.py b/trading/admin.py deleted file mode 100644 index b676649..0000000 --- a/trading/admin.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.contrib import admin -from django.contrib.auth.admin import UserAdmin -from django.contrib.auth.models import User -from .models import UserProfile, Signal, Trade, Backtest - -class UserProfileInline(admin.StackedInline): - model = UserProfile - can_delete = False - verbose_name_plural = 'Profile' - fk_name = 'user' - -class CustomUserAdmin(UserAdmin): - inlines = (UserProfileInline, ) - - def get_inline_instances(self, request, obj=None): - if not obj: - return list() - return super(CustomUserAdmin, self).get_inline_instances(request, obj) - - -admin.site.unregister(User) -admin.site.register(User, CustomUserAdmin) - -admin.site.register(Signal) -admin.site.register(Trade) -admin.site.register(Backtest) \ No newline at end of file diff --git a/trading/apps.py b/trading/apps.py deleted file mode 100644 index abf4355..0000000 --- a/trading/apps.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.apps import AppConfig - - -class TradingConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'trading' - - def ready(self): - import trading.signals diff --git a/trading/migrations/0001_initial.py b/trading/migrations/0001_initial.py deleted file mode 100644 index f4687d2..0000000 --- a/trading/migrations/0001_initial.py +++ /dev/null @@ -1,59 +0,0 @@ -# Generated by Django 5.2.7 on 2025-12-28 13:55 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Signal', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('symbol', models.CharField(max_length=20)), - ('signal', models.CharField(choices=[('BUY', 'Buy'), ('SELL', 'Sell'), ('WAIT', 'Wait')], max_length=4)), - ('confidence', models.FloatField()), - ('timestamp', models.DateTimeField(auto_now_add=True)), - ], - ), - migrations.CreateModel( - name='Backtest', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('start_date', models.DateTimeField()), - ('end_date', models.DateTimeField()), - ('results', models.JSONField()), - ('timestamp', models.DateTimeField(auto_now_add=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Trade', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('symbol', models.CharField(max_length=20)), - ('entry_price', models.FloatField()), - ('exit_price', models.FloatField(blank=True, null=True)), - ('entry_timestamp', models.DateTimeField()), - ('exit_timestamp', models.DateTimeField(blank=True, null=True)), - ('signal', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trading.signal')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='UserProfile', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('role', models.CharField(choices=[('Free', 'Free'), ('Pro', 'Pro'), ('Admin', 'Admin')], default='Free', max_length=10)), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/trading/migrations/__init__.py b/trading/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trading/migrations/__pycache__/0001_initial.cpython-311.pyc b/trading/migrations/__pycache__/0001_initial.cpython-311.pyc deleted file mode 100644 index 827589f..0000000 Binary files a/trading/migrations/__pycache__/0001_initial.cpython-311.pyc and /dev/null differ diff --git a/trading/migrations/__pycache__/__init__.cpython-311.pyc b/trading/migrations/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 20b9a48..0000000 Binary files a/trading/migrations/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/trading/models.py b/trading/models.py deleted file mode 100644 index e6a9f0c..0000000 --- a/trading/models.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User - -class UserProfile(models.Model): - USER_ROLE_CHOICES = ( - ('Free', 'Free'), - ('Pro', 'Pro'), - ('Admin', 'Admin'), - ) - user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') - role = models.CharField(max_length=10, choices=USER_ROLE_CHOICES, default='Free') - - def __str__(self): - return f'{self.user.username} - {self.role}' - -class Signal(models.Model): - SIGNAL_CHOICES = ( - ('BUY', 'Buy'), - ('SELL', 'Sell'), - ('WAIT', 'Wait'), - ) - symbol = models.CharField(max_length=20) - signal = models.CharField(max_length=4, choices=SIGNAL_CHOICES) - confidence = models.FloatField() - timestamp = models.DateTimeField(auto_now_add=True) - - def __str__(self): - return f'{self.timestamp} - {self.symbol} - {self.signal}' - -class Trade(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE) - symbol = models.CharField(max_length=20) - entry_price = models.FloatField() - exit_price = models.FloatField(null=True, blank=True) - entry_timestamp = models.DateTimeField() - exit_timestamp = models.DateTimeField(null=True, blank=True) - signal = models.ForeignKey(Signal, on_delete=models.CASCADE) - - def __str__(self): - return f'{self.user.username} - {self.symbol}' - -class Backtest(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE) - start_date = models.DateTimeField() - end_date = models.DateTimeField() - results = models.JSONField() - timestamp = models.DateTimeField(auto_now_add=True) - - def __str__(self): - return f'{self.user.username} - {self.timestamp}' \ No newline at end of file diff --git a/trading/signals.py b/trading/signals.py deleted file mode 100644 index f4951ff..0000000 --- a/trading/signals.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.db.models.signals import post_save -from django.dispatch import receiver -from django.contrib.auth.models import User -from .models import UserProfile - -@receiver(post_save, sender=User) -def create_user_profile(sender, instance, created, **kwargs): - if created: - UserProfile.objects.create(user=instance) - -@receiver(post_save, sender=User) -def save_user_profile(sender, instance, **kwargs): - try: - instance.profile.save() - except UserProfile.DoesNotExist: - UserProfile.objects.create(user=instance) diff --git a/trading/tests.py b/trading/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/trading/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/trading/views.py b/trading/views.py deleted file mode 100644 index 91ea44a..0000000 --- a/trading/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here.