1. Django urls.py
Main urls.py
“”“
URL configuration for CryptoBot project.

The urlpatterns list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path(‘’, views.home, name=‘home’)
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path(‘’, Home.as_view(), name=‘home’)
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 trading.views import home, views
from django.contrib.auth import views as auth_views
from trading.views import signals
from django.views.generic import RedirectView

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘accounts/login/’, auth_views.LoginView.as_view(), name=‘login’),
path(‘accounts/’, include(‘django.contrib.auth.urls’)), # Add this for logout, password reset, etc.
path(‘trading/’, include(‘trading.urls’)),
##path(‘’, signals_view, name=‘signals’),
path(‘signup.html/’, views.signup_view, name=‘signup’),
#path(‘api/realtime_data/<str:symbol>/’, views.get_real_time_data, name=‘realtime_data’),
#path(‘accounts/login/’, views.login_view, name=‘login’),
path(‘signals.html’, views.signals, name=‘signals’),
##path(‘signal_list/’, views.signal_list, name=‘signal_list’),
path(‘trades.html/’, views.trades, name=‘trades’),
path(‘manage_apis.html/’, views.manage_apis, name=‘manage_apis’),
###path(‘password_reset/’, auth_views.PasswordResetView.as_view(), name=‘password_reset’),
path(‘’, home, name=‘home’),
##path(‘index_view/’, views.index_view, name=‘index_view’),
###path(‘login_view/’, views.login_view, name=‘login’),
path(‘logout_view/’, views.logout_view, name=‘logout’),
path(‘favicon.ico’, RedirectView.as_view(url=‘static/favicon.ico’, permanent=True)),
]

Apps urls.py
from django.urls import path, include
from django.contrib import admin
from . import views

urlpatterns = [
##path(‘signal_list/’, views.signal_list, name=‘signal_list’),
### cause recursion path(‘trading/’, include(‘trading.urls’)),
path(‘’, views.home, name=‘home’),
path(‘home/’, views.home, name=‘home’),
path(‘trades/’, views.trades, name=‘trades’),
path(‘signup/’, views.signup_view, name=‘signup’),
path(‘signals/’, views.signals, name=‘signals’),
path(‘logout_view/’, views.logout_view, name=‘logout’),
path(‘manage_apis/’, views.manage_apis, name=‘manage_apis’),
#path(‘api/realtime_data/<str:symbol>/’, views.get_real_time_data, name=‘realtime_data’),
#path(‘toggle_demo_account/’, views.toggle_demo_account, name=‘toggle_demo_account’),
#path(‘toggle_autotrader/’, views.toggle_autotrader, name=‘toggle_autotrader’),
]

2. Django consumers.py:
from channels.generic.websocket import AsyncWebsocketConsumer
import json

from CryptoBot.trading.PriceActionLogic import PriceActionSignalGenerator

class PriceConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.symbol = self.scope[‘url_route’][‘kwargs’][‘symbol’]
self.group_name = f’crypto_{self.symbol}‘

await self.channel_layer.group_add(
self.group_name,
self.channel_name
)

await self.accept()

async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.group_name,
self.channel_name
)

#async def receive(self, text_data):
# Handle incoming WebSocket messages if needed
#pass

