Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
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.436
Tracking Error
0.191
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
from AlgorithmImports import *

class ForexCFDAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2016, 1, 1)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
        self.month_end_window = RollingWindow[TradeBar](2)  # For monthly EMA

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5  # Define basket size
        self.atr_multiplier_for_space = 1  # Define ATR multiplier for spacing
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0

        # Initialize monthly EMA
        self.monthly_ema = self.EMA(self.symbol, 30, Resolution.Daily)  # 30 days for a rough monthly EMA

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Add the daily bar to the rolling window for monthly EMA calculation
        self.month_end_window.Add(self.CurrentSlice[symbol])

        # Update the monthly EMA at the end of each month
        if self.month_end_window.IsReady and self.Time.month != self.month_end_window[0].EndTime.month:
            monthly_close = self.month_end_window[0].Close
            self.monthly_ema.Update(self.month_end_window[0].EndTime, monthly_close)

        # Update long-term bullish/bearish based on monthly EMA
        if self.month_end_window.IsReady and self.monthly_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.monthly_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            self.Debug(f"No data for {self.symbol.Value}")
            return
        
        self.Log("OnData called")
        
        if not self.symbol in data:
            self.Log(f"No data for {self.symbol}")
            return

        if self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter long position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Long', data)
        elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter short position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Short', data)
        else:
            self.Log(f"Position entry skipped. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")

    def EnterPosition(self, direction, data):
        if self.open_positions < self.basket_size:
            lot_size = 0.05  # Define lot size
            self.Log(f"Entering {direction} position: Lot Size: {lot_size}")
            if direction == 'Long':
                self.Buy(self.symbol, lot_size)
            elif direction == 'Short':
                self.Sell(self.symbol, lot_size)
            
            self.batch_positions.append(self.symbol)
            self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))  # Include direction
            self.open_positions += 1
            self.last_basket_position_time = self.Time
        else:
            self.Log("Position entry aborted. Max positions reached.")

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()

        ### Part 3: Risk Management
    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 5 * atr_value  # Example multiplier

        for price, size, direction in self.batch_entry_prices:  # Include direction in loop
            if direction == 'Long':
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif direction == 'Short':
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)
        
        current_price = data[self.symbol].Close
        if ((direction == 'Long' and current_price <= self.trailing_stop) or 
            (direction == 'Short' and current_price >= self.trailing_stop)):
            self.Liquidate(self.symbol)

    
from AlgorithmImports import *
from datetime import timedelta

class ForexCFDAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2016, 1, 1)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 14, Resolution.Daily)
        self.month_end_window = RollingWindow[TradeBar](2)
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5
        self.atr_multiplier_for_space = 1
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0
        self.last_10ema_cross = 'none'
        self.monthly_ema = self.EMA(self.symbol, 30, Resolution.Daily)

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return
        self.month_end_window.Add(self.CurrentSlice[symbol])
        if self.month_end_window.IsReady and self.Time.month != self.month_end_window[0].EndTime.month:
            monthly_close = self.month_end_window[0].Close
            self.monthly_ema.Update(self.month_end_window[0].EndTime, monthly_close)
        if self.month_end_window.IsReady and self.monthly_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.monthly_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            return

        current_price = data[self.symbol].Close
        if current_price > self.daily_ema.Current.Value:
            self.last_10ema_cross = 'above'
        elif current_price < self.daily_ema.Current.Value:
            self.last_10ema_cross = 'below'

        if self.ShouldStartNewBasket(current_price):
            self.StartNewBasket()
            self.EnterPosition(self.is_long_term_bullish, data)
        elif self.open_positions < self.basket_size and self.Time - self.last_basket_position_time > timedelta(minutes=120):
            distance = abs(current_price - self.batch_entry_prices[-1][0])
            if distance >= self.atr.Current.Value * self.atr_multiplier_for_space:
                self.EnterPosition(self.is_long_term_bullish, data)

    def EnterPosition(self, is_bullish, data):
        lot_size = 0.05
        direction = 'Long' if is_bullish else 'Short'
        self.batch_positions.append(self.symbol)
        self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
        self.open_positions += 1
        self.last_basket_position_time = self.Time
        if direction == 'Long':
            self.Buy(self.symbol, lot_size)
        else:
            self.Sell(self.symbol, lot_size)

    def ShouldStartNewBasket(self, current_price):
        if self.last_10ema_cross == 'none':
            return True
        if self.is_long_term_bullish and self.last_10ema_cross == 'below' and current_price > self.daily_ema.Current.Value:
            return True
        if not self.is_long_term_bullish and self.last_10ema_cross == 'above' and current_price < self.daily_ema.Current.Value:
            return True
        return False

    def StartNewBasket(self):
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.last_basket_position_time = self.Time

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()

        ### Part 3: Risk Management
    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 5 * atr_value  # Example multiplier

        for price, size, direction in self.batch_entry_prices:  # Include direction in loop
            if direction == 'Long':
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif direction == 'Short':
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)
        
        current_price = data[self.symbol].Close
        if ((direction == 'Long' and current_price <= self.trailing_stop) or 
            (direction == 'Short' and current_price >= self.trailing_stop)):
            self.Liquidate(self.symbol)

        #########Check for order events only - remove after checking########
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status == OrderStatus.Filled:
            self.Debug(str(orderEvent))
