Overall Statistics |
Total Trades 6 Average Win 0.02% Average Loss -0.04% Compounding Annual Return -0.373% Drawdown 0.000% Expectancy -0.026 Net Profit -0.003% Sharpe Ratio -1.65 Loss Rate 33% Win Rate 67% Profit-Loss Ratio 0.46 Alpha 0.019 Beta -2.266 Annual Standard Deviation 0.001 Annual Variance 0 Information Ratio -6.301 Tracking Error 0.002 Treynor Ratio 0.001 Total Fees $6.00 |
namespace QuantConnect.Algorithm.CSharp { /// <summary> /// Basic template algorithm simply initializes the date range and cash. This is a skeleton /// framework you can use for designing an algorithm. /// </summary> public class OcoTest : QCAlgorithm { private int _cash = 25000; private string _symbol = "AAPL"; Resolution _resolution=Resolution.Hour; /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2017, 6, 6); //Set Start Date SetEndDate(2017, 6, 8); //Set End Date SetCash(_cash); //Set Strategy Cash Transactions.MarketOrderFillTimeout = TimeSpan.FromSeconds(30); // Find more symbols here: http://quantconnect.com/data AddEquity(_symbol, _resolution); //Don't keep any positions overnight Schedule.On(DateRules.EveryDay(_symbol), TimeRules.BeforeMarketClose(_symbol, 55), () => //minutes before market close { Debug("BeforeMarketClose Liquidate"); Transactions.CancelOpenOrders(_symbol); Liquidate(); }); } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { var curBar = data[_symbol]; if(IsWarmingUp) return; //Check for bad Slice if(!ValidateTradeBar(curBar)){ Debug("INVALID TRADE BAR at:" + Time.ToString()); return; } var shares = 16; var price = Securities[_symbol].Price; var profitLossAmt = .24m; if(Time.Day == 6 && Time.Hour == 11) { //SHORT 16 shares Debug("Placing SHORT market order for " + shares.ToString()); MarketOrder(_symbol, shares * -1); LimitOrder(_symbol, shares, price - profitLossAmt ); //BUY LIMIT - profit StopMarketOrder(_symbol, shares, price + profitLossAmt); //BUY STOP - loss }else if(Time.Day == 7 && Time.Hour == 10){ //LONG 16 shares Debug("Placing LONG market order for " + shares.ToString()); MarketOrder(_symbol, shares); StopMarketOrder(_symbol, shares * -1, price - profitLossAmt); //SELL STOP - loss LimitOrder(_symbol, shares * -1, price + profitLossAmt ); //SELL LIMIT - profit } return; /* //Restrict trading time? - hours are: 10-16 if(Time.Hour >= 15) return; //Debug("hour is " + Time.Hour + " price: " + curBar.Open); //Calculate our average bar size var avgBarSize = CalcAverageBarSize(_stockData.HistoryWindow); //Debug("avgBarSize = " + avgBarSize.ToString()); //Get bar direction barDirection = GetBarDirection(curBar); //Debug("bar direction: " + barDirection.ToString()); //Return if no change? if(barDirection == EnumBarDirection.Flat){ return; } //Is our current bar >= multiple of average var currentBarSize = Math.Abs(curBar.Close - curBar.Open); //Debug("current bar size: " + currentBarSize.ToString() + " avg bar size: " + avgBarSize.ToString()); if(currentBarSize >= (avgBarSize * _triggerBarSizeMultiple)){ triggerBarSize = true; //Debug("TRIGGER BAR SIZE: " + currentBarSize.ToString()); } //if no bar trigger, exit if(!triggerBarSize) return; //Is EMA within current bar? var emaVal = _stockData.EmaWindow[0].Value; if(barDirection == EnumBarDirection.Up){ if(emaVal >= curBar.Open && emaVal <= curBar.Close){ triggerEmaWithinBar = true; } }else{ if(emaVal <= curBar.Open && emaVal >= curBar.Close){ triggerEmaWithinBar = true; } } if(triggerEmaWithinBar){ Debug("TRIGGER EMA WITHIN BAR - DIRECTION: " + barDirection + " avg bar size: " + avgBarSize.ToString()); } //If no ema in bar trigger ,exit //if(!triggerEmaWithinBar) return; var price = Securities[_symbol].Price; var shares = Math.Round((_cash * _tradePct) / price); var tradeKey = Time.ToString("yyyyddMM") + "-" + _symbol; //If we don't own and haven't traded it today (trade key), then trade if(!Portfolio[_symbol].Invested && !_trades.ContainsKey(tradeKey)){ if(barDirection == EnumBarDirection.Down){ //BUY Debug("Placing LONG market order for " + shares.ToString() + " @ " + price.ToString() + " " + tradeKey); var openTicket = MarketOrder(_symbol, shares); _openOrderIds.Add(openTicket.OrderId); StopMarketOrder(_symbol, shares * -1, price - avgBarSize); //SELL STOP - loss LimitOrder(_symbol, shares * -1, price + avgBarSize ); //SELL LIMIT - profit }else{ //SELL Debug("Placing SHORT market order for " + shares.ToString() + " @ " + price.ToString() + " " + tradeKey); var openTicket = MarketOrder(_symbol, shares * -1); _openOrderIds.Add(openTicket.OrderId); LimitOrder(_symbol, shares, price - avgBarSize ); //BUY LIMIT - profit StopMarketOrder(_symbol, shares, price + avgBarSize); //BUY STOP - loss } //Add trade to keep track of what we traded and when _trades.Add(tradeKey, shares.ToString() + " @ " + price.ToString()); } */ } // Override the base class event handler for order events public override void OnOrderEvent(OrderEvent orderEvent) { var order = Transactions.GetOrderById(orderEvent.OrderId); Debug(string.Format("OnOrderEvent: {0}: {1}: {2}", Time, order.Type, orderEvent)); //If we filled a non market order, close any other orders if(order.Type != OrderType.Market && orderEvent.Status == OrderStatus.Filled){ Debug(string.Format("Cancelling open orders for: {0}", orderEvent.Symbol)); Transactions.CancelOpenOrders(orderEvent.Symbol); } } private bool ValidateTradeBar(TradeBar bar){ return bar != null && bar.Open >= 0 && bar.Close >= 0; } } }