| Overall Statistics |
|
Total Trades 58 Average Win 0.02% Average Loss -0.02% Compounding Annual Return -75.682% Drawdown 3.400% Expectancy -0.816 Net Profit -1.807% Sharpe Ratio -4.77 Loss Rate 89% Win Rate 11% Profit-Loss Ratio 0.65 Alpha -2.305 Beta 126.987 Annual Standard Deviation 0.189 Annual Variance 0.036 Information Ratio -4.831 Tracking Error 0.189 Treynor Ratio -0.007 Total Fees $321.90 |
from datetime import timedelta
import decimal as d
class BasicTemplateFuturesAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2013, 10, 07)
self.SetEndDate(2013, 10, 11)
self.SetCash(1000000)
# Subscribe and set our expiry filter for the futures chain
futureCL = self.AddFuture(Futures.Energies.CrudeOilWTI)
futureCL.SetFilter(timedelta(0), timedelta(182))
self.entry_ticket = None
def OnData(self,slice):
if self.entry_ticket is None:
for chain in slice.FutureChains:
# Get contracts expiring no earlier than in 90 days
contracts = filter(lambda x: x.Expiry > self.Time + timedelta(90), chain.Value)
# if there is any contract, trade the front contract
if len(contracts) == 0: continue
front = sorted(contracts, key = lambda x: x.Expiry, reverse=True)[0]
price = self.Securities[front.Symbol].Price
# Place limit order below market price. Wait for rebound to buy
self.entry_ticket = self.LimitOrder(front.Symbol, 3, price - d.Decimal(0.01))
def OnOrderEvent(self, orderEvent):
#self.Log(str(orderEvent))
if orderEvent.Status != OrderStatus.Filled:
return
if self.entry_ticket is not None:
# When entry order is filled, place TP and SL orders
if orderEvent.OrderId == self.entry_ticket.OrderId:
price = orderEvent.FillPrice
self.LimitOrder(orderEvent.Symbol, -3, price + d.Decimal(0.04))
self.StopMarketOrder(orderEvent.Symbol, -3, price - d.Decimal(0.03))
# Otherwise, one of the exit orders was filled, so cancel the open orders
else:
self.Transactions.CancelOpenOrders(orderEvent.Symbol)
self.entry_ticket = None