from AlgorithmImports import *
from datetime import timedelta

class ForexCFDAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2016, 1, 1)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)

        # Replace monthly EMA with daily 200 EMA for long-term trend
        self.long_term_ema = self.EMA(self.symbol, 200, Resolution.Daily)

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5  # Define basket size
        self.atr_multiplier_for_space = 1  # Define ATR multiplier for spacing
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Update long-term bullish/bearish based on daily 200 EMA
        if self.long_term_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.long_term_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            self.Debug(f"No data for {self.symbol.Value}")
            return
    
        self.Log("OnData called")
    
        if not self.symbol in data:
            self.Log(f"No data for {self.symbol}")
            return

        # Update long-term trend based on the 200-day EMA
        self.is_long_term_bullish = self.Securities[self.symbol].Price > self.daily_200ema.Current.Value

        # Check if the symbol's daily EMA is ready before proceeding
        if not self.daily_ema.IsReady:
            return

        # Logic to handle entry for both bullish and bearish trends
        if self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter long position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Long', data)
        elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter short position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Short', data)
        else:
            self.Log(f"Position entry skipped. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")

    def EnterPosition(self, is_bullish, data):
        lot_size = 0.05
        direction = 'Long' if is_bullish else 'Short'
        self.batch_positions.append(self.symbol)
        self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
        self.open_positions += 1
        self.last_basket_position_time = self.Time
        if direction == 'Long':
            self.Buy(self.symbol, lot_size)
        else:
            self.Sell(self.symbol, lot_size)

    def ShouldStartNewBasket(self, current_price):
        if self.last_10ema_cross == 'none':
            return True
        if self.is_long_term_bullish and self.last_10ema_cross == 'below' and current_price > self.daily_ema.Current.Value:
            return True
        if not self.is_long_term_bullish and self.last_10ema_cross == 'above' and current_price < self.daily_ema.Current.Value:
            return True
        return False

    def StartNewBasket(self):
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.last_basket_position_time = self.Time

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()

        ### Part 3: Risk Management
    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 5 * atr_value  # Example multiplier

        for price, size, direction in self.batch_entry_prices:  # Include direction in loop
            if direction == 'Long':
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif direction == 'Short':
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)
        
        current_price = data[self.symbol].Close
        if ((direction == 'Long' and current_price <= self.trailing_stop) or 
            (direction == 'Short' and current_price >= self.trailing_stop)):
            self.Liquidate(self.symbol)

 
from AlgorithmImports import *
from datetime import timedelta

class ForexCFDAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2016, 1, 1)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
        self.long_term_ema = self.EMA(self.symbol, 200, Resolution.Daily)

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5
        self.atr_multiplier_for_space = 1
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0
        self.last_10ema_cross = 'none'

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Update long-term bullish/bearish based on daily 200 EMA
        if self.long_term_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.long_term_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            return

        # Update ATR and ensure all indicators are ready
        if not self.daily_ema.IsReady or not self.atr.IsReady or not self.long_term_ema.IsReady:
            return

        current_price = data[self.symbol].Price

        # Update last 10 EMA cross state
        if current_price > self.daily_ema.Current.Value:
            self.last_10ema_cross = 'above'
        elif current_price < self.daily_ema.Current.Value:
            self.last_10ema_cross = 'below'

        # Check if conditions are met to start a new basket
        if self.ShouldStartNewBasket(current_price):
            self.StartNewBasket()

        # Logic to handle entry for both bullish and bearish trends
        if self.is_long_term_bullish and self.open_positions < self.basket_size:
            if self.CanEnterNewPosition(current_price, 'Long'):
                self.EnterPosition('Long', data)
        elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
            if self.CanEnterNewPosition(current_price, 'Short'):
                self.EnterPosition('Short', data)

    def EnterPosition(self, direction, data):
        lot_size = 0.05  # Adjust lot size as needed
        self.batch_positions.append(self.symbol)
        self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
        self.open_positions += 1
        self.last_basket_position_time = self.Time
        if direction == 'Long':
            self.Buy(self.symbol, lot_size)
        else:
            self.Sell(self.symbol, lot_size)

    def ShouldStartNewBasket(self, current_price):
        if self.last_10ema_cross == 'none':
            return False
        if self.is_long_term_bullish and self.last_10ema_cross == 'below' and current_price > self.daily_ema.Current.Value:
            return True
        if not self.is_long_term_bullish and self.last_10ema_cross == 'above' and current_price < self.daily_ema.Current.Value:
            return True
        return False

    def StartNewBasket(self):
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.last_basket_position_time = self.Time
    
    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Update long-term bullish/bearish based on daily 200 EMA
        if self.long_term_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.long_term_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            self.Debug(f"No data for {self.symbol.Value}")
            return

        self.Log("OnData called")
    
        if not self.symbol in data:
            self.Log(f"No data for {self.symbol}")
            return

        # Update long-term trend based on the 200-day EMA
        self.is_long_term_bullish = self.Securities[self.symbol].Price > self.long_term_ema.Current.Value

        # Check if the symbol's daily EMA is ready before proceeding
        if not self.daily_ema.IsReady:
            return

        # Logic to handle entry for both bullish and bearish trends
        if self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter long position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Long', data)
        elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
            self.Log(f"Trying to enter short position. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
            self.EnterPosition('Short', data)
        else:
            self.Log(f"Position entry skipped. Open Positions: {self.open_positions}, Basket Size: {self.basket_size}")
    
    def EnterPosition(self, direction, data):
        lot_size = 0.05  # Define lot size for each trade
        self.batch_positions.append(self.symbol)
        self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
        self.open_positions += 1
        self.last_basket_position_time = self.Time

        if direction == 'Long':
            self.Buy(self.symbol, lot_size)
        else:
            self.Sell(self.symbol, lot_size)

    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 5 * atr_value  # Example multiplier

        for price, size, direction in self.batch_entry_prices:
            if direction == 'Long':
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif direction == 'Short':
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)

        current_price = data[self.symbol].Close
        if ((direction == 'Long' and current_price <= self.trailing_stop) or 
            (direction == 'Short' and current_price >= self.trailing_stop)):
            self.Liquidate(self.symbol)

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()
from AlgorithmImports import *
from datetime import timedelta

class ForexCFDAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2016, 1, 1)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
        self.long_term_ema = self.EMA(self.symbol, 200, Resolution.Daily)

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5
        self.atr_multiplier_for_space = 1
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0
        self.last_10ema_cross = 'none'

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Update long-term bullish/bearish based on daily 200 EMA
        if self.long_term_ema.IsReady:
            self.is_long_term_bullish = self.Securities[self.symbol].Close > self.long_term_ema.Current.Value

    def OnData(self, data):
        if not data.ContainsKey(self.symbol):
            return

        # Update ATR and ensure all indicators are ready
        if not self.daily_ema.IsReady or not self.atr.IsReady or not self.long_term_ema.IsReady:
            return

        current_price = data[self.symbol].Price

        # Update last 10 EMA cross state
        if current_price > self.daily_ema.Current.Value:
            self.last_10ema_cross = 'above'
        elif current_price < self.daily_ema.Current.Value:
            self.last_10ema_cross = 'below'

        # Check if conditions are met to start a new basket
        if self.ShouldStartNewBasket(current_price):
            self.StartNewBasket()

        # Logic to handle entry for both bullish and bearish trends
        if self.is_long_term_bullish and self.open_positions < self.basket_size:
            if self.CanEnterNewPosition(current_price, 'Long'):
                self.EnterPosition('Long', data)
        elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
            if self.CanEnterNewPosition(current_price, 'Short'):
                self.EnterPosition('Short', data)

    def EnterPosition(self, direction, data):
        lot_size = self.CalculateLotSize()  # Calculate lot size based on risk management
        self.batch_positions.append(self.symbol)
        self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
        self.open_positions += 1
        self.last_basket_position_time = self.Time
        if direction == 'Long':
            self.Buy(self.symbol, lot_size)
        else:
            self.Sell(self.symbol, lot_size)

    def ShouldStartNewBasket(self, current_price):
        if self.last_10ema_cross == 'none':
            return False
        if self.is_long_term_bullish and self.last_10ema_cross == 'below' and current_price > self.daily_ema.Current.Value:
            return True
        if not self.is_long_term_bullish and self.last_10ema_cross == 'above' and current_price < self.daily_ema.Current.Value:
            return True
        return False

    def StartNewBasket(self):
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.last_basket_position_time = self.Time

    def CanEnterNewPosition(self, current_price, direction):
        if len(self.batch_entry_prices) == 0:
            return True

        last_entry_price, _, _ = self.batch_entry_prices[-1]
        elapsed_time = self.Time - self.last_basket_position_time

        # Check time delay and price distance
        if elapsed_time >= timedelta(minutes=120):
            atr_value = self.atr.Current.Value
            pip_distance = self.atr_multiplier_for_space * atr_value
            if direction == 'Long' and current_price - last_entry_price >= pip_distance:
                return True
            elif direction == 'Short' and last_entry_price - current_price >= pip_distance:
                return True

        return False

def CalculateLotSize(self):
    # Implement lot size calculation logic based on account value and risk management
    # Placeholder value
    return 0.05

def ExecuteTrailingStopLoss(self, data):
    if not self.atr.IsReady or len(self.batch_entry_prices) == 0:
        return

    atr_value = self.atr.Current.Value
    trailing_stop_distance = 0.5 * atr_value  # Trailing by 0.5x ATR

    # Calculate new trailing stop for each position
    for i in range(len(self.batch_entry_prices)):
        entry_price, lot_size, direction = self.batch_entry_prices[i]
        if direction == 'Long':
            # For long positions, trailing stop is below the entry price
            new_trailing_stop = entry_price + trailing_stop_distance
            if new_trailing_stop > self.trailing_stop:
                self.trailing_stop = new_trailing_stop
        elif direction == 'Short':
            # For short positions, trailing stop is above the entry price
            new_trailing_stop = entry_price - trailing_stop_distance
            if self.trailing_stop == 0 or new_trailing_stop < self.trailing_stop:
                self.trailing_stop = new_trailing_stop

    # Check if current price has hit the trailing stop
    current_price = data[self.symbol].Price
    if ((direction == 'Long' and current_price <= self.trailing_stop) or 
        (direction == 'Short' and current_price >= self.trailing_stop)):
        self.Liquidate(self.symbol)
        self.Debug("Trailing stop hit. Liquidating positions.")
#from AlgorithmImports import *
#from datetime import timedelta

#class ForexCFDAlgorithm(QCAlgorithm):
#   from AlgorithmImports import *

from AlgorithmImports import *

class ForexCFDAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2016, 5, 5)  # Start Date
        self.SetCash(50000)  # Set Strategy Cash
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol
        self.Debug("Initialization complete")

    def OnData(self, data):
        # Manual trigger for a long trade
        if self.Time.hour == 10 and not self.Portfolio.Invested:
            quantity = 1  # Positive for long position
            self.MarketOrder(self.symbol, quantity)
            self.Debug(f"Manual long trade executed for {self.symbol.Value}")
    
    
    #def Initialize(self):
    #    self.SetStartDate(2016, 1, 1)  # Start Date
    #    self.SetCash(50000)  # Set Strategy Cash

        # Forex symbol
    #    self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
    #    self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
    #    self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
    #    self.long_term_ema = self.EMA(self.symbol, 200, Resolution.Daily)

        # State variables
    #    self.is_long_term_bullish = False
    #    self.batch_positions = []
    #    self.batch_entry_prices = []
    #    self.open_positions = 0
    #    self.basket_size = 5
    #    self.atr_multiplier_for_space = 1
    #    self.last_basket_position_time = self.Time
    #    self.trailing_stop = 0
    #    self.last_10ema_cross = 'none'

    #def OnEndOfDay(self, symbol):
    #    if symbol != self.symbol:
    #        return

        # Update long-term bullish/bearish based on daily 200 EMA
    #    if self.long_term_ema.IsReady:
    #        self.is_long_term_bullish = self.Securities[self.symbol].Close > self.long_term_ema.Current.Value


    #def OnData(self, data):
        # Force open a position for testing
    #    if not self.Portfolio.Invested:
    #        self.MarketOrder(self.symbol, 0.05)  # Replace 'quantity' with the desired number of units
    #        self.Debug(f"Forced position opened for {self.symbol.Value}")

        
        #if not data.ContainsKey(self.symbol):
        #   return

        # Update ATR and ensure all indicators are ready
        #if not self.daily_ema.IsReady or not self.atr.IsReady or not self.long_term_ema.IsReady:
        #    return

        #current_price = data[self.symbol].Price

        # Update last 10 EMA cross state
        #if current_price > self.daily_ema.Current.Value:
        #    self.last_10ema_cross = 'above'
        #elif current_price < self.daily_ema.Current.Value:
        #    self.last_10ema_cross = 'below'

        # Check if conditions are met to start a new basket
        #if self.ShouldStartNewBasket(current_price):
        #    self.StartNewBasket()

        # Execute trailing stop loss logic
        #self.ExecuteTrailingStopLoss(data)

        # Logic to handle entry for both bullish and bearish trends
        #if self.is_long_term_bullish and self.open_positions < self.basket_size:
        #    if self.CanEnterNewPosition(current_price, 'Long'):
        #        self.EnterPosition('Long', data)
        #elif not self.is_long_term_bullish and self.open_positions < self.basket_size:
        #    if self.CanEnterNewPosition(current_price, 'Short'):
        #        self.EnterPosition('Short', data)

    #def EnterPosition(self, direction, data):
    #    lot_size = self.CalculateLotSize()  # Calculate lot size based on risk management
    #    self.batch_positions.append(self.symbol)
    #    self.batch_entry_prices.append((data[self.symbol].Close, lot_size, direction))
    #    self.open_positions += 1
    #    self.last_basket_position_time = self.Time
    #    if direction == 'Long':
    #        self.Buy(self.symbol, lot_size)
    #    else:
    #        self.Sell(self.symbol, lot_size)

    #def ShouldStartNewBasket(self, current_price):
    #    if self.last_10ema_cross == 'none':
    #        return False
    #    if self.is_long_term_bullish and self.last_10ema_cross == 'below' and current_price > self.daily_ema.Current.Value:
    #        return True
    #    if not self.is_long_term_bullish and self.last_10ema_cross == 'above' and current_price < self.daily_ema.Current.Value:
    #        return True
    #    return False

    #def StartNewBasket(self):
    #    self.batch_positions = []
    #    self.batch_entry_prices = []
    #    self.open_positions = 0
    #    self.last_basket_position_time = self.Time

    #def CanEnterNewPosition(self, current_price, direction):
    #    if len(self.batch_entry_prices) == 0:
    #        return True

    #    last_entry_price, _, _ = self.batch_entry_prices[-1]
    #    elapsed_time = self.Time - self.last_basket_position_time

        # Check time delay and price distance
    #    if elapsed_time >= timedelta(minutes=120):
    #        atr_value = self.atr.Current.Value
    #        pip_distance = self.atr_multiplier_for_space * atr_value
    #        if direction == 'Long' and current_price - last_entry_price >= pip_distance:
    #            return True
    #        elif direction == 'Short' and last_entry_price - current_price >= pip_distance:
    #            return True

    #    return False

#def CalculateLotSize(self):
    # Implement lot size calculation logic based on account value and risk management
    # Placeholder value
#    return 0.05

#def ExecuteTrailingStopLoss(self, data):
#    if not self.atr.IsReady or len(self.batch_entry_prices) == 0:
#        return

#    atr_value = self.atr.Current.Value
#    trailing_stop_distance = 0.5 * atr_value  # Trailing by 0.5x ATR

    # Calculate new trailing stop for each position
#    for i in range(len(self.batch_entry_prices)):
#        entry_price, lot_size, direction = self.batch_entry_prices[i]
#        if direction == 'Long':
            # For long positions, trailing stop is below the entry price