async def send_price_update(self, event):
price_data = event[‘data’]
print(f"Received price data: {price_data}“)

# Convert to suitable DataFrame format
# Using your signal generator
signal_generator = PriceActionSignalGenerator()
signals = signal_generator.generate_trading_signals

# Log or send the signals elsewhere as needed
print(f"Generated Signals for {self.symbol}: {signals}”)
await self.send(text_data=json.dumps(event[‘data’]))

3. JavaScript File:
document.addEventListener(‘DOMContentLoaded’, (event) => {
document.getElementById(‘demo-account-switch’).addEventListener(‘change’, function() {
fetch(’/api/toggle_demo_account’, { method: ‘POST’ })
.then(response => {
if (response.ok) {
alert(‘Demo account setting updated’);
} else {
alert(‘Failed to update demo account setting’);
}
});
});

document.getElementById(‘autotrader-switch’).addEventListener(‘change’, function() {
fetch(‘/api/toggle_autotrader’, { method: ‘POST’ })
.then(response => {
if (response.ok) {
alert(‘Autotrader setting updated’);
} else {
alert(‘Failed to update autotrader setting’);
}
});
});

// Setup the candlestick chart
const ctx = document.getElementById(‘price-chart’).getContext(‘2d’);
const priceChart = new Chart(ctx, {
type: ‘candlestick’,
data: {
datasets: [{ label: ‘Price’,data: [],}]
},
options: {
scales: {
x: { type: ‘time’ },
y: { beginAtZero: false }
}
}
});



const symbol = document.getElementById(‘coin-select’).value;
//const ws_path = ‘ws://localhost:8000/ws/price/{symbol}/';
//const ws_path ='ws://{window.location.protocol}//{window.location.hostname}/ws/price/{symbol.toLowerCase()}/’;
const ws_path = ws://${window.location.host}/ws/price/${symbol.toLowerCase()}/;
const socket = new WebSocket(ws_path);

socket.onopen = () => console.log(‘WebSocket connection established.’);


socket.onmessage = function(event) {
const data = JSON.parse(event.data);

// Append the new data
if(data && data.x && data.o && data.h && data.l && data.c) {
const newCandle = {
x: new Date(data.x),
o: data.o,
h: data.h,
l: data.l,
c: data.c
};

priceChart.data.datasets[0].data.push(newCandle);
priceChart.update();

document.getElementById(‘current-price’).textContent = data.c;
}
else {console.error(‘Unexpected data structure’, data)}
};

socket.onclose = function(event) {
console.error(‘WebSocket closed unexpectedly’);
};
socket.onerror = (error) => {
console.error(‘WebSocket error:’, error);
};
});

4. Settings
“”“
Django settings for CryptoBot project.

Generated by ‘django-admin startproject’ using Django 5.1.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
”“”

from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / ‘subdir’.
####BASE_DIR = Path(file).resolve().parent.parent
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ‘django-insecure-o37zxon!g+b=!9jw#kk+v&9+eg6iy)j3+bqz#^43wo!qw^jn’

# SECURITY WARNING: don’t run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘trading’,
‘channels’,
]

MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
###‘django.middleware.session.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]
CSP_DEFAULT_SRC = (“‘self’”,)
CSP_SCRIPT_SRC = (“‘self’”, ‘https://trusted-external-source.com’)
#CSP_SCRIPT_SRC = [“‘unsafe-eval’”, “‘unsafe-inline’”, ‘*’]


ROOT_URLCONF = ‘CryptoBot.urls’
CELERY_BROKER_URL = ‘redis://localhost:6379/0’
CELERY_RESULT_BACKEND = ‘redis://localhost:6379/0’

TEMPLATES = [
{ ‘DIRS’: [os.path.join(BASE_DIR, ‘trading/templates’)],
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
####‘DIRS’: [],
‘APP_DIRS’: True,
‘OPTIONS’: {
‘context_processors’: [
‘django.template.context_processors.debug’,
‘django.template.context_processors.request’,
‘django.contrib.auth.context_processors.auth’,
‘django.contrib.messages.context_processors.messages’,
],
},
},
]

WSGI_APPLICATION = ‘CryptoBot.wsgi.application’

ASGI_APPLICATION = ‘CryptoBot.asgi.application’

CHANNEL_LAYERS = {
‘default’: {
‘BACKEND’: ‘channels.layers.InMemoryChannelLayer’,
###Will use Redis server later on, wen LIVE
},
}


# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases

DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.sqlite3’,
‘NAME’: os.path.join(BASE_DIR, ‘db.sqlite3’),
}
}


# Password validation
# https://docs.djangoproject.com/en/5.1/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
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = ‘en-us’

TIME_ZONE = ‘UTC’

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/

STATIC_URL = ‘/static/’
STATICFILES_DIRS = [
os.path.join(BASE_DIR, ‘static’)
]
STATIC_ROOT = os.path.join(BASE_DIR, ‘staticfiles’)

# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = ‘django.db.models.BigAutoField’

6. asgi.py File:
“”“
ASGI config for CryptoBot project.

It exposes the ASGI callable as a module-level variable named application.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
”“”

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘CryptoBot.settings’)

application = get_asgi_application()

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import trading.routing

os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘CryptoBot.settings’)

application = ProtocolTypeRouter({
“http”: get_asgi_application(),
“websocket”: AuthMiddlewareStack(
URLRouter(
trading.routing.websocket_urlpatterns
)
),
})

Using the above information, can you tell me what causes the issues below and ways to resolve it
The logs in my terminal show several HTTP requests and responses, including a WebSocket connection attempt that resulted in a 404 Not Found error. Let’s break down the relevant parts:

HTTP Requests:
The first few lines show HTTP GET requests for the main page (/) and static resources (/static/realdata.js, /static/styles.css, /static/favicon-32x32.png, /static/site.webmanifest).
WebSocket Connection Attempt:
The logs indicate that a WebSocket connection attempt was made to /ws/price/{symbol}/. The URL is dynamically generated, and the placeholder{symbol} is replaced with the actual symbol value (e.g., btcusdt).
404 Not Found Error:
The server responded with a 404 Not Found error for the WebSocket connection attempt. This means that the server could not find the requested resource at the specified URL.
Warning Message:
The warning message Not Found: /ws/price/${symbol}/ indicates that the server could not find the resource at the specified URL.

how can I resolve this