Overall Statistics Total Trades 40 Average Win 46.76% Average Loss -5.46% Compounding Annual Return 244.802% Drawdown 39.500% Expectancy 3.307 Net Profit 1242.308% Sharpe Ratio 2.013 Loss Rate 55% Win Rate 45% Profit-Loss Ratio 8.57 Alpha 0.437 Beta 0.473 Annual Standard Deviation 0.481 Annual Variance 0.231 Information Ratio -0.308 Tracking Error 0.503 Treynor Ratio 2.046 Total Fees \$0.00
```import clr
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
import decimal as d

class MovingAverageAlgorithm(QCAlgorithm):

def __init__(self):
# Market parameters
self.previousTime = None
self.previousPrice = None
self.previousTrigger = None
self.sellTicket = None
self.stopTicket = None
self.symbol = "BTCEUR"
self.base = "BTC"
self.quote = "EUR"
self.market = Market.GDAX
self.brokerage = BrokerageName.GDAX
self.resolution = Resolution.Daily
self.conversionRate = 1.23

# Strategy parameters
self.length_fast_ema = 5
self.length_slow_ema = 14
self.initial_stop_percent_delta = 0.1 # e.g. 0.1 means stop price = 0.9 * price
self.follow_factor = 1 # 0 means stop price follows price 1 for 1,

def Initialize(self):
'''Initialise algorithm with data, resolution, cash and start-end dates'''

self.SetStartDate(2016,1,1)  # Set Start Date
self.SetEndDate(2018,2,3)  # Set End Date
self.Portfolio.SetCash(0)  # Set USD to 0 since we only have EUR in our account
self.Portfolio.SetCash("EUR", 1000, self.conversionRate) # Set EUR strategy cash with static EURUSD conversion rate

self.SetBrokerageModel(self.brokerage, AccountType.Cash)  # crypto brokerage

# Indicators
self.ema_fast = self.EMA(self.symbol, self.length_fast_ema, self.resolution)  # fast moving average
self.ema_slow = self.EMA(self.symbol, self.length_slow_ema, self.resolution)  # slow moving average

self.SetBenchmark(self.symbol)

# Note - use single quotation marks: ' instead of double "
# Chart - Master Container for the Chart:
coinPlot = Chart('Strategy Equity')
# On the Trade Plotter Chart we want 3 series: trades and price:

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 security data
'''
# Notice in this method:
# 1. We never need to 'update' our indicators with the data, the engine takes care of this for us
# 2. We can use indicators directly in math expressions
# 3. We can easily plot many indicators at the same time

# Wait for indicators to fully initialize
return

# Allow one trade maximum per day
if self.previousTime is not None and self.previousTime.date() == self.Time.date():
return

# Retrieve quote asset. CashBook is a dictionary of currencies (including crypto assets)
availableQuote = self.Portfolio.CashBook[self.quote].Amount
# Retrieve current holdings
holdings = self.Portfolio.CashBook[self.base].Amount
# Retrieve current price
currentPrice = self.Securities[self.symbol].Close

## UPDATE TRAILING STOP LIMIT ORDER ##
# Increase trailing stop limit if it exist and if necessary:
if self.stopTicket is not None:
if currentPrice > self.previousPrice:
ratio = currentPrice / self.previousPrice
adjustedRatio = (ratio + self.follow_factor) / (1 + self.follow_factor)

updateOrderFields = UpdateOrderFields()
updateOrderFields.StopPrice = trigger
updateOrderFields.LimitPrice = trigger * 0.99
self.stopTicket.Update(updateOrderFields)
self.previousTrigger = trigger

# Define a small tolerance to avoid bouncing when comparing indicators:
tolerance = 0.00015

# 1. Go long if we're currently short or flat
# Note that we cannot short crypto assets at the moment with GDAX API
# 2. If fast ema is greater than slow ema, then go long
# 3. Wait for price confirmation: price must exceed a recent high
if holdings <= 0:
if self.ema_fast.Current.Value > self.ema_slow.Current.Value * d.Decimal(1 + tolerance):
limitPrice = currentPrice * d.Decimal(1+0.001)
# use all cash on long, 0.999 is here to avoid buying power issues
quantity = (availableQuote  / limitPrice) * d.Decimal(0.999)
lot = self.Securities[self.symbol].SymbolProperties.LotSize
roundedQuantity = round(quantity/lot-d.Decimal(0.5))*lot  # -0.5 is present to round down the quantity
self.buyTicket = self.LimitOrder(self.symbol, roundedQuantity, round(limitPrice, 2))

## SELL ORDER ##
# 1. Liquidate if we're currently long
# 2. If fast ema is less than slow ema then liquidate the long
if holdings > 0:
if self.ema_fast.Current.Value < self.ema_slow.Current.Value:
limitPrice = currentPrice * d.Decimal(1-0.001)
self.sellTicket = self.LimitOrder(self.symbol, -holdings, round(limitPrice, 2))  # sell entire position

# Store in memory the time and the price of the last execution
self.previousTime = self.Time
self.previousPrice = currentPrice

# Plot indicators and benchma
self.Plot('Strategy Equity', 'Benchmark', self.Securities[self.symbol].Price)
self.Plot('Strategy Equity', 'Fast EMA', self.ema_fast.Current.Value)
self.Plot('Strategy Equity', 'Slow EMA', self.ema_slow.Current.Value)

def OnOrderEvent(self, event):
# Handle filling of buy & sell orders:
# Determine if order is the buy or the sell or the stop

order = self.Transactions.GetOrderById(event.OrderId)
self.Log("{0}: {1}: {2}".format(self.Time, order.Type, event))

# If buy order is filled, create stop loss
# limit price is set below the trigger to maximise the chances of catching a price decrease
trigger = (1 - self.initial_stop_percent_delta) * self.buyTicket.AverageFillPrice
limit = trigger * 0.99
self.stopTicket = self.StopLimitOrder(self.symbol, -quantity, stopPrice=trigger, limitPrice=limit)
self.previousTrigger = trigger

## SELL ORDER FILLED ##
elif event.OrderId == self.sellTicket.OrderId:
self.Debug("Sell ticket event detected")
# If sell order is filled, cancel stop loss
if self.sellTicket.Status == OrderStatus.Filled:
self.Debug("Sell order filled")
self.stopTicket.Cancel()

## STOP ORDER FILLED ##
elif event.OrderId == self.stopTicket.OrderId:
self.Debug("Stop ticket event detected")
# If stop order is filled, cancel the sell order, if any:
if self.stopTicket.Status == OrderStatus.Filled:
self.Debug("Stop order filled")
self.stopTicket = None
if self.sellTicket is not None:
self.sellTicket.Cancel()
self.sellTicket = None                        ```