All market gains since 1993 have occurred after hours

Discussion in 'Trading' started by krugman25, Apr 13, 2019.

  1. krugman25

    krugman25 Guest

    Something interesting that could be done here is to break down relative performed of day-of-week performance by year. If the relative performance ratios hold for each year then there may be something here worth looking into.
     
    #191     Apr 18, 2019
  2. krugman25

    krugman25 Guest

    Here is some more testing with interesting results.

    The first test is only entering on either a Friday or Monday (trade would close either Monday or Tuesday). By doing this the R squared increases, largest draw down is significantly lower, the volume of trades are reduced by 60% (60% lower overall commissions and fees), and the relative average daily gain remains the same.

    The second test has the same parameters as the first but in addition it only trades overnight when the previous daytime session was down, and only if it was down by more than -0.5%. What it looks like to me, in my short time testing, is that performance is generally worse when the market goes up by any amount in the previous session, and also when the previous session didn't move much. The best performance slice of that pie is when the previous session is down by a decent amount.

    Profit factor for these two tests are 1.51(second test) compared to 1.31(first test), so the overall bang for your buck increases when you add these thresholds, but it significantly reduces number of trading opportunities. 2500+ trades for the first test compared to 500 for the second test.

    First Test
    Monday_Tuesday_Only.png Monday_Tuesday_Only_Metrics.png

    Second Test
    Monday_Tuesday_Only_With_Thresholds.png Monday_Tuesday_Only_With_Thresholds_Metrics.png
     
    Last edited by a moderator: Apr 18, 2019
    #192     Apr 18, 2019
  3. krugman25

    krugman25 Guest

    It's funny how we stumble up these things, but it turns out if I take the exact same parameters of test #2, but rather than use the past day I use the past 5 day, it significantly increases the performance metrics. It's darn near a straight line up with a 0.95 r squared.


    Third Test
    Monday_Tuesday_Only_With_Thresholds_Week.png Monday_Tuesday_Only_With_Thresholds_Week_Metrics.png
     
    Last edited by a moderator: Apr 18, 2019
    #193     Apr 18, 2019
  4. Overnight

    Overnight

    Well, there's only one thing for it. Do it live and see how it goes. If you just happen to start at the beginning of any of those down spikes, yer account is blown out.

    If you manage to survive those down spikes, yer a year out and are at break-even. Krug, your analysis is flawed. It all looks great on a chart, but it does not work in RL. If you think it can, try it.

    I'll be trying it on the equity micros when they come out. But those charts are nothing to toot upon, in my book, and my opine.
     
    #194     Apr 18, 2019
  5. krugman25

    krugman25 Guest

    Patience my friend. More testing to do. If something doesn't work in a perfect condition back test why would it work live? I want to find something that performs superbly in back test, then it may perform decently in live trading once commissions, fees, spread, etc. take a bite out of it.

    Your being kind of a drama queen. Show me the big down spike in any of those tests I just showed. Also, if your not leveraged then how is this any more dangerous than a buy and hold?


    Patience my friend. More testing to do.

    I will likely as well. It's a good sized product to do live testing of these things.
     
    #195     Apr 18, 2019
  6. krugman25

    krugman25 Guest

    Your talking to a guy that has been developing and improving a natural gas pipeline monitor system for 8 years now. I know patience. I am in no hurry. The markets are not going anywhere. This thread hasn't even been running for a week.
     
    #196     Apr 18, 2019
  7. Overnight

    Overnight

    Yes sir.
     
    #197     Apr 18, 2019
    krugman25 likes this.
  8. krugman25

    krugman25 Guest

    For whoever wants the source code...

    If there is a bug please let me know. This is 100% subject to change. We will call this version 1.

    #region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.Indicators;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class AfterHoursStudy : Strategy
    {
    private DateTime openTradeTime;
    private DateTime closeTradeTime;
    private bool buyAndHold;
    private int sharesToTrade;
    private double previousDayBuyThresholdGreaterThan;
    private double previousDayBuyThresholdLessThan;
    private bool doReinvestGains;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"To backtest the performance of trading market hours and after hours seperately.";
    Name = "AfterHoursStudy";
    Calculate = Calculate.OnBarClose;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = false;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 1;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;

    OpenTradeTime = default(DateTime);
    closeTradeTime = default(DateTime);
    buyAndHold = false;
    sharesToTrade = 50;
    previousDayBuyThresholdGreaterThan = 5;
    previousDayBuyThresholdLessThan = -5;
    doReinvestGains = false;
    }
    else if (State == State.Configure)
    {
    openTradeTime = OpenTradeTime;
    closeTradeTime = CloseTradeTime;
    buyAndHold = BuyAndHold;
    sharesToTrade = SharesToTrade;
    previousDayBuyThresholdGreaterThan = PreviousDayBuyThresholdGreaterThan;
    previousDayBuyThresholdLessThan = PreviousDayBuyThresholdLessThan;
    doReinvestGains = DoReinvestGains;
    }
    }

    protected override void OnBarUpdate()
    {

    //Print(Time[0].ToString("MM/dd/yyyy HH:mm") + "-" + Close[0]);

    if (CurrentBar < BarsRequiredToTrade)
    return;

    DateTime currentTimeInLocalTimezone = DateTime.SpecifyKind(Time[0], DateTimeKind.Local);
    DateTime _openTradeTime = openTradeTime;
    DateTime _closeTradeTime = closeTradeTime;

    if(currentTimeInLocalTimezone.IsDaylightSavingTime())
    {
    _openTradeTime = openTradeTime.AddHours(1);
    _closeTradeTime = closeTradeTime.AddHours(1);
    }

    if (Position.MarketPosition == MarketPosition.Flat)
    {
    if(buyAndHold)
    EnterLong();
    else if (currentTimeInLocalTimezone.Hour == _openTradeTime.Hour && currentTimeInLocalTimezone.Minute == _openTradeTime.Minute)
    {
    double previousSessionPerformance = (Close[0] - Close[10]) / Close[10] * 100;

    // Print("session start: " + Time[2].ToString("MM/dd/yyyy HH:mm") + "-" + Close[2]);
    // Print("session end (current): " + Time[0].ToString("MM/dd/yyyy HH:mm") + "-" + Close[0]);
    // Print("Previous Session performance: " + previousSessionPerformance);

    if(previousSessionPerformance > PreviousDayBuyThresholdGreaterThan || previousSessionPerformance < PreviousDayBuyThresholdLessThan)
    {
    int additionalShares = 0;

    if(doReinvestGains)
    additionalShares = (int)(SystemPerformance.AllTrades.TradesPerformance.NetProfit / Close[0]);

    if(currentTimeInLocalTimezone.DayOfWeek == DayOfWeek.Friday ||
    currentTimeInLocalTimezone.DayOfWeek == DayOfWeek.Monday)
    EnterLong(sharesToTrade + additionalShares);
    }

    //Print("Opened: " + Time[0].ToString("MM/dd/yyyy HH:mm") + "-" + Close[0]);
    }
    }
    else
    {
    if(!buyAndHold)
    {
    //Print("Closed: " + Time[0].ToString("MM/dd/yyyy HH:mm") + "-" + Close[0]);
    if (currentTimeInLocalTimezone.Hour == _closeTradeTime.Hour && currentTimeInLocalTimezone.Minute == _closeTradeTime.Minute)
    ExitLong();
    }
    }
    }

    #region Properties

    [Display(ResourceType = typeof(Custom.Resource), Name = "Shares to Trade", GroupName = "Order Timing", Order = 1)]
    public int SharesToTrade {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Open Trade Time (local DST)", GroupName = "Order Timing", Order = 2)]
    [Gui.PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")]
    public DateTime OpenTradeTime {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Close Trade Time (local DST)", GroupName = "Order Timing", Order = 3)]
    [Gui.PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")]
    public DateTime CloseTradeTime {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Buy and Hold (override)", GroupName = "Order Timing", Order = 4)]
    public bool BuyAndHold {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Previous Day Gains Buy Threshhold (greater than)", GroupName = "Order Timing", Order = 5)]
    public double PreviousDayBuyThresholdGreaterThan {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Previous Day Gains Buy Threshhold (less than)", GroupName = "Order Timing", Order = 6)]
    public double PreviousDayBuyThresholdLessThan {get; set;}

    [Display(ResourceType = typeof(Custom.Resource), Name = "Reinvest Gains", GroupName = "Order Timing", Order = 7)]
    public bool DoReinvestGains {get; set;}

    #endregion
    }
    }
     
    #198     Apr 18, 2019
  9. krugman25

    krugman25 Guest

    So if we want to start talking realism, then we need to reinvest gains. There is no way we are going to be trading the same lot size in 2019 as we were in 1993. I added a few lines of code to take the gains and buy that many whole numbers of shares. The results are a 61% increase in profits by reinvesting, from $68,000 to $110,000.

    Not Reinvested
    NotReinvested.png

    Reinvested
    Reinvested.png
     
    #199     Apr 18, 2019
    userque likes this.
  10. Overnight

    Overnight

    Ahh, there's the rub. There had to be a caveat.
     
    #200     Apr 18, 2019