| Overall Statistics |
|
Total Trades 784 Average Win 0.20% Average Loss -0.12% Compounding Annual Return 2.830% Drawdown 2.500% Expectancy 0.062 Net Profit 2.830% Sharpe Ratio 0.869 Loss Rate 60% Win Rate 40% Profit-Loss Ratio 1.69 Alpha 0.021 Beta 0.103 Annual Standard Deviation 0.026 Annual Variance 0.001 Information Ratio 0.256 Tracking Error 0.026 Treynor Ratio 0.222 Total Fees $0.00 |
import pandas
import numpy as np
### <summary>
### Simple RSI Strategy intended to provide a minimal algorithm example using
### one indicator
### </summary>
class RSIAlgorithm(QCAlgorithm):
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.'''
# Set our main strategy parameters
self.SetStartDate(2013,1, 1) # Set Start Date
self.SetEndDate(2014,1,1) # Set End Date
self.SetCash(10000) # Set Strategy Cash
RSI_Period = 14 # RSI Look back period
self.RSI_OB = 60 # RSI Overbought level
self.RSI_OS = 40 # RSI Oversold level
self.Allocate = 2 # Percentage of captital to allocate
self.tolerance = 0.00015
self.spread = 20/10000
self.first_stg_up = 0
self.first_stg_down = 0
self.trend = 0
self.trend_n = 0
self.symbol = "EURUSD"
## Rename variables for percentages to make more readable and less confusing
self.tpPercent = 20/10000
self.slPercent = 10/10000
## Reassign these to be variables for Order Tickets
self.tp = None
self.sl = None
self.holdings = 0
self.quant = 10000
# Find more symbols here: http://quantconnect.com/data
self.AddForex("EURUSD", Resolution.Minute)
self.RSI_Ind = self.RSI("EURUSD", RSI_Period)
self.bb_ind = self.BB("EURUSD", 20, 1, MovingAverageType.Simple);
self.slow = self.SMA("EURUSD", 20, Resolution.Hour)
self.fast = self.SMA("EURUSD", 7, Resolution.Hour)
# Ensure that the Indicator has enough data before trading,.
self.SetWarmUp(20)
def OnData(self, data):
trend_sma = np.where(self.fast.Current.Value > self.slow.Current.Value,1,0)
spread = self.bb_ind.UpperBand.Current.Value - self.bb_ind.LowerBand.Current.Value
spread_bin = np.where(spread > self.spread,1,0)
# Check if we are in the market
fxOpen = data[self.symbol].Open
fxClose = data[self.symbol].Close
price = data[self.symbol].Price
if trend_sma == 1 and fxClose > fxOpen and fxClose >= self.bb_ind.UpperBand.Current.Value:
self.trend = 1
if trend_sma == 0 and fxClose < fxOpen and fxClose <= self.bb_ind.LowerBand.Current.Value :
self.trend = -1
if spread_bin == 0:
self.first_stg_up = 0
self.first_stg_down = 0
self.trend = 0
self.trend_n = 0
if not self.Portfolio.Invested and not self.IsWarmingUp:
# If not, we check the RSI Indicator
if self.trend == 1 :
#
## you need to assign to self.order or else variable will remain local
self.order = self.MarketOrder(self.symbol, self.quant)
## you need to define fxClose or else the orders won't be properly placed
fxClose = data[self.symbol].Close
## you need to replace sl with self.sl, as you want these to be global variables
## otherwise, they will not be accessible outside of OnData
self.sl = self.StopMarketOrder(self.symbol, -self.quant, fxClose - self.slPercent)
self.tp = self.LimitOrder(self.symbol, -self.quant, fxClose + self.tpPercent)
if self.trend == -1 :
self.order = self.MarketOrder(self.symbol, -self.quant)
## you need to define fxClose or else the orders won't be properly placed
fxClose = data[self.symbol].Close
## you need to replace sl with self.sl, as you want these to be global variables
## otherwise, they will not be accessible outside of OnData
self.sl = self.StopMarketOrder(self.symbol, self.quant, fxClose + self.slPercent)
self.tp = self.LimitOrder(self.symbol, self.quant, fxClose - self.tpPercent)
def OnOrderEvent(self, orderEvent):
self.Log(orderEvent)
## This will check for the boolean value of whether or not the order has been filled
if not (orderEvent.Status == OrderStatus.Filled):
return
## python doesn't support null. Instead, check for None
if (self.tp is None) or (self.sl is None):
return
filledOrderId = orderEvent.OrderId
if self.tp.OrderId == filledOrderId:
self.Liquidate()
if self.sl.OrderId == filledOrderId:
self.Liquidate()