Troubleshooting a cBot for trading by price crosses the MA
Troubleshooting a cBot for trading by price crosses the MA
12 Apr 2019, 19:58
Hello and good day everyone
I've borrowed a code that was originally designed to trade by MA crosses and modified it to operate when the price crosses a single MA but i'm getting some errors and the code doesn't compile
The original code:
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; } [Parameter("Include Trailing Stop", DefaultValue = false)] public bool IncludeTrailingStop { get; set; } [Parameter("Trailing Stop Trigger (pips)", DefaultValue = 20)] public int TrailingStopTrigger { get; set; } [Parameter("Trailing Stop Step (pips)", DefaultValue = 10)] public int TrailingStopStep { get; set; } #endregion #region Indicator declarations private SimpleMovingAverage _sma1 { get; set; } private SimpleMovingAverage _sma2 { get; set; } #endregion
My code:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class X : 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")] public DataSeries SourceSma1 { get; set; } [Parameter("Period", DefaultValue = 1, MinValue = 1, MaxValue = 1000)] public int Periodwma { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } [Parameter("Take Profit", DefaultValue = null, MinValue = null, Step = 1)] public double TakeP { get; set; } [Parameter("Stop Loss", DefaultValue = null, MaxValue = null, Step = 1)] public double StopL { get; set; } [Parameter("Include Trailing Stop", DefaultValue = false)] public bool IncludeTrailingStop { get; set; } [Parameter("Trailing Stop Trigger (pips)", DefaultValue = 20)] public int TrailingStopTrigger { get; set; } [Parameter("Trailing Stop Step (pips)", DefaultValue = 10)] public int TrailingStopStep { get; set; } #endregion #region Indicator declarations private WeightedMovingAverage { 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 wma = Indicators.WeightedMovingAverage(SourceSma1, PeriodsSma1); } /// <summary> /// This method is called every time the price changes for the symbol /// </summary> protected override void OnTick() { if (CalculateOnBar) { return; } ManagePositions(); if (IncludeTrailingStop) { SetTrailingStop(); } } /// <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 (wma.Result.LastValue.HasCrossedAbove) { // 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 (wma.Result.LastValue.HasCrossedBelow) { // 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, StopL, TakeP); } /// <summary> /// /// </summary> /// <param name="type"></param> private void ClosePosition(TradeType type) { var p = Positions.Find(InstanceName, this.Symbol, type); if (p != null) { ClosePosition(p); } } /// <summary> /// When the profit in pips is above or equal to Trigger the stop loss will start trailing the spot price. /// TrailingStop defines the number of pips the Stop Loss trails the spot price by. /// If Trigger is 0 trailing will begin immediately. /// </summary> private void SetTrailingStop() { var sellPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Sell); foreach (Position position in sellPositions) { double distance = position.EntryPrice - Symbol.Ask; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice < position.StopLoss) { ModifyPosition(position, newStopLossPrice, position.TakeProfit); } } var buyPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Buy); foreach (Position position in buyPositions) { double distance = Symbol.Bid - position.EntryPrice; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice > position.StopLoss) { ModifyPosition(position, newStopLossPrice, position.TakeProfit); } } } #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 } }
I was wondering if anyone can help me find out what am I doing wrong
Best regards
Replies
... Deleted by UFO ...
PanagiotisCharalampous
14 Apr 2019, 13:26
Hi pejman101,
There are several errors in your code. See below
#region Indicator declarations private WeightedMovingAverage { get; set; } #endregion
You don't declare any parameter name here
/// <summary> /// This is called when the robot first starts, it is only called once. /// </summary> protected override void OnStart() { // construct the indicators wma = Indicators.WeightedMovingAverage(SourceSma1, PeriodsSma1); }
PeriodsSma1 is not defined anywhere
if (wma.Result.LastValue.HasCrossedAbove) { // 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 (wma.Result.LastValue.HasCrossedBelow) { // 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); }
?HasCrossedAbove and HasCrossedBelow are not used properly. See here and here how to use them.
Best Regards,
Panagiotis
@PanagiotisCharalampous
pejman101
14 Apr 2019, 19:57
RE:
Panagiotis Charalampous said:
Hi pejman101,
There are several errors in your code. See below
#region Indicator declarations private WeightedMovingAverage { get; set; } #endregionYou don't declare any parameter name here
/// <summary> /// This is called when the robot first starts, it is only called once. /// </summary> protected override void OnStart() { // construct the indicators wma = Indicators.WeightedMovingAverage(SourceSma1, PeriodsSma1); }PeriodsSma1 is not defined anywhere
if (wma.Result.LastValue.HasCrossedAbove) { // 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 (wma.Result.LastValue.HasCrossedBelow) { // 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); }?HasCrossedAbove and HasCrossedBelow are not used properly. See here and here how to use them.
Best Regards,
Panagiotis
Thank you very much for your time and help!
I fixed all the issues accordingly and it works perfectly now!
@pejman101
pejman101
12 Apr 2019, 20:01
The compelete original code
@pejman101