Hi, i have written the following bot based on a ma envelope strategy. It opens a position whenever price gets below or the upper or lower band, with a tp of 2pips. When backtesting on eurusd, with comimission set to 20 and spread to 0.2, it gives pretty nice results. I dont use ontick data, as my strategy is based on a onbar method. However during forward testing it looses money very quickly. Any idea why, and tips so it might work?
You should use the envelope indicator: https://ctrader.com/algos/indicators/show/281
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class NewcBot : Robot
{
[Parameter(DefaultValue = 52)]
public int EnvelopePeriod { get; set; }
[Parameter(DefaultValue = 0.101)]
public double BandDistance { get; set; }
[Parameter("Source")]
public DataSeries Source { get; set; }
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("Periodpricema", DefaultValue = 2)]
public int Periodsprice { get; set; }
[Parameter("TP", DefaultValue = 2)]
public int TP { get; set; }
[Parameter("SL", DefaultValue = 10000)]
public int SL { get; set; }
private ExponentialMovingAverage emaprice;
private EnvelopeChannels envelopeChannels;
protected override void OnStart()
{
emaprice = Indicators.ExponentialMovingAverage(Source, Periodsprice);
envelopeChannels = Indicators.GetIndicator<EnvelopeChannels>(EnvelopePeriod, BandDistance, MovingAverageType.Simple);
}
protected override void OnBar()
{
var currentPriceMa = emaprice.Result.Last(1);
var previousPriceMa = emaprice.Result.Last(2);
var channelup = envelopeChannels.ChannelUp.Last(1);
var prevchannelup = envelopeChannels.ChannelUp.Last(2);
var channeldown = envelopeChannels.ChannelLow.Last(1);
var prevchanneldown = envelopeChannels.ChannelLow.Last(1);
var longPosition = Positions.Find("Buy", SymbolName, TradeType.Buy);
var shortPosition = Positions.Find("Sell", SymbolName, TradeType.Sell);
{
//Buy Entry
if (prevchannelup > previousPriceMa && channelup < currentPriceMa)
{
if (shortPosition != null)
ClosePosition(shortPosition);
{
if(Positions.Count == 0)
ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits,"Buy", SL, TP);
}
}
if(prevchannelup < previousPriceMa && channelup > currentPriceMa && longPosition != null)
ClosePosition(longPosition);
//Sell Entry
else if (prevchanneldown < previousPriceMa && channeldown > currentPriceMa)
{
if (longPosition != null)
ClosePosition(longPosition);
{
if(Positions.Count == 0)
ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, "Sell",SL,TP);
}
}
if (prevchanneldown > previousPriceMa && channeldown < currentPriceMa && shortPosition != null)
ClosePosition(shortPosition);
}
}
private double VolumeInUnits
{
get { return Symbol.QuantityToVolumeInUnits(Quantity); }
}
}
}