Profitable cBot apart from one rogue parameter!!
15 Sep 2015, 16:54
Hi All,
I've been getting some good results with the robot below, however I have a parameter that doesn't seem to act as it should...
I'm counting up the total pips of a position with this:
int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);
and then using totalPips to delay when a martingale strategy is called with this
if ( totalPips <= MartingaleTrigger * Symbol.PipSize)
The problem is that this MartingaleTrigger value isn't doing anything related to the Symbol.Pipsize. In fact, back test results remain the same regardless of the MartingaleTrigger value. However, if I remove the parameter all together the backtest results do change!?!?
Any help or advice would be greatly appreciated...
(Backtest with EURGBP, m1)
using System;
using System.Linq;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Requests;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BolliBot : Robot
{
[Parameter("Source")]
public DataSeries SourceSeries { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 1000, MinValue = 1)]
private int StopLossInPips { get; set; }
[Parameter("Take Profit (pips)", DefaultValue = 1000, MinValue = 1)]
private int TakeProfitInPips { get; set; }
[Parameter("Volume", DefaultValue = 1000, MinValue = 1000)]
public int Volume { get; set; }
[Parameter("RSI High Trigger", DefaultValue = 60)]
public int highRSI { get; set; }
[Parameter("RSI Low Trigger", DefaultValue = 40)]
public int lowRSI { get; set; }
[Parameter("Bollinger Bands Deviations", DefaultValue = 2.5)]
public double Deviations { get; set; }
[Parameter("Periods", DefaultValue = 20)]
public int Periods { get; set; }
[Parameter("Fast MA", DefaultValue = 1)]
public int FastPeriods { get; set; }
[Parameter("MA Type")]
public MovingAverageType MAType { get; set; }
[Parameter("Mid MA", DefaultValue = 200)]
public int MidPeriods { get; set; }
[Parameter("Slow MA", DefaultValue = 1000)]
public int SlowPeriods { get; set; }
[Parameter("Martingale Trigger", DefaultValue = -5)]
public int MartingaleTrigger { get; set; }
[Parameter("Overall Profit Take Profit", DefaultValue = 10)]
public int OverAllProfitTP { get; set; }
[Parameter("Overall Loss Stop Loss", DefaultValue = -10000)]
public int OverAllLossSL { get; set; }
[Parameter("MartinGale Volume Multiplied By", DefaultValue = 32)]
public int martingaleMultiplier { get; set; }
private RelativeStrengthIndex rsi;
private MovingAverage fastMa;
private MovingAverage midMa;
private MovingAverage slowMa;
Dictionary<int, int> dic = new Dictionary<int, int>();
BollingerBands bollingerBands;
string label = "BolliBot";
protected override void OnStart()
{
bollingerBands = Indicators.BollingerBands(SourceSeries, Periods, Deviations, MAType);
rsi = Indicators.RelativeStrengthIndex(SourceSeries, Periods);
fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
midMa = Indicators.MovingAverage(SourceSeries, MidPeriods, MAType);
slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
}
private void ExecuteOrder(int volume, TradeType tradeType)
{
ExecuteMarketOrder(tradeType, Symbol, volume, label, StopLossInPips, TakeProfitInPips);
}
protected override void OnBar()
{
var top = bollingerBands.Top.Last(1);
var bottom = bollingerBands.Bottom.Last(1);
var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);
var FastMa = fastMa.Result.Last(0);
var MidMa = midMa.Result.Last(0);
var SlowMa = slowMa.Result.Last(0);
var high = rsi.Result.Last(0);
var low = rsi.Result.Last(0);
var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);
if (Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa)
{
ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
Print("Short Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount);
}
if (Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa)
{
ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
Print("Long Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount);
}
}
protected override void OnTick()
{
var top = bollingerBands.Top.Last(1);
var bottom = bollingerBands.Bottom.Last(1);
var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);
var FastMa = fastMa.Result.Last(0);
var MidMa = midMa.Result.Last(0);
var SlowMa = slowMa.Result.Last(0);
var high = rsi.Result.Last(0);
var low = rsi.Result.Last(0);
var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);
var symbolSearch = Positions.FindAll(label, Symbol);
int posCount = Positions.Count;
foreach (Position position in symbolSearch)
for (int y = posCount - 1; y >= 0; y--)
{
int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);
int test = 0;
if (!dic.TryGetValue(Positions[y].Id, out test))
{
dic[Positions[y].Id] = 0;
}
if (Positions[y].TradeType == TradeType.Sell && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa)
{
dic[Positions[y].Id] = 1;
ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType);
Print("Martingale SHORT!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount);
}
if (Positions[y].TradeType == TradeType.Buy && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa)
{
dic[Positions[y].Id] = 1;
ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType);
Print("Martingale LONG!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount);
}
}
double overallProfit = 0;
foreach (Position position in symbolSearch)
{
overallProfit += position.GrossProfit;
}
if (overallProfit >= OverAllProfitTP)
{
Print("OVERALL Profit TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count);
foreach (Position position in symbolSearch)
{
ClosePosition(position);
}
}
if (overallProfit <= OverAllLossSL)
{
Print("OVERALL Loss TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count);
foreach (Position position in symbolSearch)
{
ClosePosition(position);
}
}
}
}
}

moneybiz
15 Sep 2015, 22:45
RE:
9718853 said:
Positions[y].Pips is already gibing you the profit or loss in pips.
Subtracting Positions[y].EntryPrice from pips is not logical. One is a value like 10 (pips) and the other is a value like 1.12345.
int totalPips = Positions[y].Pips is enough.
What does the MartingaleTrigger represent, pips or price? If pips then totalPips <= MartingaleTrigger is enough.
You use multiplication with Symbol.PipSize only when you want to add/subtract some pips from a price value.
Say you want to set a take profit price position as 10 pips from the entry price.
var takeProfit = Positions[y].EntryPrice + (TakeProfitPips * Symbol.PipSize);
var takeProfit = 1.12345 + (10 * 0.0001) = 1.12445
@moneybiz