Overall Statistics
Total Trades
214
Average Win
0.71%
Average Loss
-0.76%
Compounding Annual Return
-5.505%
Drawdown
36.400%
Expectancy
-0.526
Net Profit
-34.970%
Sharpe Ratio
-0.724
Probabilistic Sharpe Ratio
0.000%
Loss Rate
75%
Win Rate
25%
Profit-Loss Ratio
0.93
Alpha
-0.037
Beta
0
Annual Standard Deviation
0.051
Annual Variance
0.003
Information Ratio
-0.803
Tracking Error
0.16
Treynor Ratio
-615.112
Total Fees
$236548.40
Estimated Strategy Capacity
$50000.00
Lowest Capacity Asset
ZC YY8E90VXTCTH
################################################################################
# QUANTARMY FUTURE SPREADER
# ----------------------------------
#
# ABSTRACT:
# -------
# PROOF OF CONCEPT OF A SPREAD TRADE IN QUANTCONNECT
# - TRY TO ADJUST TO SEASONAL SPREAD TRADE
#
#
#
#   ---> JCX 2022/08 V0.1 WWW.QUANTARMY.COM
#
################################################################################


from AlgorithmImports import *


class QAFutureSpreader(QCAlgorithm):

    # ==================================================================================
    # Reserved for future comments
    # ==================================================================================
    def Initialize(self):
        self.SetStartDate(2015, 1, 1)    
        self.SetCash(100000000)             
        self.corn = self.AddFuture(Futures.Grains.Corn, Resolution.Daily)
        self.symbolcorn = self.corn.Symbol
        self.corn.SetFilter(lambda x: x.ExpirationCycle([1, 12]))

        self.wheat = self.AddFuture(Futures.Grains.Wheat, Resolution.Daily)
        self.symbolwheat = self.wheat.Symbol
        self.wheat.SetFilter(lambda x: x.ExpirationCycle([1,12]))
        self.SetWarmup(21)
        self.fecha = self.Time

    def OnData(self, slice: Slice) -> None:

            chain = slice.FuturesChains.get(self.symbolcorn)
            chain2 = slice.FutureChains.get(self.symbolwheat)


            if chain and chain2:
                contract = sorted(chain, key=lambda contract: contract.Expiry, reverse=True)[0]
                contract2 = sorted(chain2, key =lambda contract: contract.Expiry, reverse=True)[0]

                if not self.Portfolio.Invested:
                    # if day == day when start the seasonal edge
                    # create the spread
                    # need to select month of expiring of the asset
                    # Exact, how to go to ESZ23 future exactly or similar

                    self.SetHoldings(contract.Symbol, 0.01)
                    self.fecha = self.Time
                    self.SetHoldings(contract2.Symbol, -0.01)
        
                else:
                    # If we stay in a trade and its time go go out, just liquidate.
                    if self.Time > self.fecha +timedelta(30):
                        self.Liquidate()