Overall Statistics
Total Trades
64
Average Win
11.31%
Average Loss
-1.28%
Compounding Annual Return
0.617%
Drawdown
24.900%
Expectancy
0.229
Net Profit
6.364%
Sharpe Ratio
0.093
Probabilistic Sharpe Ratio
0.027%
Loss Rate
88%
Win Rate
12%
Profit-Loss Ratio
8.83
Alpha
0.005
Beta
0.035
Annual Standard Deviation
0.09
Annual Variance
0.008
Information Ratio
-0.607
Tracking Error
0.159
Treynor Ratio
0.236
Total Fees
$128.07
Estimated Strategy Capacity
$430000.00
Lowest Capacity Asset
EURUSD 8G
class VirtualBrownGull(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2012, 3, 4)  # Set Start Date
        self.SetEndDate(2022, 3, 11)
        self.SetCash(10000)  # Set Strategy Cash
        self.SetSecurityInitializer(self.CustomSecurityInitializer)
        self.eurusd = self.AddForex("EURUSD", Resolution.Daily, Market.Oanda, 30).Symbol
        self.quoteBarWindow = RollingWindow[QuoteBar](2)
        
        #setting up SMA and linking to rolling window
        self.twohundredsma = self.SMA(self.eurusd, 200, Resolution.Daily)
        self.twohundredsma.Updated += self.SMAUpdated
        self.twohunsmaWindow = RollingWindow[IndicatorDataPoint](2)
        
        #History Request for SMA data, returns table with high, low, open, close columns for each bar requested, indexed by close column here
        
        hist_prices = self.History(self.eurusd, 200, Resolution.Daily)["askclose"]
        for time, askclose in hist_prices.loc[self.eurusd].items(): 
                self.twohundredsma.Update(time, askclose)

    def SMAUpdated(self, sender, updated):
        self.twohunsmaWindow.Add(updated)
    
    def CustomSecurityInitializer(self, security):
        security.SetLeverage(30)
    
    
    def OnData(self, data):
        
        ## Check if everything ready ####################################################################################################################
        
        self.quoteBarWindow.Add(data[self.eurusd]) 
        
        if not self.quoteBarWindow.IsReady:
            return
        
        if not self.twohundredsma.IsReady:
            return
        
        if not self.twohunsmaWindow.IsReady:
            return
        
        ##################################################################################################################################################
        ## If not invested, enter on cross up and put stop at SMA ########################################################################################
        
        ordersize = (self.Portfolio.GetBuyingPower(self.eurusd, OrderDirection.Buy) * .01) / (data[self.eurusd].Ask.Close - self.twohundredsma.Current.Value)
        
        if not self.Portfolio[self.eurusd].IsLong or self.Portfolio[self.eurusd].IsShort:
        
            if self.quoteBarWindow[0].Ask.Low > self.twohunsmaWindow[0].Value and self.quoteBarWindow[1].Ask.Low < self.twohunsmaWindow[1].Value:
            
                self.MarketOrder(self.eurusd, ordersize)
                self.stopticket = self.StopMarketOrder(self.eurusd, -ordersize , round(self.twohundredsma.Current.Value, 5))
                self.exitordersize = ordersize
                self.Log("Max Risk Quantity: " + str((self.Portfolio.GetBuyingPower(self.eurusd, OrderDirection.Buy) * .01) / (data[self.eurusd].Ask.Close - self.twohundredsma.Current.Value)))
                self.Log("Order Size: " + str(ordersize))
                
            else:
                pass
            
        ###################################################################################################################################################
        ## If invested, exit on cross down  ###############################################################################################################
        
        if self.Portfolio[self.eurusd].IsLong:
            
            if self.quoteBarWindow[0].Ask.Close < self.twohunsmaWindow[0].Value and self.quoteBarWindow[1].Ask.Close > self.twohunsmaWindow[1].Value:
                
                self.MarketOrder(self.eurusd, -self.exitordersize)
                
                self.stopticket.Cancel("Cancelled")
                
                
        else:
            pass