"<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BTCUSDC Moving Average and Derivatives with Trading Simulation</title>
    <!-- Include Chart.js (Latest Version) -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <!-- Include Chart.js Zoom Plugin (Latest Version) -->
    <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
</head>
<body>
    <h1>BTCUSDC Moving Average and Derivatives with Trading Simulation</h1>
    <label for="startDate">Start Date:</label>
    <input type="date" id="startDate" value="2023-11-01">
    <label for="endDate">End Date:</label>
    <input type="date" id="endDate" value="2023-11-05">
    <button id="fetchData">Fetch Data</button>
    <canvas id="chart" width="800" height="400"></canvas>

    <script>
        // Function to initialize the default behavior on page load
        window.onload = function() {
            main();
        };

        document.getElementById('fetchData').addEventListener('click', function() {
            main();
        });

        async function main() {
            const startDateInput = document.getElementById('startDate').value;
            const endDateInput = document.getElementById('endDate').value;

            // Convert dates to Unix timestamps in milliseconds
            const startTime = new Date(startDateInput).getTime();
            const endTime = new Date(endDateInput).getTime();

            // Fetch BTCUSDC 1-minute prices from Binance API
            const symbol = 'BTCUSDC';
            const interval = '1m';

            const klines = await fetchKlines(symbol, interval, startTime, endTime);

            if (klines.length === 0) {
                alert('No data available for the selected date range.');
                return;
            }

            // Extract closing prices and timestamps
            const timestamps = klines.map(k => k[0]); // Open time
            const closePrices = klines.map(k => parseFloat(k[4])); // Close price

            // Calculate 99-point moving average
            const ma99 = movingAverage(closePrices, 99);

            // Calculate first derivative of MA99
            const derivative = firstDerivative(ma99);

            // Calculate second derivative of MA99
            const secondDerivative = firstDerivative(derivative);

            // Calculate MA20 of the derivative
            const ma20Derivative = movingAverage(derivative, 99);

            // Calculate derivative of MA20 derivative
            const derivativeOfMA20Derivative = firstDerivative(ma20Derivative);

            // The earliest index where all data arrays have valid data
            const startingIndex = 119;

            // Prepare data for plotting
            const labels = timestamps.slice(startingIndex).map(ts => new Date(ts).toLocaleString());
            const priceData = closePrices.slice(startingIndex);
            const ma99Data = ma99.slice(startingIndex);
            const derivativeData = derivative.slice(startingIndex);
            const secondDerivativeData = secondDerivative.slice(startingIndex);
            const ma20DerivativeData = ma20Derivative.slice(startingIndex);
            const derivativeOfMA20DerivativeData = derivativeOfMA20Derivative.slice(startingIndex);

            // Simulate trading strategy
            const {specialPointsData, tradeSignals, profitLossData, cumulativeProfitLossData} = simulateTrading(
                priceData,
                derivativeData,
                secondDerivativeData,
                derivativeOfMA20DerivativeData,ma99Data
            );

            // Plot the data
            plotData(
                labels,
                priceData,
                ma99Data,
                derivativeData,
                secondDerivativeData,
                ma20DerivativeData,
                derivativeOfMA20DerivativeData,
                specialPointsData,
                cumulativeProfitLossData
            );
        }

        async function fetchKlines(symbol, interval, startTime, endTime) {
            const limit = 1000; // Max limit per request
            let klines = [];
            let fetchTime = startTime;

            while (fetchTime < endTime) {
                 const url = `https://fapi.binance.com/fapi/v1/klines?symbol=${symbol}&interval=${interval}&startTime=${fetchTime}&endTime=${endTime}&limit=${limit}`;
        
                const response = await fetch(url);
                const data = await response.json();

                if (data.code) {
                    // Handle error
                    alert('Error fetching data: ' + data.msg);
                    break;
                }

                if (data.length === 0) {
                    break;
                }

                klines = klines.concat(data);
                fetchTime = data[data.length - 1][0] + 60000; // Next minute
            }

            return klines;
        }

        function movingAverage(data, windowSize) {
            let ma = [];
            for (let i = 0; i < data.length; i++) {
                if (i < windowSize - 1 || data[i] === null) {
                    ma.push(null); // Not enough data to calculate MA
                } else {
                    const windowData = data.slice(i - windowSize + 1, i + 1);
                    if (windowData.includes(null)) {
                        ma.push(null); // Moving average cannot be calculated with null values
                    } else {
                        const sum = windowData.reduce((acc, val) => acc + val, 0);
                        ma.push(sum / windowSize);
                    }
                }
            }
            return ma;
        }

        function firstDerivative(data) {
            let derivative = [];
            for (let i = 0; i < data.length; i++) {
                if (i === 0 || data[i - 1] === null || data[i] === null) {
                    derivative.push(null); // Cannot calculate derivative
                } else {
                    derivative.push(data[i] - data[i - 1]);
                }
            }
            return derivative;
        }

        function simulateTrading(priceData, derivativeData, secondDerivativeData, derivativeOfMA20DerivativeData,ma99) {
            let specialPointsData = [];
            let tradeSignals = [];
            let position = 0; // BTC holdings
            let cash = 0; // USDC balance (we start with 0 for tracking profit/loss)
            let cumulativeProfitLoss = 0;
            let profitLossData = []; // Profit/Loss at each time point
            let cumulativeProfitLossData = []; // Cumulative Profit/Loss over time

            for (let i = 0; i < priceData.length; i++) {
                // Initialize profit/loss to previous value
                if (i === 0) {
                    profitLossData.push(0);
                } else {
                    profitLossData.push(cumulativeProfitLossData[i - 1]);
                }

                // Buy condition with new criterion
                if (
                    derivativeData[i] !== null &&
                    secondDerivativeData[i] !== null &&
                    derivativeOfMA20DerivativeData[i] !== null &&
                    derivativeData[i] < -5 &&
                    secondDerivativeData[i] > 0 &&
                    derivativeOfMA20DerivativeData[i] < -0.1 && ma99[i]>priceData[i]
                ) {
                    // Buy signal
                    if (position === 0) {
                        // Buy BTC worth 50 USDC
                        let btcBought = 50 / priceData[i];
                        position += btcBought;
                        cash -= 50; // We spend 50 USDC
                        tradeSignals.push({type: 'buy', index: i, price: priceData[i]});
                    }
                    specialPointsData.push(priceData[i]); // Mark special point
                } else {
                    specialPointsData.push(null);
                }

                // Sell condition: derivative becomes greater than 0
                if (position > 0 && priceData[i]>ma99[i]) {
                    // Sell all BTC holdings
                    let proceeds = position * priceData[i];
                    cash += proceeds;
                    let profit = cash + (position * priceData[i]) - 50; // Profit from this trade
                    cumulativeProfitLoss += profit - (cumulativeProfitLossData[i - 1] || 0);
                    profitLossData[i] = cumulativeProfitLoss; // Update profit/loss at this point

                    position = 0; // Reset position
                    cash = 0; // Reset cash for next trade (since we started with 0)

                    tradeSignals.push({type: 'sell', index: i, price: priceData[i]});
                }

                cumulativeProfitLossData.push(cumulativeProfitLoss);
            }

            return {specialPointsData, tradeSignals, profitLossData, cumulativeProfitLossData};
        }

        function plotData(labels, priceData, ma99Data, derivativeData, secondDerivativeData, ma20DerivativeData, derivativeOfMA20DerivativeData, specialPointsData, cumulativeProfitLossData) {
            const ctx = document.getElementById('chart').getContext('2d');

            // Create an array of zeros for the zero line
            const zeroData = labels.map(() => 0);

            // Clear existing chart if any
            if (window.myChart instanceof Chart) {
                window.myChart.destroy();
            }

            // Register the zoom plugin (necessary in Chart.js v4)
            Chart.register(ChartZoom);

            window.myChart = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: [
                        {
                            label: 'Actual Price',
                            data: priceData,
                            borderColor: 'black',
                            fill: false,
                            yAxisID: 'y',
                            pointRadius: 0, // Prevent default points
                        },
                        {
                            label: 'Moving Average (99)',
                            data: ma99Data,
                            borderColor: 'blue',
                            fill: false,
                            yAxisID: 'y',
                            pointRadius: 0,
                        },
                        {
                            label: 'First Derivative',
                            data: derivativeData,
                            borderColor: 'green',
                            fill: false,
                            yAxisID: 'y1',
                            pointRadius: 0,
                        },
                        {
                            label: 'Second Derivative',
                            data: secondDerivativeData,
                            borderColor: 'red',
                            fill: false,
                            yAxisID: 'y1',
                            pointRadius: 0,
                        },
                        // Add the zero line for derivative axis
                        {
                            label: 'Derivative Zero Line',
                            data: zeroData,
                            borderColor: 'gray',
                            borderDash: [5, 5],
                            pointRadius: 0,
                            borderWidth: 1,
                            fill: false,
                            yAxisID: 'y1',
                        },
                        // New datasets for MA20 of derivative and its derivative
                        {
                            label: 'MA20 of Derivative',
                            data: ma20DerivativeData,
                            borderColor: 'magenta',
                            fill: false,
                            yAxisID: 'y1',
                            pointRadius: 0,
                        },
                        {
                            label: 'Derivative of MA20 of Derivative',
                            data: derivativeOfMA20DerivativeData,
                            borderColor: 'cyan',
                            fill: false,
                            yAxisID: 'y1',
                            pointRadius: 0,
                        },
                        // New dataset for special points
                        {
                            label: 'Special Points (Buy Signal)',
                            data: specialPointsData,
                            borderColor: 'purple',
                            backgroundColor: 'purple',
                            pointRadius: 5, // Size of the dot
                            pointHoverRadius: 7,
                            showLine: false,
                            yAxisID: 'y',
                            type: 'line', // Ensure it aligns with the chart type
                        },
                        // Dataset for cumulative profit/loss
                        {
                            label: 'Cumulative Profit/Loss',
                            data: cumulativeProfitLossData,
                            borderColor: 'orange',
                            fill: false,
                            yAxisID: 'y2',
                            pointRadius: 0,
                            borderWidth: 2,
                            tension: 0.1,
                        },
                    ]
                },
                options: {
                    responsive: true,
                    interaction: {
                        mode: 'index',
                        intersect: false,
                    },
                    stacked: false,
                    plugins: {
                        zoom: {
                            pan: {
                                enabled: true,
                                mode: 'x',
                                modifierKey: null, // Allows panning without modifier key
                            },
                            zoom: {
                                wheel: {
                                    enabled: true,
                                },
                                pinch: {
                                    enabled: true,
                                },
                                mode: 'x',
                            },
                        },
                    },
                    scales: {
                        x: {
                            display: true,
                            ticks: {
                                maxRotation: 90,
                                minRotation: 90,
                                maxTicksLimit: 20,
                            }
                        },
                        y: {
                            type: 'linear',
                            display: true,
                            position: 'left',
                            title: {
                                display: true,
                                text: 'Price / Moving Average'
                            }
                        },
                        y1: {
                            type: 'linear',
                            display: true,
                            position: 'right',
                            grid: {
                                drawOnChartArea: false,
                            },
                            title: {
                                display: true,
                                text: 'Derivatives'
                            }
                        },
                        y2: {
                            type: 'linear',
                            display: true,
                            position: 'right',
                            grid: {
                                drawOnChartArea: false,
                            },
                            title: {
                                display: true,
                                text: 'Cumulative Profit/Loss (USDC)'
                            },
                            ticks: {
                                // Include USDC symbol
                                callback: function(value, index, ticks) {
                                    return '$' + value.toFixed(2);
                                }
                            },
                            // Offset the scale to the right
                            offset: true,
                        },
                    }
                }
            });

            // Add double-click event listener to reset zoom
            const canvas = document.getElementById('chart');
            canvas.addEventListener('dblclick', function(){
                window.myChart.resetZoom();
            });
        }

        // Automatically fetch data on page load
        // (Already called inside window.onload)
    </script>
</body>
</html>" this is my btcusdc futures strategy testing code. but its profit loss system is broken, rewrite it such that initial amount is 500 usdc. and i want you to calculate the value of the assets for my strategy. draw value of assets in terms of usdc.