Partial Close of trade not being tallied in Backtesting or Optimization
Created at 28 Nov 2020, 06:33
Partial Close of trade not being tallied in Backtesting or Optimization
28 Nov 2020, 06:33
Hi I am backtesting and optimizing a cbot with a partial close of the position.
In the below example a trade of 1 Lot is opened and half of it is closed using ClosePosition(position, newVol).
The Backtesting results show the Trade Statistics not including the partial closes in it's calculations. While the Net Profit circled in green is correct.
The Optimization results show the Trade Statistics not including the partial closes in it's calculations. While the Net Profit circled in yellow is incorrect, while the ending balance and equity circled in green is correct.
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 SampleRSIcBot : Robot
{
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("Source", Group = "RSI")]
public DataSeries Source { get; set; }
[Parameter("Periods", Group = "RSI", DefaultValue = 14)]
public int Periods { get; set; }
[Parameter("Partial Close offset", DefaultValue = 10, MinValue = 10, Step = 10)]
public int Offset { get; set; }
private RelativeStrengthIndex rsi;
protected override void OnStart()
{
rsi = Indicators.RelativeStrengthIndex(Source, Periods);
}
protected override void OnStop()
{
foreach (var position in Positions)
{
ClosePosition(position);
}
}
protected override void OnTick()
{
if (rsi.Result.LastValue < 30)
{
Close(TradeType.Sell);
Open(TradeType.Buy);
}
else if (rsi.Result.LastValue > 70)
{
Close(TradeType.Buy);
Open(TradeType.Sell);
}
if (rsi.Result.LastValue < 30 + Offset)
{
PartialClose(TradeType.Sell);
}
if (rsi.Result.LastValue > 70 - Offset)
{
PartialClose(TradeType.Buy);
}
}
private void Close(TradeType tradeType)
{
foreach (var position in Positions.FindAll("SampleRSI", SymbolName, tradeType))
ClosePosition(position);
}
private void PartialClose(TradeType tradeType)
{
foreach (var position in Positions.FindAll("SampleRSI", SymbolName, tradeType))
{
double newVol = Symbol.NormalizeVolumeInUnits((position.VolumeInUnits / 2), RoundingMode.Up);
if (position.Quantity == Quantity)
{
ClosePosition(position, newVol);
Print("Partial closing " + newVol + " of " + position + " due to RSI = " + rsi.Result.LastValue);
}
}
}
private void Open(TradeType tradeType)
{
var position = Positions.Find("SampleRSI", SymbolName, tradeType);
var volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
if (position == null)
ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "SampleRSI");
}
}
}
PanagiotisCharalampous
30 Nov 2020, 15:31
Hi prosteel1,
I have forwarded this issue to the product team for investigation.
Best Regards,
Panagiotis
Join us on Telegram
@PanagiotisCharalampous