Good evening all,
I am very new to QC and to coding and strive to figure things out on my own before seeking help. So, now I seek help. I have cloned the below algorithm below and made a few modifications. The question I have today and as you can see below: I am trying to apply a 5 period SMA using the Close and a 5 period SMA using the open. Yes, both are 5 periods but I am trying to use it as an indicator for when the open crosses below the close. I've modeled this perfectly in R with some additional variables and conditions for profit/loss and risk management.
I don't think I am using the Field Selectors appropriately or at least I don't think the functionality aligns with what I am aiming for. Any help would be appreciated. Thanks.
Very respectfully,
Geno
using System;
using System.Linq;
using QuantConnect.Indicators;
using QuantConnect.Models;
using QuantConnect.Algorithm;
using QuantConnect.Data.Market;
using QuantConnect.Data;
namespace QuantConnect.Algorithm.Examples
{
/// <summary>
///
/// QuantConnect University: EMA + SMA Cross
///
/// In this example we look at the canonical 15/30 day moving average cross. This algorithm
/// will go long when the 15 crosses above the 30 and will liquidate when the 15 crosses
/// back below the 30.
/// </summary>
public class MySma : QCAlgorithm, IAlgorithm
{
private SimpleMovingAverage fast;
private SimpleMovingAverage slow;
private SimpleMovingAverage[] ribbon;
private string symbol = "EURUSD";
public override void Initialize()
{
// set up our analysis span
SetStartDate(2015, 01, 01);
SetEndDate(2015, 06, 01);
// request SPY data with minute resolution
AddSecurity(SecurityType.Forex, symbol, Resolution.Minute);
Securities[symbol].FeeModel = new ConstantFeeModel(0.0m);
// create a 15 day exponential moving average
fast = SMA(symbol, 5, Resolution.Minute, Field.Open);
// create a 30 day exponential moving average
slow = SMA(symbol, 5, Resolution.Minute, Field.Close);
// the following lines produce a simple moving average ribbon, this isn't
// actually used in the algorithm's logic, but shows how easy it is to make
// indicators and plot them!
// note how we can easily define these indicators to receive hourly data
int ribbonCount = 7;
int ribbonInterval = 15*8;
ribbon = new SimpleMovingAverage[ribbonCount];
for(int i = 0; i < ribbonCount; i++)
{
ribbon[i] = SMA(symbol, (i + 1)*ribbonInterval, Resolution.Hour);
}
}
private DateTime previous;
public override void OnData(Slice data)
{
// a couple things to notice in this method:
// 1. We never need to 'update' our indicators with the data, the engine takes care of this for us
// 2. We can use indicators directly in math expressions
// 3. We can easily plot many indicators at the same time
// wait for our slow ema to fully initialize
if (!slow.IsReady) return;
// only once per day
////if (previous.Date == Time.Date) return;
// define a small tolerance on our checks to avoid bouncing
const decimal tolerance = 0.0m;
var holdings = Portfolio[symbol].Quantity;
// we only want to go long if we're currently short or flat
if (holdings <= 0)
{
// if the fast is greater than the slow, we'll go long
if (fast > slow)// * (1 + tolerance))
{
Log("BUY >> " + Securities[symbol].Price);
SetHoldings(symbol, 1.0);
}
}
// we only want to liquidate if we're currently long
// if the fast is less than the slow we'll liquidate our long
if (holdings > 0 && fast < slow)
{
Log("SELL >> " + Securities[symbol].Price);
Liquidate(symbol);
}
//Plot(symbol, "Price", data[symbol].Price);
//Plot("Ribbon", "Price", data[symbol].Price);
// easily plot indicators, the series name will be the name of the indicator
Plot(symbol, fast, slow);
Plot("Ribbon", ribbon);
previous = Time;
}
}
}
JayJayD
Hi there Genorse,
You're almost there!
If you check the SMA method, you'll see that the selector's argument is an IBaseData. That abstraction only has one property for the price, the Close. But you can cast it to a QuoteBar in order to get the OHLC data. Like this:
fast = SMA(symbol, 5, selector: d => ((QuoteBar)d).Low);
Check the logs in the attached backtest.
Hope it helps.
Genorse Gilbert
Thanks JayJayD! That worked perfect. I changed the Selector Type "d" to "m". I assume it stands for "day" and "minute" respectively; let me know if I am wrong. Thanks again.
V/R,
Geno
Genorse Gilbert
Also, I checked the log in the backtest that you attached; the current SMA and the current Low for the same time stamp does not match. Should it match? Thanks.
V/R,
Geno
JayJayD
Genorse,
I'm glad I helped.
The d is an input name in a lambda expression, it can be anything, I choose d because in this case represents the input data.
Remember, SMA stands for Simple Moving Average, in this case is the average of the last 15 observations. So, the current SMA should be equal to the mean of the last 15 low observations.
Genorse Gilbert
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!