#            new_trailing_stop = entry_price + trailing_stop_distance
#            if new_trailing_stop > self.trailing_stop:
#                self.trailing_stop = new_trailing_stop
#        elif direction == 'Short':
            # For short positions, trailing stop is above the entry price
#            new_trailing_stop = entry_price - trailing_stop_distance
#            if self.trailing_stop == 0 or new_trailing_stop < self.trailing_stop:
#                self.trailing_stop = new_trailing_stop

    # Check if current price has hit the trailing stop
#    current_price = data[self.symbol].Price
#    if ((direction == 'Long' and current_price <= self.trailing_stop) or 
#        (direction == 'Short' and current_price >= self.trailing_stop)):
#        self.Liquidate(self.symbol)
#        self.Debug("Trailing stop hit. Liquidating positions.")
from AlgorithmImports import *

class ForexCFDAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Start Date
        self.SetCash(100000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
        self.month_end_window = RollingWindow[TradeBar](2)  # For monthly EMA

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5  # Define basket size
        self.atr_multiplier_for_space = 2  # Define ATR multiplier for spacing
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0

        # Initialize monthly EMA
        self.monthly_ema = self.EMA(self.symbol, 30, Resolution.Daily)  # 30 days for a rough monthly EMA

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Add the daily bar to the rolling window for monthly EMA calculation
        self.month_end_window.Add(self.CurrentSlice[symbol])

        # Update the monthly EMA at the end of each month
        if self.month_end_window.IsReady and self.Time.month != self.month_end_window[0].EndTime.month:
            monthly_close = self.month_end_window[0].Close
            self.monthly_ema.Update(self.month_end_window[0].EndTime, monthly_close)

    def OnData(self, data):
        # Ensure data for the symbol is available
        if not self.symbol in data:
            return

        # Update daily EMA and ATR
        if not self.daily_ema.Update(data[self.symbol]) or not self.atr.Update(data[self.symbol]):
            return

        # Update long-term bullish/bearish based on monthly EMA
        if self.month_end_window.IsReady and self.monthly_ema.IsReady:
            self.is_long_term_bullish = data[self.symbol].Close > self.monthly_ema.Current.Value

        # Position entry logic
        if (self.Time - self.last_basket_position_time).total_minutes() >= 120:
            if self.is_long_term_bullish and data[self.symbol].Close > self.daily_ema.Current.Value:
                self.EnterPosition('Long', data)
            elif not self.is_long_term_bearish and data[self.symbol].Close < self.daily_ema.Current.Value:
                    self.EnterPosition('Short', data)

        # Risk management
        if self.open_positions > 0:
            self.ExecuteTrailingStopLoss(data) 

    def EnterPosition(self, direction, data):
        self.Debug(f"Attempting to enter {direction} position")
        
        if self.open_positions < self.basket_size:
            if self.open_positions == 0 or (data[self.symbol].Close - self.batch_entry_prices[-1][0] >= self.atr.Current.Value * self.atr_multiplier_for_space):
                lot_size = 0.05  # Define lot size
                if direction == 'Long':
                    self.Buy(self.symbol, lot_size)
                else:
                    self.Sell(self.symbol, lot_size)

                # Update state variables
                self.batch_positions.append(self.symbol)
                self.batch_entry_prices.append((data[self.symbol].Close, lot_size))
                self.open_positions += 1
                self.last_basket_position_time = self.Time

                self.Debug(f"Position entered: {direction}, Lot size: {lot_size}, Open positions: {self.open_positions}")

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()

        ### Part 3: Risk Management
    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 3 * atr_value  # Example multiplier

        # Update trailing stop for each position
        for price, size in self.batch_entry_prices:
            if self.Portfolio[self.symbol].IsLong:
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif self.Portfolio[self.symbol].IsShort:
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)
    
        # Check and execute trailing stop
        current_price = data[self.symbol].Close
        if (self.Portfolio[self.symbol].IsLong and current_price <= self.trailing_stop) or \
           (self.Portfolio[self.symbol].IsShort and current_price >= self.trailing_stop):
            self.Liquidate(self.symbol)

    
from AlgorithmImports import *

class ForexCFDAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Start Date
        self.SetCash(100000)  # Set Strategy Cash

        # Forex symbol
        self.symbol = self.AddForex("EURUSD", Resolution.Daily).Symbol

        # Indicators
        self.daily_ema = self.EMA(self.symbol, 10, Resolution.Daily)
        self.atr = self.ATR(self.symbol, 100, Resolution.Daily)
        self.month_end_window = RollingWindow[TradeBar](2)  # For monthly EMA

        # State variables
        self.is_long_term_bullish = False
        self.batch_positions = []
        self.batch_entry_prices = []
        self.open_positions = 0
        self.basket_size = 5  # Define basket size
        self.atr_multiplier_for_space = 2  # Define ATR multiplier for spacing
        self.last_basket_position_time = self.Time
        self.trailing_stop = 0

    def OnEndOfDay(self, symbol):
        if symbol != self.symbol:
            return

        # Add the daily bar to the rolling window for monthly EMA calculation
        self.month_end_window.Add(self.CurrentSlice[symbol])

        # Update the monthly EMA at the end of each month
        if self.month_end_window.IsReady and self.Time.month != self.month_end_window[0].EndTime.month:
            monthly_close = self.month_end_window[0].Close
            self.monthly_ema.Update(self.month_end_window[0].EndTime, monthly_close)

    def OnData(self, data):
        # Ensure data for the symbol is available
        if not self.symbol in data:
            return

        # Update daily EMA and ATR
        if not self.daily_ema.Update(data[self.symbol]) or not self.atr.Update(data[self.symbol]):
            return

        # Update long-term bullish/bearish based on monthly EMA
        if self.month_end_window.IsReady and self.monthly_ema.IsReady:
            self.is_long_term_bullish = data[self.symbol].Close > self.monthly_ema.Current.Value

        # Position entry logic
        if (self.Time - self.last_basket_position_time).total_minutes() >= 120:
            if self.is_long_term_bullish and data[self.symbol].Close > self.daily_ema.Current.Value:
                self.EnterPosition('Long', data)
            elif not self.is_long_term_bearish and data[self.symbol].Close < self.daily_ema.Current.Value:
                    self.EnterPosition('Short', data)

    def EnterPosition(self, direction, data):
        if self.open_positions < self.basket_size:
            if self.open_positions == 0 or (data[self.symbol].Close - self.batch_entry_prices[-1][0] >= self.atr.Current.Value * self.atr_multiplier_for_space):
                lot_size = 0.05  # Define lot size
                if direction == 'Long':
                    self.Buy(self.symbol, lot_size)
                else:
                    self.Sell(self.symbol, lot_size)

                # Update state variables
                self.batch_positions.append(self.symbol)
                self.batch_entry_prices.append((data[self.symbol].Close, lot_size))
                self.open_positions += 1
                self.last_basket_position_time = self.Time

    def OnEndOfAlgorithm(self):
        # Liquidate all positions at the end of the algorithm
        self.Liquidate()

        ### Part 3: Risk Management
    def ExecuteTrailingStopLoss(self, data):
        atr_value = self.atr.Current.Value
        trailing_stop_distance = 3 * atr_value  # Example multiplier

        # Update trailing stop for each position
        for price, size in self.batch_entry_prices:
            if self.Portfolio[self.symbol].IsLong:
                self.trailing_stop = max(self.trailing_stop, price - trailing_stop_distance)
            elif self.Portfolio[self.symbol].IsShort:
                self.trailing_stop = min(self.trailing_stop, price + trailing_stop_distance)
    
        # Check and execute trailing stop
        current_price = data[self.symbol].Close
        if (self.Portfolio[self.symbol].IsLong and current_price <= self.trailing_stop) or \
           (self.Portfolio[self.symbol].IsShort and current_price >= self.trailing_stop):
            self.Liquidate(self.symbol)

    def OnData(self, data):
        # Previous OnData content...

        # Risk management
        if self.open_positions > 0:
            self.ExecuteTrailingStopLoss(data)

        ### Part 4: Monthly EMA Calculation

    def OnEndOfDay(self, symbol):
        # Previous OnEndOfDay content...

        # Update long-term bullish/bearish based on monthly EMA
        if self.month_end_window.IsReady and self.monthly_ema.IsReady:
            self.is_long_term_bullish = data[self.symbol].Close > self.monthly_ema.Current.Value