Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
10000.00
End Equity
10000
Net Profit
0%
Sharpe Ratio
0
Sortino Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
# region imports
from AlgorithmImports import *
# endregion
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity

# Import libraries
import pandas as pd
import numpy as np
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score
from statistics import mean
from sklearn.preprocessing import OneHotEncoder, LabelEncoder, MinMaxScaler, label_binarize
from sklearn.model_selection import train_test_split, learning_curve
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
from sklearn.metrics import classification_report, accuracy_score, confusion_matrix, ConfusionMatrixDisplay, precision_recall_fscore_support, precision_score, recall_score
from sklearn.metrics import precision_recall_fscore_support as score

import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime

import plotly.graph_objects as go

class CryptoAIScapping(QCAlgorithm):
    def initialize(self):
        self.set_warm_up(100, Resolution.DAILY)
        self.set_start_date(2024, 10, 28)
        self.set_end_date(2024, 10, 30)
        self.set_cash(10000)
        self.crypto_symbol = self.add_crypto("BTCUSD", Resolution.MINUTE).symbol
        self.crypto_history = self.history("BTCUSD", 3, Resolution.MINUTE)
        self.quote_bar_window = RollingWindow[QuoteBar](3)
        self.set_risk_management(MaximumDrawdownPercentPerSecurity(0.20))

        # Correct method calls for indicators
        self.std = self.std(self.crypto_symbol, 22)
        self.rsi = self.rsi(self.crypto_symbol, 14)
        self.atr = self.aroon(self.crypto_symbol, 10, 20)
        self.aroon = self.aroon(self.crypto_symbol, 10, 20) # Corrected to include both up and down periods
        self.macd = self.macd(self.crypto_symbol, 12, 26, 9, MovingAverageType.Exponential)

        self.set_benchmark("BTCUSD")

    def on_data(self, data):
        if self.is_warming_up:
            return

        for quote_bar in self.crypto_history:
            self.quote_bar_window.add(quote_bar)

        if not self.quote_bar_window.is_ready:
            return

        if not all([self.rsi.IsReady, self.atr.IsReady, self.aroon.IsReady, self.macd.IsReady]):
            return

        Bar0 = self.quote_bar_window[0]  # Current bar has index zero.
        Bar1 = self.quote_bar_window[1]  # Previous bar has index one.
        Bar2 = self.quote_bar_window[2]  # Bar from two periods ago

        # Compute the difference between the current close and the previous close
        close_diff0 = Bar0.close - Bar1.close
        close_diff1 = Bar1.close - Bar2.close

        # Compute the difference between the current volume and the previous volume
        volume_diff0 = Bar0.volume - Bar1.volume
        volume_diff1 = Bar1.volume - Bar2.volume

        close_spread_AB0 = Bar0.ask.close - Bar1.bid.close
        close_spread_AB1 = Bar1.ask.close - Bar2.bid.close

        size_spread_AB0 = Bar0.last_ask_size - Bar1.last_bid_size
        size_spread_AB1 = Bar1.last_ask_size - Bar2.last_bid_size

        ask_rangeOC_0 = Bar0.askopen - Bar0.askclose
        ask_rangeHL_0 = Bar0.askhigh - Bar0.asklow
        ask_rangeHC_0 = Bar0.askhigh - Bar0.askclose
        ask_rangeHO_0 = Bar0.askhigh - Bar0.askopen
        ask_rangeOL_0 = Bar0.askopen - Bar0. asklow
        ask_rangeCL_0 = Bar0.askclose - Bar0.asklow

        ask_rangeOC_1 = Bar1.askopen - Bar1.askclose
        ask_rangeHL_1 = Bar1.askhigh - Bar1.asklow
        ask_rangeHC_1 = Bar1.askhigh - Bar1.askclose
        ask_rangeHO_1 = Bar1.askhigh - Bar1.askopen
        ask_rangeOL_1 = Bar1.askopen - Bar1. asklow
        ask_rangeCL_1 = Bar1.askclose - Bar1.asklow

        bid_rangeOC_0 = Bar0.bidopen - Bar0.bidclose
        bid_rangeHL_0 = Bar0.bidhigh - Bar0.bidlow
        bid_rangeHC_0 = Bar0.bidhigh - Bar0.bidclose
        bid_rangeHO_0 = Bar0.bidhigh - Bar0.bidopen
        bid_rangeOL_0 = Bar0.bidopen - Bar0.bidlow
        bid_rangeCL_0 = Bar0.bidclose - Bar0.bidlow

        bid_rangeOC_1 = Bar1.bidopen - Bar1.bidclose
        bid_rangeHL_1 = Bar1.bidhigh - Bar1.bidlow
        bid_rangeHC_1 = Bar1.bidhigh - Bar1.bidclose
        bid_rangeHO_1 = Bar1.bidhigh - Bar1.bidopen
        bid_rangeOL_1 = Bar1.bidopen - Bar1.bidlow
        bid_rangeCL_1 = Bar1.bidclose - Bar1.bidlow

        rangeOC_0 = Bar0.open - Bar0.close
        rangeHL_0 = Bar0.high - Bar0.low
        rangeHC_0 = Bar0.high - Bar0.close
        rangeHO_0 = Bar0.high - Bar0.open
        rangeOL_0 = Bar0.open - Bar0.low 
        rangeCL_0 = Bar0.close - Bar0.low 

        rangeOC_1 = Bar1.open - Bar1.close
        rangeHL_1 = Bar1.high - Bar1.low
        rangeHC_1 = Bar1.high - Bar1.close
        rangeHO_1 = Bar1.high - Bar1.open
        rangeOL_1 = Bar1.open - Bar1.low 
        rangeCL_1 = Bar1.close - Bar1.low 

        rsi_0 = self.rsi.current.value
        rsiAL_0 = self.rsi.average_loss.current.value
        rsiAG_0 = self.rsi.average_gain.current.value

        rsi_1 = self.rsi[1].value
        rsiAL_1 = self.rsi.average_loss[1].value
        rsiAG_1 = self.rsi.average_gain[1].value

        atr_0 = self.atr.current.value
        atrTR_0 = self.atr.true_range.current.value

        atr_1 = self.atr[1].value
        atrTR_1 = self.atr.true_range[1].value

        aroon_0 = self.aroon.current.value
        aroonUP_0 = self.aroon.aroon_up.current.value
        aroonDWN_0 = self.aroon.aroon_down.current.value

        aroon_1 = self.aroon[1].value
        aroonUP_1 = self.aroon.aroon_up[1].value
        aroonDWN_1 = self.aroon.aroon_down[1].value

        macd_0 = self.macd.current.value
        macdFS_0 = self.macd.fast.current.value
        macdSL_0 = self.macd.slow.current.value
        macdSG_0 = self.macd.signal.current.value
        macdHST_0 = self.macd.histogram.current.value
        
        macd_1 = self.macd.previous.value
        macdFS_1 = self.macd.fast.previous.value
        macdSL_1 = self.macd.slow.previous.value
        macdSG_1 = self.macd.signal.previous.value
        macdHST_1 = self.macd.histogram.previous.value

        std1 = self.std.current.value

        if close_diff1 < -1*std1:
            pricestrength_1 = -3
        elif close_diff1 < -0.15*std1:
            pricestrength_1 = -2
        elif close_diff1 < 0:
            pricestrength_1 = -1
        elif close_diff1 < 0.15*std1:
            pricestrength_1 = 1
        elif close_diff1 < 1*std1:
            pricestrength_1 = 2
        else:
            pricestrength_1 = 2

        inputData = [rsiAG_1, rsiAL_1, rsi_1, atr_1, atrTR_1, aroonDWN_1, aroonUP_1, aroon_1, macd_1, macdFS_1, macdHST_1, macdSG_1, macdSL_1, close_spread_AB1, size_spread_AB1,
        ask_rangeOC_1, ask_rangeHL_1, ask_rangeHC_1, ask_rangeHO_1, ask_rangeOL_1, ask_rangeCL_1, bid_rangeOC_1, bid_rangeHL_1, bid_rangeHC_1, bid_rangeHO_1, bid_rangeOL_1, 
        bid_rangeCL_1, rangeOC_1, rangeHL_1, rangeHC_1, rangeHO_1, rangeOL_1, rangeCL_1, volume_diff1, close_diff1, pricestrength_1, rsiAG_0, rsiAL_0, rsi_0, atr_0, 
        atrTR_0, aroonDWN_0, aroonUP_0, aroon_0, macd_0, macdFS_0, macdHST_0, macdSG_0, macdSL_0, close_spread_AB0, size_spread_AB0, ask_rangeOC_0, ask_rangeHL_0, ask_rangeHC_0,
        ask_rangeHO_0, ask_rangeOL_0, ask_rangeCL_0, bid_rangeOC_0, bid_rangeHL_0, bid_rangeHC_0, bid_rangeHO_0, bid_rangeOL_0, bid_rangeCL_0, rangeOC_0, rangeHL_0, rangeHC_0,
        rangeHO_0, rangeOL_0, rangeCL_0, volume_diff0]

        # Create a MinMaxScaler object
        scaler = MinMaxScaler()

        # Scaling the raw input features
        inputData = scaler.fit_transform(inputData)

        odd_ratios = l1_model.predict_proba(inputData)

        self.debug(f'The odd ratios {odd_ratios}')

        Buy = 0
        Sell = 0

        if (odd_ratios[1] + odd_ratios[3]) > 0.55:
            Buy = 1
        elif (odd_ratios[0] + odd_ratios[2]) > 0.55:
            Sell = 1
            
        holdings = self.portfolio[self.cryptoSymbol]
        
        if Buy:
            if holdings.invested:
                if holdings.is_short:
                    if holdings.profit > 0:
                        self.debug(f'Liquidate holdings at Profit {holdings.profit}')
                    elif holdings.profit < 0:
                        self.debug(f'Liquidate holdiings at Loss {holdings.profit}')
                    self.liquidate(self.cryptoSymbol)
            self.set_holdings(self.cryptoSymbol, 0.10)
            self.debug(f'Long position at {holdings.price}')
            takeProfitLg = Price + 0.25*std1
            stopLossLg = Price - 1*std1
        elif Sell:
            if holdings.invested:
                if holdings.is_long:
                    if holdings.profit > 0:
                        self.debug(f'Liquidate holdings at Profit {holdings.profit}')
                    elif holdings.profit < 0:
                        self.debug(f'Liquidate holdings at Loss {holdings.profit}')
                    self.liquidate(self.cryptoSymbol)
            self.set_holdings(self.cryptoSymbol, -0.10)
            self.debug(f'Short position at {holdings.price}')            
            takeProfitShrt = Price - 0.25*std1
            stopLossShrt = Price + 1*std1
        else:
            if holdings.invested:
                if holdings.is_short:
                    if holdings.price < takeProfitShrt and (odd_ratios[1] + odd_ratios[3] + odd_ratios[4] + odd_ratios[5]) > 0.50:
                        self.debug(f'Liquidate holdings at Profit {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)
                    elif holdings.price > stopLossShrt and (odd_ratios[0] + odd_ratios[2] ) < 0.50:
                        self.debug(f'Liquidate holdings at Loss {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)
                    elif odd_ratios[5] > 0.3:         
                        self.debug(f'Liquidate holdings at {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)
                if holdings.is_long:
                    if holdings.price > takeProfitLg and (odd_ratios[0] + odd_ratios[2] + odd_ratios[4] + odd_ratios[5]) > 0.50:
                        self.debug(f'Liquidate holdings at Profit {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)
                    elif holdings.price < stopLossLg and (odd_ratios[1] + odd_ratios[3] ) < 0.50:
                        self.debug(f'Liquidate holdings at Loss {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)
                    elif odd_ratios[4] > 0.3:         
                        self.debug(f'Liquidate holdings at {holdings.profit}')
                        self.liquidate(self.cryptoSymbol)