| 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;
}
}
}