| Overall Statistics |
|
Total Trades 87 Average Win 11.52% Average Loss -4.07% Compounding Annual Return 56.553% Drawdown 29.400% Expectancy 1.852 Net Profit 1740.057% Sharpe Ratio 1.587 Loss Rate 26% Win Rate 74% Profit-Loss Ratio 2.83 Alpha 0.338 Beta 8.026 Annual Standard Deviation 0.314 Annual Variance 0.099 Information Ratio 1.523 Tracking Error 0.314 Treynor Ratio 0.062 Total Fees $454.03 |
"""
TNA TLT Strategy using hourly RSI
(which is used as momentum indicator rather than a contrarian)
"""
from clr import AddReference # .NET Common Language Runtime (CLR) <- http://pythonnet.github.io/
AddReference("System")
AddReference("QuantConnect.Algorithm") # to load an assembly use AddReference
AddReference("QuantConnect.Common")
from System import * # CLR namespaces to be treatedas Python packages
from QuantConnect import *
from QuantConnect.Algorithm import *
# from QuantConnect.Python import PythonQuandl # quandl data not CLOSE
# from QuantConnect.Python import PythonData # custom data
import numpy as np; import pandas as pd
from datetime import datetime, timedelta
import decimal
import talib
class TNAbyRSI(QCAlgorithm):
def __init__(self):
#self._period = 14
self._period = 14
self.perc_pos = 0.98 # just need something ~0.3 for enough fun
def Initialize(self):
self.SetCash(10000)
#self.SetStartDate(2014,05,01)
self.SetStartDate(2012,1,1)
self.SetEndDate(datetime.now().date() - timedelta(1))
#self.SetStartDate(2018,1,1)
#self.SetEndDate(2016,3,1)
self.first_time = True
self.RSI_previous = None
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
self.TNA = self.AddEquity("TNA", Resolution.Hour).Symbol
self.TLT = self.AddEquity("TLT", Resolution.Hour).Symbol
self.SPY = self.AddEquity("SPY", Resolution.Hour).Symbol
#self.Securities["TNA"].SetLeverage(1.0)
#self.Securities["TLT"].SetLeverage(1.0)
#self.Securities["SPY"].SetLeverage(1.0)
#self.CalculateOrderQuantity("SPY", 1.0))
self._RSI = self.RSI(self.TNA, self._period, MovingAverageType.Simple, Resolution.Hour)
#self._RSI = self.RSI(self.TNA, self._period, MovingAverageType.Simple, Resolution.Daily)
#self.Plot("Indicators", self._RSI)
#Original
self.Schedule.On(self.DateRules.EveryDay(self.TNA), self.TimeRules.AfterMarketOpen(self.TNA, 361), Action(self.rebalance))
#Time of Day
#self.Schedule.On(self.DateRules.EveryDay(self.SPY), self.TimeRules.AfterMarketOpen(self.SPY, 361), Action(self.rebalance))
#self.Plot("TNA", "TNA", self.TNA)
def OnData(self, data):
# we may insert some stop-losses in here
pass
def rebalance(self):
# wait if still open orders
if len(self.Transactions.GetOpenOrders())>0: return
# wait for i. indicator warm up
if (not self._RSI.IsReady):
if self.first_time: # update RSI previous
self.RSI_previous = self._RSI.Current.Value
self.first_time = False
#self.SetHoldings(self.TLT, self.perc_pos)
self.SetHoldings(self.TNA, self.perc_pos)
return
# update RSI
RSI_curr = self._RSI.Current.Value
self.Log(str(self.Time)+" RSI: "+ str(round(RSI_curr,2)))
# get current qnties
TNA_qnty = self.Portfolio[self.TNA].Quantity
TLT_qnty = self.Portfolio[self.TLT].Quantity
# Overbought conditions
if RSI_curr > 85 and TNA_qnty > 10: # up and above 85: SELL
self.Liquidate(self.TNA)
self.SetHoldings(self.TLT, self.perc_pos)
self.Log("BOUGHT " + str((self.Portfolio[self.TLT].Quantity) - TLT_qnty) + " shares of TLT" + " and SOLD " + str(TNA_qnty - (self.Portfolio[self.TNA].Quantity)) + " shares of TNA")
# Oversold condition
if RSI_curr < 15 and TLT_qnty > 10: # up and above 15: BUY
self.Liquidate(self.TLT)
self.SetHoldings(self.TNA, self.perc_pos)
self.Log("SOLD " + str(TLT_qnty - (self.Portfolio[self.TLT].Quantity)) + " shares of TLT" + " and BOUGHT " + str((self.Portfolio[self.TNA].Quantity) - TNA_qnty) + " shares of TNA")
self.RSI_previous = RSI_curr