Overall Statistics
Total Trades
41
Average Win
0.00%
Average Loss
-0.01%
Compounding Annual Return
-1.644%
Drawdown
0.300%
Expectancy
-0.957
Net Profit
-0.279%
Sharpe Ratio
-6.562
Probabilistic Sharpe Ratio
0.000%
Loss Rate
96%
Win Rate
4%
Profit-Loss Ratio
0.00
Alpha
-0.011
Beta
-0.006
Annual Standard Deviation
0.002
Annual Variance
0
Information Ratio
-7.432
Tracking Error
0.056
Treynor Ratio
2.204
Total Fees
$0.00
import decimal as d
from System.Drawing import Color

class MovingAverageBasic(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017,1,1)  # Set Start Date
        self.SetEndDate(2017,3,1)
        self.SetCash(1000000)  # Set Strategy Cash
        self.defaultQuantity = 100000
         
        
        #self.AddForex("AUDUSD", Resolution.Hour, Market.Oanda) #AddForex merely adds the security, but you cant refer to it later.
        self.audusd = self.AddForex("AUDUSD", Resolution.Hour, Market.Oanda).Symbol #But doing this you now can refer to self.symbol
        # Symbols are a way to identify an asset uniquely. They are objects which contain all the information required 
        # to identify a security, without needing external references, or proprietary database look-ups.
        
        self.SetBrokerageModel(BrokerageName.OandaBrokerage)

        self.fastEMA = self.EMA("AUDUSD", 10, Resolution.Hour)
        self.slowEMA = self.EMA("AUDUSD", 100, Resolution.Hour)
        self.fastEMAWin = RollingWindow[float](10)
        self.slowEMAWin = RollingWindow[float](10)
        self.PriceWin = RollingWindow[float](3)
        self.ATRindy = self.ATR("AUDUSD",20,MovingAverageType.Simple, Resolution.Hour)
        self.SetWarmUp(100)
        self.fill_price = 0
        self.quant_filled = 0
        #Risk Management
        self.leverage = self.Securities["AUDUSD"].Leverage
        self.pip = self.Securities["AUDUSD"].SymbolProperties.MinimumPriceVariation * 10 #times 10 converts pipette to pip
        
        #initializing charts
        #Chart.Stacked: This means the chart will appear as a separate chart below the main equity chart.
        #Chart.Overlay: This means that the chart will be overlayed on top of the main equity chart.
        FXPlot = Chart("FX Plot", ChartType.Stacked)
        # On the Trade Plotter Chart we want 3 series: trades and price:
        FXPlot.AddSeries(Series("Price", SeriesType.Line, 0))
        FXPlot.AddSeries(Series("Buy", SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Triangle))
        FXPlot.AddSeries(Series("Sell", SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.TriangleDown))
        FXPlot.AddSeries(Series("FastMA", SeriesType.Line, '$' , Color.Orange))
        FXPlot.AddSeries(Series("SlowMA", SeriesType.Line, '$', Color.Purple))
        self.AddChart(FXPlot)
       



    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
            Arguments:
                data: Slice object keyed by symbol containing the stock data
        '''

        
        # Creates an indicator and adds to a rolling window when it is updated
        self.fastEMAWin.Add(self.fastEMA.Current.Value)
        self.slowEMAWin.Add(self.slowEMA.Current.Value)
        self.ATR_Now = self.ATRindy.Current.Value
        
        if not self.slowEMA.IsReady:
            return
        if not self.fastEMA.IsReady:
            return
        if self.IsWarmingUp:
            return
        
        #Logging-------------------------------------------------------------------------------
        Cutup = self.CrossAbove(self.fastEMAWin, self.slowEMAWin)
        Cutdown = self.CrossBelow(self.fastEMAWin, self.slowEMAWin)
        time_now = self.Time
        holdings = self.Securities["AUDUSD"].Holdings.Quantity
        
        
        if self.Portfolio[self.audusd].IsLong:
            if self.Falling(self.slowEMAWin, self.slowEMAWin):
                self.Liquidate(self.audusd)
                self.Log("Closing Long | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))  
                
                
        elif self.Portfolio[self.audusd].IsShort:
            if self.Rising(self.slowEMAWin, self.slowEMAWin):
                self.Liquidate(self.audusd)
                self.Log("Closing Short | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))  
                
        else:
            if self.CrossAbove(self.fastEMAWin, self.slowEMAWin) and not self.Falling(self.slowEMAWin, self.slowEMAWin):
                self.MarketOrder(self.audusd, self.CalculateTradeSize())
                self.Log("New Long | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))  
                self.Log("Market long order fill price is {}".format(self.fill_price))
                #insert calculation function here
                self.StopMarketOrder(self.audusd, -self.defaultQuantity, self.fill_price - 2*self.ATR_Now )
                #self.holdings = self.Securities["AUDUSD"].Holdings.Quantity
                
         
            if self.CrossBelow(self.fastEMAWin, self.slowEMAWin) and not self.Rising(self.slowEMAWin, self.slowEMAWin):
                self.MarketOrder(self.audusd, -self.defaultQuantity)
                self.Log("New Short | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))  
                self.Log("Market short order fill price is {}".format(self.fill_price))
                #insert calculation function here
                self.StopMarketOrder(self.audusd, self.defaultQuantity, self.fill_price + 2*self.ATR_Now )
                #self.holdings = self.Securities["AUDUSD"].Holdings.Quantity
        
       
        #below is all for the charting
        self.Plot("FX Plot", "FastMA", self.fastEMA.Current.Value)
        self.Plot("FX Plot", "SlowMA", self.slowEMA.Current.Value)
        self.Plot("FX Plot","Price", data["AUDUSD"].Price)
        
    #below are event handlers, as well as functions to determine the status of the EMA
    #-------------------------------------------------------------------------------
        
    def CrossAbove(self, fast, slow, tolerance=0):
        return fast[0] > slow[0] * (1 + tolerance) and fast[2] < slow[2] * (1 - tolerance)

    def CrossBelow(self, fast, slow, tolerance = 0):
        return fast[0] < slow[0] * (1 - tolerance) and fast[2] > slow[2] * (1 + tolerance)
        
    def Rising(self, current, lookback, tolerance = 0):
        return current[0] > lookback[2] * (1 + tolerance)
        
    def Falling(self, current, lookback, tolerance = 0):
        return current[0] < lookback[2] * (1 - tolerance)
    
    def CalculateTradeSize(self):
        self.MaxLossAbsolute = self.Portfolio.Cash * 0.02
        self.MaxLossAbsolute + 2*self.ATR_Now
        
        return self.MaxLossAbsolute / 2 * self.ATR_Now
       
    def OnOrderEvent(self, orderEvent):
        self.order_tick = self.Transactions.GetOrderById(orderEvent.OrderId)
        self.fill_price = orderEvent.FillPrice
        self.quant_filled = orderEvent.FillQuantity
        if self.fill_price > 0:
            if self.quant_filled > 0:
                self.Plot("FX Plot","Buy",self.fill_price)
            elif self.quant_filled <0:
                self.Plot("FX Plot","Sell",self.fill_price)
        #self.Log("An order was filled at {}".format(self.fill_price))