Overall Statistics
Total Trades
5
Average Win
38.32%
Average Loss
0%
Compounding Annual Return
11.508%
Drawdown
17.300%
Expectancy
0
Net Profit
192.786%
Sharpe Ratio
1.1
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
-0.112
Beta
11.347
Annual Standard Deviation
0.104
Annual Variance
0.011
Information Ratio
0.908
Tracking Error
0.104
Treynor Ratio
0.01
Total Fees
$25.00
import decimal 

class BasicTemplateAlgorithm(QCAlgorithm):
    '''In this example we look at the canonical 15/30 day moving average cross. This algorithm
    will go long when the 15 crosses above the 30 and will liquidate when the 15 crosses
    back below the 30.'''
    
    # Initialize the global parameter at first
    def __init__(self):
            self.symbol = "AAPL"
            self.previous = None
            self.fast = None
            self.slow = None
    
    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
        #This part comes from the basic Template with Set the Start and End Date as the function name
        self.SetStartDate(2009, 1, 1)  
        self.SetEndDate(2018, 11, 9)    
        self.SetCash(100000)  
        self.SetBenchmark(self.symbol)
        # Find more symbols here: http://quantconnect.com/data
        self.AddSecurity(SecurityType.Equity, self.symbol, Resolution.Minute)

        # In order to do the simple moving average strategy, we need to get the moving average for 50 days and 200 days rolling window
        # In the community I find QuantConnect has SMA as the function for getting simple moving average,
        # therefore it's easier for calculating the moving average than a regular python environment
        self.fast = self.SMA(self.symbol, 50, Resolution.Daily);
        self.slow = self.SMA(self.symbol, 200, Resolution.Daily);

        
    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: TradeBars IDictionary object with your stock data
        '''
        # We need to wait for the 200 moving average to be calculated out since it needs more steps of date to formulate the 200 moving average
        if not self.slow.IsReady:
            return    

        # This part is the result coming from debugging. I find that the running time is so long for backtesting without this part and 
        # from community some algorithm suuggests there may exist a situation that the trade executes multiple times at same day
        # Therefore I added this part for ensure there is only one trade at same day
        if self.previous is not None and self.previous.date == self.Time.date:
            return

        # Convenient for following part, we get the postion as the current position of our portfolio with reference in documentation suggesting the 
        # attribute "Quantity" gives us the position quantity.
        position = self.Portfolio[self.symbol].Quantity

        # This is the core part of the strategy
        
        # At first we only need to long the AAPL stock when our position is neutral. The reason for the position < 0 part is that I also implement a long-short strategy 
        # The decimal.Decimal(1.00015) part is the usual tolerance part for moving average strategy with purpose of preventing too frequent position change with a high transaction costs
        # The execution part is simple from the reference of documentation that buy 1000 shares by a market order, which can be executed immediately with function "MarketOrder()" as instructed
        if position <= 0 and self.fast.Current.Value > self.slow.Current.Value*decimal.Decimal(1.00015):
            self.MarketOrder(self.symbol, 1000)
            #self.SetHoldings(self.symbol, 1.0)
             
        # The short or liquidate position is similar to the long position and the Liquidate function is refered in the documentation
        # As mentioned before, I also implment a long short strategy both for the whole portfolio or 1000 shares
        if position > 0 and self.fast.Current.Value < self.slow.Current.Value:
            #self.SetHoldings(self.symbol,-1.0)
            self.Liquidate(self.symbol)
        # As mentioned before, I need to check if there is only one trade at the same day, I need store today's date with variable "previous" after all the procedures
        self.previous = self.Time