| Overall Statistics |
|
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return -6.990% Drawdown 8.900% Expectancy 0 Net Profit 0% Sharpe Ratio -0.585 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.022 Beta -0.315 Annual Standard Deviation 0.079 Annual Variance 0.006 Information Ratio -2.299 Tracking Error 0.115 Treynor Ratio 0.148 Total Fees $2.00 |
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using System;
using System.Linq;
namespace QuantConnect.Algorithm.CSharp
{
public class QCUMovingAverageCross : QCAlgorithm
{
int cnt = 0;
const decimal tolerance = 0.00015m;
private const string ticker = "EURUSD";
Symbol symbol;
private AverageTrueRange atr;
private SimpleMovingAverage ma100_h1;
private SimpleMovingAverage ma100_m30;
private SimpleMovingAverage ma100_m15;
private SimpleMovingAverage ma50_m30;
public override void Initialize()
{
// set up our analysis span
SetStartDate(2016, 11, 01);
SetEndDate(2017, 03, 15);
SetCash(1000);
symbol = AddForex(ticker, market: Market.Oanda).Symbol;
ma100_h1 = SMA(symbol, 100, Resolution.Hour);
ma100_m15 = new SimpleMovingAverage(100);
ma50_m30 = new SimpleMovingAverage(50);
ma100_m30 = new SimpleMovingAverage(100);
/*var fifteenMinuteConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(15));
SubscriptionManager.AddConsolidator(symbol, fifteenMinuteConsolidator);
fifteenMinuteConsolidator.DataConsolidated += FifteenMinuteConsolidator_DataConsolidated; ;*/
var thirtyMinuteConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(30));
SubscriptionManager.AddConsolidator(symbol, thirtyMinuteConsolidator);
thirtyMinuteConsolidator.DataConsolidated += ThirtyMinuteConsolidator_DataConsolidated; ;
atr = ATR(symbol, 360, MovingAverageType.Simple, Resolution.Minute);
SetWarmUp(TimeSpan.FromDays(1));
}
private void FifteenMinuteConsolidator_DataConsolidated(object sender, QuoteBar e)
{
}
private void ThirtyMinuteConsolidator_DataConsolidated(object sender, QuoteBar e)
{
ma100_h1.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
ma100_m15.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
ma50_m30.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
ma100_m30.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
//atr.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
}
//private DateTime previous;
public override void OnData(Slice data)
{
if (IsWarmingUp || !data.ContainsKey(symbol)) return;
var atrLoss = atr * 3.3m;
var atrProfit = atr * 1.5m;
var stopLossLong = Securities[symbol].Price - atrLoss;
var takeProfitLong = Securities[symbol].Price + atrProfit;
var stopLossShort = Securities[symbol].Price + atrLoss;
var takeProfitShort = Securities[symbol].Price - atrProfit;
// Here you can use LINQ to select the tickets you need.
var openLongOrderTicket = Transactions.GetOrderTickets(o => o.Status == OrderStatus.Filled && o.Quantity > 0)
.FirstOrDefault();
var openShortOrderTicket = Transactions.GetOrderTickets(o => o.Status == OrderStatus.Filled && o.Quantity < 0)
.FirstOrDefault();
if (enterLong() && Portfolio[symbol].Quantity == 0)//!Portfolio[symbol].Invested)
{
Debug("long " + Securities[symbol].Price + " SL: " + stopLossLong + " TP: " + takeProfitLong);
openLongOrderTicket = StopLimitOrder(symbol, 1000, stopLossLong, takeProfitLong, "test"); //minimum FXCM ordersize = 1K = 1000
Debug(Portfolio[symbol].Quantity.ToString());
//Debug(cnt.ToString());
}
if (enterShort() && (Portfolio[symbol].Quantity == 0))
{
Debug(Portfolio[symbol].Quantity.ToString());
Debug("short " + Securities[symbol].Price + " SL: " + stopLossShort + " TP: " + takeProfitShort);
openShortOrderTicket = StopLimitOrder(symbol, -1000, stopLossShort, takeProfitShort, "test");
Debug(Portfolio[symbol].Quantity.ToString());
//Debug(cnt.ToString());
}
if (openLongOrderTicket != null)
{
var stopPrice = openLongOrderTicket.Get(OrderField.StopPrice);
if (stopPrice < stopLossLong)
{
//Debug(Portfolio.CashBook["USD"].Amount.ToString());
openLongOrderTicket.Update(new UpdateOrderFields { StopPrice = stopLossLong });
}
}
if (openShortOrderTicket != null)
{
var stopPrice = openShortOrderTicket.Get(OrderField.StopPrice);
if (stopPrice > stopLossShort)
{
//Debug(Portfolio.CashBook["USD"].Amount.ToString());
openShortOrderTicket.Update(new UpdateOrderFields { StopPrice = stopLossShort });
}
}
cnt++;
if (cnt%2000 == 0)
{
Debug(Securities[symbol].Price.ToString());
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
switch (orderEvent.Status)
{
case OrderStatus.New:
break;
case OrderStatus.Submitted:
break;
case OrderStatus.PartiallyFilled:
break;
case OrderStatus.Filled:
break;
case OrderStatus.Canceled:
break;
case OrderStatus.None:
break;
case OrderStatus.Invalid:
break;
case OrderStatus.CancelPending:
break;
default:
break;
}
}
public override void OnEndOfDay()
{
Log("EOD " + Time.ToShortDateString());
}
private bool enterLong()
{
var price = Securities[symbol].Price;
if ((price > ma100_h1 * (1 + tolerance)) &&
(price > ma100_m30 * (1 + tolerance)) &&
(price > ma100_m15 * (1 + tolerance)) &&
(ma100_m30 > ma50_m30))
{
return true;
}
return false;
}
private bool enterShort()
{
var price = Securities[symbol].Price;
if ((price < ma100_h1 * (1 + tolerance)) &&
(price < ma100_m30 * (1 + tolerance)) &&
(price < ma100_m15 * (1 + tolerance)) &&
(ma100_m30 < ma50_m30))
{
return true;
}
return false;
}
}
}namespace QuantConnect {
//
// Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
// files use "public partial class" if you want to split up your algorithm namespace into multiple files.
//
//public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
//{
// Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
//}
//public class Indicator
//{
// ...or you can define whole new classes independent of the QuantConnect Context
//}
}namespace QuantConnect {
//
// Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
// files use "public partial class" if you want to split up your algorithm namespace into multiple files.
//
//public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
//{
// Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
//}
//public class Indicator
//{
// ...or you can define whole new classes independent of the QuantConnect Context
//}
}