using cAlgo.API;
using cAlgo.API.Indicators;
using System;
using System.Collections.Generic;
namespace MovingAverageCrossoverBot
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class MovingAverageCrossoverBot : Robot
{
private TimeFrame higherTimeframe = TimeFrame.Daily; // Define the higher timeframe
private double higherTimeframeThreshold = 0.5;
private double lotSize;
private MovingAverage fastMA;
private MovingAverage slowMA;
private DateTime lastBarTime;
protected override void OnStart()
{
// Configure your symbols and timeframes
// TimeFrame timeframe = TimeFrame.HeikinHour;
// Configure your moving average periods
int fastMAPeriod = 50;
int slowMAPeriod = 200;
// Initialize moving averages
fastMA = Indicators.MovingAverage(Bars.ClosePrices, fastMAPeriod, MovingAverageType.Simple);
slowMA = Indicators.MovingAverage(Bars.ClosePrices, slowMAPeriod, MovingAverageType.Simple);
lastBarTime = Bars.OpenTimes.LastValue;
}
protected override void OnTick()
{
// Check if a new bar has formed
if (Bars.OpenTimes.LastValue > lastBarTime)
{
lastBarTime = Bars.OpenTimes.LastValue;
int index = Bars.ClosePrices.Count - 1; // Index of the last closed bar
bool isHigherTimeframeUptrend = IsHigherTimeframeUptrend();
foreach (var position in Positions)
{
if(!isHigherTimeframeUptrend && Positions.Count > 0)
{
ClosePosition(position);
}
}
if ( fastMA.Result.HasCrossedAbove(slowMA.Result, index)&& isHigherTimeframeUptrend)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", 40, 10, null );
}
}
}
private void ClosePosition(TradeResult position)
{
ClosePosition(position);
}
private bool IsHigherTimeframeUptrend()
{
// Calculate moving averages on the higher timeframe
double[] higherTimeframeFastMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 50);
double[] higherTimeframeSlowMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 200);
int lastIndex = Bars.ClosePrices.Count - 1;
// Check if the slow MA on higher timeframe is below the fast MA, indicating a potential downtrend
return higherTimeframeSlowMASeries[lastIndex] < higherTimeframeFastMASeries[lastIndex];
}
private double[] CalculateSimpleMovingAverage(DataSeries source, TimeFrame timeframe, int period)
{
double[] smaValues = new double[source.Count];
for (int i = 0; i < source.Count; i++)
{
if (i >= period - 1)
{
double sum = 0;
for (int j = i - period + 1; j <= i; j++)
{
sum += source[j];
}
smaValues[i] = sum / period;
}
else
{
smaValues[i] = source[i];
}
}
return smaValues;
}
}
}