#region imports
from AlgorithmImports import *
#endregion
# futs_list = [Futures.Indices.SP500EMini, Futures.Grains.Corn, Futures.Currencies.JPY]
futs_list = [
Futures.Grains.BlackSeaCornFinanciallySettledPlatts,
Futures.Grains.BlackSeaWheatFinanciallySettledPlatts,
Futures.Grains.SRWWheat,
Futures.Grains.HRWWheat,
Futures.Grains.Corn,
Futures.Grains.Soybeans,
Futures.Grains.SoybeanMeal,
Futures.Grains.SoybeanOil,
Futures.Grains.Oats,
Futures.Currencies.GBP,
Futures.Currencies.CAD,
Futures.Currencies.JPY,
Futures.Currencies.CHF,
Futures.Currencies.EUR,
Futures.Currencies.AUD,
Futures.Currencies.NZD,
Futures.Currencies.RUB,
Futures.Currencies.BRL,
Futures.Currencies.MXN,
Futures.Currencies.ZAR,
# Futures.Currencies.AUDCAD,
# Futures.Currencies.AUDJPY,
# Futures.Currencies.AUDNZD,
# Futures.Currencies.BTC,
# Futures.Currencies.CADJPY,
# Futures.Currencies.StandardSizeUSDOffshoreRMBCNH,
# Futures.Currencies.EuroFXEmini,
# Futures.Currencies.EURAUD,
# Futures.Currencies.EURCAD,
# Futures.Currencies.EURSEK,
# Futures.Currencies.JapaneseYenEmini,
# Futures.Energies.PropaneNonLDHMontBelvieu,
# Futures.Energies.ArgusPropaneFarEastIndexBALMO,
# Futures.Energies.MiniEuropeanThreePointPercentFiveFuelOilBargesPlatts,
# Futures.Energies.MiniSingaporeFuelOil180CstPlatts,
# Futures.Energies.GulfCoastULSDPlattsUpDownBALMO,
# Futures.Energies.GulfCoastJetPlattsUpDownBALMO,
# Futures.Energies.PropaneNonLDHMontBelvieuOPIS,
# Futures.Energies.EuropeanPropaneCIFARAArgusBALMO,
# Futures.Energies.PremiumUnleadedGasoline10ppmFOBMEDPlatts,
# Futures.Energies.ArgusPropaneFarEastIndex,
# Futures.Energies.GasolineEurobobOxyNWEBargesArgusCrackSpreadBALMO,
# Futures.Energies.MontBelvieuNaturalGasolineOPIS,
# Futures.Energies.MontBelvieuNormalButaneOPISBALMO,
# Futures.Energies.ConwayPropaneOPIS,
# Futures.Energies.MontBelvieuLDHPropaneOPISBALMO,
# Futures.Energies.ArgusPropaneFarEastIndexVsEuropeanPropaneCIFARAArgus,
# Futures.Energies.ArgusPropaneSaudiAramco,
# Futures.Energies.GroupThreeULSDPlattsVsNYHarborULSD,
# Futures.Energies.GroupThreeSuboctaneGasolinePlattsVsRBOB,
# Futures.Energies.SingaporeFuelOil180cstPlattsBALMO,
# Futures.Energies.SingaporeFuelOil380cstPlattsBALMO,
# Futures.Energies.MontBelvieuEthaneOPIS,
# Futures.Energies.MontBelvieuNormalButaneOPIS,
# Futures.Energies.BrentCrudeOilVsDubaiCrudeOilPlatts,
# Futures.Energies.ArgusLLSvsWTIArgusTradeMonth,
# Futures.Energies.SingaporeGasoilPlattsVsLowSulphurGasoilFutures,
# Futures.Energies.LosAngelesCARBOBGasolineOPISvsRBOBGasoline,
# Futures.Energies.LosAngelesJetOPISvsNYHarborULSD,
# Futures.Energies.LosAngelesCARBDieselOPISvsNYHarborULSD,
# Futures.Energies.EuropeanNaphthaPlattsBALMO,
# Futures.Energies.EuropeanPropaneCIFARAArgus,
# Futures.Energies.MontBelvieuNaturalGasolineOPISBALMO,
# Futures.Energies.RBOBGasolineCrackSpread,
# Futures.Energies.GulfCoastHSFOPlattsBALMO,
# Futures.Energies.MarsArgusVsWTITradeMonth,
# Futures.Energies.MarsArgusVsWTIFinancial,
# Futures.Energies.EthanolT2FOBRdamIncludingDutyPlatts,
# Futures.Energies.MontBelvieuLDHPropaneOPIS,
# Futures.Energies.GasolineEurobobOxyNWEBargesArgus,
# Futures.Energies.WTIBrentFinancial,
# Futures.Energies.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread1000mt,
# Futures.Energies.GasolineEurobobOxyNWEBargesArgusBALMO,
# Futures.Energies.BrentLastDayFinancial,
Futures.Energies.CrudeOilWTI,
# Futures.Energies.GulfCoastCBOBGasolineA2PlattsVsRBOBGasoline,
# Futures.Energies.ClearbrookBakkenSweetCrudeOilMonthlyIndexNetEnergy,
# Futures.Energies.WTIFinancial,
# Futures.Energies.ChicagoEthanolPlatts,
# Futures.Energies.SingaporeMogas92UnleadedPlattsBrentCrackSpread,
# Futures.Energies.DubaiCrudeOilPlattsFinancial,
# Futures.Energies.JapanCnFNaphthaPlattsBALMO,
Futures.Energies.Ethanol,
# Futures.Energies.EuropeanNaphthaPlattsCrackSpread,
# Futures.Energies.EuropeanPropaneCIFARAArgusVsNaphthaCargoesCIFNWEPlatts,
# Futures.Energies.SingaporeFuelOil380cstPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts,
# Futures.Energies.EastWestGasolineSpreadPlattsArgus,
# Futures.Energies.EastWestNaphthaJapanCFvsCargoesCIFNWESpreadPlatts,
# Futures.Energies.RBOBGasolineVsEurobobOxyNWEBargesArgusThreeHundredFiftyThousandGallons,
# Futures.Energies.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread,
# Futures.Energies.FreightRouteTC14Baltic,
# Futures.Energies.OnePercentFuelOilCargoesFOBNWEPlattsVsThreePointFivePercentFuelOilBargesFOBRdamPlatts,
# Futures.Energies.GulfCoastHSFOPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts,
Futures.Energies.WTIHoustonCrudeOil,
# Futures.Energies.NaturalGasHenryHubLastDayFinancial,
Futures.Energies.HeatingOil,
# Futures.Energies.NaturalGasHenryHubPenultimateFinancial,
# Futures.Energies.WTIHoustonArgusVsWTITradeMonth,
Futures.Energies.Gasoline,
Futures.Energies.NaturalGas,
Futures.Financials.Y30TreasuryBond,
Futures.Financials.Y10TreasuryNote,
Futures.Financials.Y5TreasuryNote,
Futures.Financials.Y2TreasuryNote,
Futures.Financials.EuroDollar,
# Futures.Financials.FiveYearUSDMACSwap,
# Futures.Financials.UltraUSTreasuryBond,
# Futures.Financials.UltraTenYearUSTreasuryNote,
Futures.Indices.SP500EMini,
Futures.Indices.NASDAQ100EMini,
# Futures.Indices.Dow30EMini,
# Futures.Indices.VIX,
# Futures.Indices.Russell2000EMini,
Futures.Indices.Nikkei225Dollar,
Futures.Indices.BloombergCommodityIndex,
Futures.Indices.NASDAQ100BiotechnologyEMini,
Futures.Indices.FTSEEmergingEmini,
Futures.Indices.SP400MidCapEmini,
Futures.Indices.SPGSCICommodity,
Futures.Indices.USDDenominatedIbovespa,
Futures.Indices.MSCITaiwanIndex,
Futures.Indices.Nikkei225Yen,
Futures.Indices.Nifty50,
Futures.Indices.HangSeng,
Futures.Forestry.RandomLengthLumber,
Futures.Meats.LiveCattle,
Futures.Meats.FeederCattle,
Futures.Meats.LeanHogs,
Futures.Metals.Gold,
Futures.Metals.Silver,
Futures.Metals.Platinum,
Futures.Metals.Palladium,
Futures.Metals.AluminumMWUSTransactionPremiumPlatts25MT,
Futures.Metals.AluminiumEuropeanPremiumDutyPaidMetalBulletin,
Futures.Metals.Copper,
Futures.Metals.USMidwestDomesticHotRolledCoilSteelCRUIndex,
Futures.Softs.Sugar11CME,
Futures.Softs.Cocoa,
Futures.Dairy.CashSettledButter,
Futures.Dairy.CashSettledCheese,
Futures.Dairy.ClassIIIMilk,
Futures.Dairy.DryWhey,
Futures.Dairy.ClassIVMilk,
Futures.Dairy.NonfatDryMilk,
]
# region imports
from AlgorithmImports import *
# endregion
from Futs import futs_list
class FutureObject(object):
def __init__(self, algo, symbol):
self.algo = algo
self.future = self.algo.AddFuture(symbol, self.algo.Resolution, dataNormalizationMode = DataNormalizationMode.BackwardsRatio, dataMappingMode = DataMappingMode.OpenInterest, contractDepthOffset = 0)
self.consolidator = TradeBarConsolidator(timedelta(days=1)) # before continuous futures they recommended QuoteBarConsolidator.
self.consolidator.DataConsolidated += self.algo.OnDataConsolidated
self.algo.SubscriptionManager.AddConsolidator(self.future.Symbol, self.consolidator)
self.multiplier = self.future.SymbolProperties.ContractMultiplier
self.fast_ma_bars = 50
self.slow_ma_bars = 100
self.atr_bars = 100
self.lookback_bars = 252
self.fast_highlow_bars = 25
self.slow_highlow_bars = 50
self.fast_ma = SimpleMovingAverage(f"FAST_MA", self.fast_ma_bars)
self.slow_ma = SimpleMovingAverage(f"SLOW_MA", self.slow_ma_bars)
self.atr = AverageTrueRange(f"ATR", self.atr_bars)
self.fast_high = Maximum(f"FAST_HIGH", self.fast_highlow_bars)
self.slow_high = Maximum(f"SLOW_HIGH", self.slow_highlow_bars)
self.fast_low = Minimum(f"FAST_LOW", self.fast_highlow_bars)
self.slow_low = Minimum(f"SLOW_LOW", self.slow_highlow_bars)
self.logr = LogReturn(f"LOGR", 1)
self.logr.Updated += self.logr_updated
self.closes = RollingWindow[float](self.lookback_bars)
self.volumes = RollingWindow[float](3)
self.logrs = RollingWindow[float](self.lookback_bars)
self.volume = 0
self.invested = 0
self.size = 0
self.high_since_buy = 0
self.low_since_buy = 9e99
self.indicators = [
self.fast_ma,
self.slow_ma,
self.atr,
self.fast_high,
self.slow_high,
self.fast_low,
self.slow_low,
self.logr,
]
def reset(self):
self.invested = 0
self.size = 0
self.high_since_buy = 0
self.low_since_buy = 9e99
def logr_updated(self, sender, updated):
self.logrs.Add(updated.Value)
def is_ready(self):
for indicator in self.indicators:
if not indicator.IsReady:
return False
return True
def trade(self, close):
signal = self.signal(close)
if self.invested == 0:
if signal == 1: self.open_position(1, close)
elif signal == -1: self.open_position(-1, close)
else:
if signal == -1: self.close_position()
def close_position(self):
self.algo.Liquidate(self.future.Symbol)
self.reset()
def open_position(self, signal, price):
contracts = self.get_size(price)
if (signal == 1) and (contracts):
self.algo.Debug(f"Buying {self.future.Mapped}")
self.algo.Buy(self.future.Mapped, contracts)
self.size = contracts
self.invested = 1
elif (signal == -1) and (contracts):
self.algo.Debug(f"Shorting {self.future.Mapped}")
self.algo.Sell(self.future.Mapped, contracts)
self.size = contracts
self.invested = -1
def signal(self, close):
if self.invested == 0:
if (self.fast_ma.Current.Value > self.slow_ma.Current.Value) and (close > self.slow_high.Current.Value): return 1
if (self.fast_ma.Current.Value < self.slow_ma.Current.Value) and (close < self.slow_low.Current.Value): return -1
return 0
self.high_since_buy = np.max([self.high_since_buy, close])
self.low_since_buy = np.min([self.low_since_buy, close])
if self.invested == 1:
if (close < self.fast_low.Current.Value): return -1
if (close < self.high_since_buy - self.atr.Current.Value * 3): return -1
return 0
elif self.invested == -1:
if (close > self.fast_high.Current.Value): return -1
if (close > self.low_since_buy + self.atr.Current.Value * 3): return -1
return 0
def get_volume(self, close):
self.volume = np.mean([x for x in list(self.volumes)])
def get_size(self, price):
atr = self.atr.Current.Value
if atr == 0: return 0
num_contracts = (self.algo.risk_factor * self.algo.Portfolio.TotalPortfolioValue) / \
(atr * self.multiplier)
notional = num_contracts * self.multiplier * price
if (notional > self.algo.Portfolio.MarginRemaining):
self.algo.Debug(f"Not enough margin remaining to buy {num_contracts} of {self.future.Symbol} ({notional})")
return None
if (num_contracts < 1):
self.algo.Debug(f"Contracts too expensive (can't buy {num_contracts} of {self.future.Symbol})")
return 0
return num_contracts
def validate(self, data):
if (not self.future.Symbol in data.Bars) | (not self.algo.Securities.ContainsKey(self.future.Symbol)):
# if self.invested != 0: self.close_position()
return False
return True
class FatOrangePelican(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 11, 28) # Set Start Date
self.SetCash(1_000_000) # Set Strategy Cash
self.risk_factor = 0.005
self.Resolution = Resolution.Minute
self.n_contracts = 40
self.tickers = [ Futures.Indices.SP500EMini, Futures.Indices.NASDAQ100EMini, Futures.Indices.Russell2000EMini, Futures.Indices.Nikkei225Dollar, Futures.Indices.HangSeng, Futures.Indices.FTSEEmergingEmini, \
Futures.Currencies.AUD, Futures.Currencies.GBP, Futures.Currencies.EUR, Futures.Currencies.JPY, Futures.Currencies.NZD, Futures.Currencies.CAD, Futures.Currencies.CHF, \
Futures.Grains.Corn, Futures.Forestry.RandomLengthLumber, Futures.Meats.LiveCattle, Futures.Meats.LeanHogs, Futures.Grains.Oats, Futures.Grains.Soybeans, Futures.Softs.Sugar11CME, Futures.Grains.SRWWheat, \
Futures.Energies.CrudeOilWTI, Futures.Energies.HeatingOil, Futures.Energies.NaturalGas, Futures.Energies.Gasoline, \
Futures.Metals.Gold, Futures.Metals.Palladium, Futures.Metals.Platinum, Futures.Metals.Silver, \
Futures.Financials.Y30TreasuryBond, Futures.Financials.Y10TreasuryNote, Futures.Financials.Y5TreasuryNote, Futures.Financials.Y2TreasuryNote, Futures.Financials.EuroDollar]
self.futures = { x.future.Symbol:x for x in [FutureObject(self, y) for y in self.tickers] }
def OnDataConsolidated(self, sender, bar: TradeBar):
symbol = bar.Symbol
future = self.futures[symbol]
for indicator in future.indicators:
if indicator.Name == 'ATR': indicator.Update(bar)
else: indicator.Update(bar.Time, bar.Close)
future.closes.Add(bar.Close)
future.volumes.Add(bar.Volume * future.multiplier * bar.Close)
def OnData(self, data: Slice):
if len([x.is_ready() for x in self.futures.values()]) == 0:
return
# universe = self.get_universe(data)
# self.Debug(f"Validating...")
for f in self.futures.values():
if not f.validate(data):
continue
# self.Debug(f"Successfully validated {f.future.Symbol}")
close = data.Bars[f.future.Symbol].Close
f.trade(close)
# self.Debug(str([x.Value for x in self.Portfolio.Keys]))
def get_universe(self, data):
min_volume = sorted([future.volume for future in self.futures.values() if future.validate(data)], reverse=True)
if len(min_volume) == 0: min_volume = 0
else: min_volume = min_volume[min(len(min_volume)-1, self.n_contracts)]
universe = [future for future in self.futures.values() if (future.volume >= min_volume) and (future.validate(data))]
return universe