Help me what is wrong here: 

 

20250331 14:03:03.150 ERROR:: Extensions.SetRuntimeError(): Extensions.SetRuntimeError(): RuntimeError at 03/28/2025 04:00:00 UTC. 
Context: Consolidators update System.InvalidCastException: Specified cast is not valid.
  at Python.Runtime.PyObject.ToDecimal(IFormatProvider provider)
  at QuantConnect.StringExtensions.ConvertInvariant(Object value, Type conversionType) in Common/StringExtensions.cs:line 108
  at QuantConnect.StringExtensions.ConvertInvariant[T](Object value) in Common/StringExtensions.cs:line 38
  at QuantConnect.Data.Consolidators.DynamicDataConsolidator.GetNamedPropertyOrValueProperty(DynamicData data, String propertyName) in
Common/Data/Consolidators/DynamicDataConsolidator.cs:line 112
  at QuantConnect.Data.Consolidators.DynamicDataConsolidator.AggregateBar(TradeBar& workingBar, DynamicData data) in
Common/Data/Consolidators/DynamicDataConsolidator.cs:line 73
  at QuantConnect.Data.Consolidators.PeriodCountConsolidatorBase`2.Update(T data) in Common/Data/Consolidators/PeriodCountConsolidatorBase.cs:line 
208
  at QuantConnect.Data.Consolidators.DataConsolidator`1.Update(IBaseData data) in Common/Data/Consolidators/DataConsolidator.cs:line 41
  at QuantConnect.Lean.Engine.AlgorithmManager.Run(AlgorithmNodePacket job, IAlgorithm algorithm, ISynchronizer synchronizer, ITransactionHandler  
transactions, IResultHandler results, IRealTimeHandler realtime, ILeanManager leanManager, CancellationTokenSource cancellationTokenSource) in      
Engine/AlgorithmManager.cs:line 420 

 

# region imports
from AlgorithmImports import *
# endregion
from dydx_perpetual_data import DydxPerpetualData
import os
class DydxTestAlgorithm(QCAlgorithm):
   def initialize(self):
       self.set_start_date(2025, 3, 28)
       self.set_end_date(2025, 3, 31)
       self.set_cash(100000)
       symbolBTC = "BTC-USD"
       symbolETH = "ETH-USD"
       self._btc_symbol = self.add_data(DydxPerpetualData, symbolBTC, Resolution.MINUTE).symbol
       self._eth_symbol = self.add_data(DydxPerpetualData, symbolETH, Resolution.MINUTE).symbol
       self.set_benchmark(symbolBTC)
       self.set_benchmark(symbolETH)
       self._btc_short_ma = self.sma(self._btc_symbol, 60)
       self._btc_long_ma = self.sma(self._btc_symbol, 240)
       self._eth_short_ma = self.sma(self._eth_symbol, 60)
       self._eth_long_ma = self.sma(self._eth_symbol, 240)

   def on_data(self, data: Slice):
       if not (self._btc_symbol in data and self._eth_symbol in data):
           return
       btc_bullish_trend = self._btc_short_ma.current.value > self._btc_long_ma.current.value
       btc_current_price = data[self._btc_symbol].close
       if btc_bullish_trend and not self.portfolio[self._btc_symbol].invested:
           self.set_holdings(self._btc_symbol, 0.5)
       elif not btc_bullish_trend and self.portfolio[self._btc_symbol].invested:
           self.liquidate(self._btc_symbol)
       eth_bullish_trend = self._eth_short_ma.current.value > self._eth_long_ma.current.value
       eth_current_price = data[self._eth_symbol].close
       if eth_bullish_trend and not self.portfolio[self._eth_symbol].invested:
           self.set_holdings(self._eth_symbol, 0.5)
       elif not eth_bullish_trend and self.portfolio[self._eth_symbol].invested:
           self.liquidate(self._eth_symbol)

 

import os
from datetime import datetime
from QuantConnect import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from QuantConnect.Python import PythonData
from decimal import Decimal, InvalidOperation
class DydxPerpetualData(PythonData):
   def __init__(self):
       self.open = 0.0
       self.high = 0.0
       self.low = 0.0
       self.close = 0.0
       self.volume = 0.0
       self.openInterest = 0.0

   def get_source(self, config: SubscriptionDataConfig, date: datetime, isLiveMode: bool) -> SubscriptionDataSource:
       resolution = "1MIN" if config.Resolution == Resolution.MINUTE else "1DAY"
       symbol = config.Symbol.Value
       file_path = os.path.join(Globals.data_folder, "dydx", "perpetual", resolution, f"{symbol}.csv")
       # file_path = os.path.join("D:\\MyProjects\\doxia-investing\\DoxiaInvesting-QuantConnect-dYdx\\DydxBacktestingQuantConnect\\data\\dydx\\perpetual", resolution, f"{symbol}.csv")
       return SubscriptionDataSource(file_path, SubscriptionTransportMedium.LOCAL_FILE)
   def safe_decimal(self, value: str) -> Decimal:
       """Safely convert a string to Decimal, returning 0 on failure."""
       try:
           return Decimal(value.strip()) if value.strip() else Decimal(0)
       except (InvalidOperation, ValueError, TypeError):
           return Decimal(0)
   def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, isLiveMode: bool) -> BaseData:
       if not line or line.startswith("Date"):
           return None
       data = DydxPerpetualData()
       parts = line.split(',')
       try:
           data.time = datetime.strptime(parts[0], "%Y%m%d %H:%M")
           data.open = self.safe_decimal(parts[1])
           data.high = self.safe_decimal(parts[2])
           data.low = self.safe_decimal(parts[3])
           data.close = self.safe_decimal(parts[4])
           data.volume = self.safe_decimal(parts[5])
           data.openInterest = self.safe_decimal(parts[6])
           data.symbol = config.Symbol
           data.value = data.close
           return data
       except Exception as e:
           # self.Log(f"Error parsing line: {line}. Exception: {str(e)}")
           return None