Moving Average cBot to enter trades after crossover and when averages are certain distance apart (in PIPS)
Moving Average cBot to enter trades after crossover and when averages are certain distance apart (in PIPS)
16 Aug 2019, 13:01
Hey all,
I want to be able to set a pip amount as a perameter and the cBot will only open an order once the averages have crossed over and are equal to or more than the pip amount set away from eachother.
Help please (code below),
Samuel
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; /* * POPULAR SIMPLE MOVING AVERAGES * * The simple moving average (SMA) is the most basic of the moving averages used for trading. * The simple moving average formula is calculated by taking the average closing price of a stock over the last "x" periods. * * 5 - SMA - For the hyper trader. This short of an SMA will constantly give you signals. The best use of a 5-SMA is as a trade trigger in conjunction with a longer SMA period. * 10 - SMA - popular with the short-term traders. Great swing traders and day traders. * 20 - SMA - the last stop on the bus for short-term traders. Beyond 20-SMA you are basically looking at primary trends. * 50 - SMA - use the trader to gauge mid-term trends. * 200 -SMA - welcome to the world of long-term trend followers. Most investors will look for a cross above or below this average to represent if the stock is in a bullish or bearish trend. */ namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class ClickAlgoSchoolSMA : Robot { #region User defined parameters [Parameter("Instance Name", DefaultValue = "001")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source SMA #1")] public DataSeries SourceSma1 { get; set; } [Parameter("Source SMA #2")] public DataSeries SourceSma2 { get; set; } [Parameter("Period SMA #1", DefaultValue = 5, MinValue = 1, MaxValue = 100)] public int PeriodsSma1 { get; set; } [Parameter("Period SMA #2", DefaultValue = 20, MinValue = 1, MaxValue = 100)] public int PeriodsSma2 { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } #endregion #region Indicator declarations private SimpleMovingAverage _sma1 { get; set; } private SimpleMovingAverage _sma2 { get; set; } #endregion #region cTrader events /// <summary> /// This is called when the robot first starts, it is only called once. /// </summary> protected override void OnStart() { // construct the indicators _sma1 = Indicators.SimpleMovingAverage(SourceSma1, PeriodsSma1); _sma2 = Indicators.SimpleMovingAverage(SourceSma2, PeriodsSma2); } /// <summary> /// This method is called every time the price changes for the symbol /// </summary> protected override void OnTick() { if (CalculateOnBar) { return; } ManagePositions(); } /// <summary> /// This method is called at every candle (bar) close, when it has formed /// </summary> protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePositions(); } /// <summary> /// This method is called when your robot stops, can be used to clean-up memory resources. /// </summary> protected override void OnStop() { // unused } #endregion #region Position management private void ManagePositions() { if (_sma1.Result.LastValue > _sma2.Result.LastValue) { // if there is no buy position open, open one and close any sell position that is open if (!IsPositionOpenByType(TradeType.Buy)) { OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } // if a sell position is already open and signal is buy do nothing if (_sma1.Result.LastValue < _sma2.Result.LastValue) { // if there is no sell position open, open one and close any buy position that is open if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } /// <summary> /// Opens a new long position /// </summary> /// <param name="type"></param> private void OpenPosition(TradeType type) { // calculate volume from lot size. long volume = Symbol.QuantityToVolume(LotSize); // open a new position ExecuteMarketOrder(type, this.Symbol, volume, InstanceName, null, null); } /// <summary> /// /// </summary> /// <param name="type"></param> private void ClosePosition(TradeType type) { var p = Positions.Find(InstanceName, this.Symbol, type); if (p != null) { ClosePosition(p); } } #endregion #region Position Information /// <summary> /// /// </summary> /// <param name="type"></param> /// <returns></returns> private bool IsPositionOpenByType(TradeType type) { var p = Positions.FindAll(InstanceName, Symbol, type); if (p.Count() >= 1) { return true; } return false; } #endregion } }
Replies
samuelbreezey
19 Aug 2019, 22:27
RE:
FireMyst said:
You need to calculate the difference in pips between the two emas.
Here's a function that will help you:
private double DifferenceInPips(Symbol s, double firstPrice, double secondPrice, bool returnAbs) { if (returnAbs) return Math.Abs((firstPrice - secondPrice) / s.PipSize); else return (firstPrice - secondPrice) / s.PipSize; }
Then change your condition from:
if (_sma1.Result.LastValue > _sma2.Result.LastValue)
to:
if (_sma1.Result.LastValue > _sma2.Result.LastValue && DifferenceInPips(Symbol, _sma1.Result.LastValue, _sma2.Result.LastValue, false) > whatever_amount_you_want)
Thank you,
Here's the code I have now, does this look okay? Do you not have to change the following coding as well?
if (_sma1.Result.LastValue < _sma2.Result.LastValue)
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; /* * POPULAR SIMPLE MOVING AVERAGES * * The simple moving average (SMA) is the most basic of the moving averages used for trading. * The simple moving average formula is calculated by taking the average closing price of a stock over the last "x" periods. * * 5 - SMA - For the hyper trader. This short of an SMA will constantly give you signals. The best use of a 5-SMA is as a trade trigger in conjunction with a longer SMA period. * 10 - SMA - popular with the short-term traders. Great swing traders and day traders. * 20 - SMA - the last stop on the bus for short-term traders. Beyond 20-SMA you are basically looking at primary trends. * 50 - SMA - use the trader to gauge mid-term trends. * 200 -SMA - welcome to the world of long-term trend followers. Most investors will look for a cross above or below this average to represent if the stock is in a bullish or bearish trend. */ namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class ClickAlgoSchoolSMA : Robot { #region User defined parameters [Parameter("Instance Name", DefaultValue = "001")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source SMA #1")] public DataSeries SourceSma1 { get; set; } [Parameter("Source SMA #2")] public DataSeries SourceSma2 { get; set; } [Parameter("Period SMA #1", DefaultValue = 5, MinValue = 1, MaxValue = 100)] public int PeriodsSma1 { get; set; } [Parameter("Period SMA #2", DefaultValue = 20, MinValue = 1, MaxValue = 100)] public int PeriodsSma2 { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } #endregion #region Indicator declarations private SimpleMovingAverage _sma1 { get; set; } private SimpleMovingAverage _sma2 { get; set; } #endregion #region cTrader events /// <summary> /// This is called when the robot first starts, it is only called once. /// </summary> protected override void OnStart() { // construct the indicators _sma1 = Indicators.SimpleMovingAverage(SourceSma1, PeriodsSma1); _sma2 = Indicators.SimpleMovingAverage(SourceSma2, PeriodsSma2); } /// <summary> /// This method is called every time the price changes for the symbol /// </summary> protected override void OnTick() { if (CalculateOnBar) { return; } ManagePositions(); } /// <summary> /// This method is called at every candle (bar) close, when it has formed /// </summary> protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePositions(); } /// <summary> /// This method is called when your robot stops, can be used to clean-up memory resources. /// </summary> protected override void OnStop() { // unused } #endregion #region Position management private double DifferenceInPips(Symbol s, double firstPrice, double secondPrice, bool returnAbs) { if (returnAbs) return Math.Abs((firstPrice - secondPrice) / s.PipSize); else return (firstPrice - secondPrice) / s.PipSize; } private void ManagePositions() { if (_sma1.Result.LastValue > _sma2.Result.LastValue && DifferenceInPips(Symbol, _sma1.Result.LastValue, _sma2.Result.LastValue, false) > 20) { // if there is no buy position open, open one and close any sell position that is open if (!IsPositionOpenByType(TradeType.Buy)) { OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } // if a sell position is already open and signal is buy do nothing if (_sma1.Result.LastValue < _sma2.Result.LastValue) { // if there is no sell position open, open one and close any buy position that is open if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } /// <summary> /// Opens a new long position /// </summary> /// <param name="type"></param> private void OpenPosition(TradeType type) { // calculate volume from lot size. long volume = Symbol.QuantityToVolume(LotSize); // open a new position ExecuteMarketOrder(type, this.Symbol, volume, InstanceName, null, null); } /// <summary> /// /// </summary> /// <param name="type"></param> private void ClosePosition(TradeType type) { var p = Positions.Find(InstanceName, this.Symbol, type); if (p != null) { ClosePosition(p); } } #endregion #region Position Information /// <summary> /// /// </summary> /// <param name="type"></param> /// <returns></returns> private bool IsPositionOpenByType(TradeType type) { var p = Positions.FindAll(InstanceName, Symbol, type); if (p.Count() >= 1) { return true; } return false; } #endregion } }
Thanks Samuel
@samuelbreezey
firemyst
17 Aug 2019, 18:26
You need to calculate the difference in pips between the two emas.
Here's a function that will help you:
Then change your condition from:
if (_sma1.Result.LastValue > _sma2.Result.LastValue)
to:
if (_sma1.Result.LastValue > _sma2.Result.LastValue && DifferenceInPips(Symbol, _sma1.Result.LastValue, _sma2.Result.LastValue, false) > whatever_amount_you_want)
@firemyst