| Overall Statistics |
|
Total Trades 5 Average Win 1.52% Average Loss -0.32% Compounding Annual Return 0% Drawdown 109.900% Expectancy 1.878 Net Profit -110.481% Sharpe Ratio -0.412 Probabilistic Sharpe Ratio 0.238% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 4.76 Alpha -0.992 Beta 0.989 Annual Standard Deviation 2.416 Annual Variance 5.837 Information Ratio -0.411 Tracking Error 2.412 Treynor Ratio -1.006 Total Fees $9.25 Estimated Strategy Capacity $340000000.00 Lowest Capacity Asset GC UKF0TK80C5UL |
from AlgorithmImports import*
import pandas as pd
class FuturesSMAAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetEndDate(2011, 1, 1)
self.SetCash(100000)
futureES = self.AddFuture(Futures.Metals.Gold)
futureES.SetFilter(TimeSpan.FromDays(30), TimeSpan.FromDays(720))
self.new_day = True
self.contract = None
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), self.SpecificTime)
self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x)))
def OnData(self, slice):
self.InitUpdateContract(slice)
def InitUpdateContract(self, slice):
if not self.new_day:
return
if self.contract != None and (self.contract.Expiry - self.Time).days >= 3: # rolling 3 days before expiry
return
for chain in slice.FutureChains.Values:
if self.contract != None:
self.Log('Expiry days away {} - {}'.format((self.contract.Expiry-self.Time).days, self.contract.Expiry))
self.Log('Reset: closing all positions')
self.Liquidate()
contracts = list(chain.Contracts.Values)
chain_contracts = list(contracts)
chain_contracts = sorted(chain_contracts, key=lambda x: x.Expiry)
self.contract = chain_contracts[0]
self.Log("Setting contract to: {}".format(self.contract.Symbol.Value))
one_day = TradeBarConsolidator(TimeSpan.FromDays(1))
self.SubscriptionManager.AddConsolidator(self.contract.Symbol, one_day)
self.sma = self.SMA(self.contract.Symbol, 80, Resolution.Daily)
history = self.History(self.contract.Symbol, 80, Resolution.Daily).reset_index(drop=False)
for bar in history.itertuples():
if len(history) < 80:
raise Exception(f'Empty history at {self.Time}')
if bar.time.minute == 0 and ((self.Time-bar.time)/pd.Timedelta(minutes=1)) >=2:
self.sma.Update(bar.time, bar.close)
if (self.sma != None and self.sma.IsReady):
holdings = self.Portfolio[self.contract.Symbol].Quantity
price = self.Securities[self.contract.Symbol].Price
if not self.Portfolio.Invested:
if price < self.sma.Current.Value:
self.MarketOrder(self.contract.Symbol, -1)
if price > self.sma.Current.Value:
self.MarketOrder(self.contract.Symbol, 1)
if holdings < 0 and price > self.sma.Current.Value:
self.Liquidate()
self.MarketOrder(self.contract.Symbol, 1)
if holdings > 0 and price < self.sma.Current.Value:
self.Liquidate()
self.MarketOrder(self.contract.Symbol, -1)
else:
self.Debug("SMA not yet Ready")
self.new_day = False
def SpecificTime(self):
self.Log(f"SpecificTime: Fired at : {self.Time}")
self.new_day = True