Untitled
unknown
plain_text
2 years ago
6.3 kB
12
Indexable
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 desiredTradeVolume = 10000.0; // Desired trade volume in base currency units (e.g., for EURUSD)
private double lotSize;
private MovingAverage fastMA;
private MovingAverage slowMA;
private DateTime lastBarTime;
private RelativeStrengthIndex rsi;
private double riskPercentage = 2.0;
private TradeResult openBuyPosition = null;
private TradeResult openSellPosition = null;
protected override void OnStart()
{
int rsiPeriod = 14; // Period for RSI calculation
rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, rsiPeriod);
// 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;
lotSize = Symbol.NormalizeVolumeInUnits(desiredTradeVolume);
}
protected override void OnTick()
{
if(Positions.Count == 0)
{
openBuyPosition = null;
openSellPosition = null;
}
// 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
if (CrossesOnMultipleTimeframes() && fastMA.Result.HasCrossedAbove(slowMA.Result, index)&& openBuyPosition == null)
{
openBuyPosition = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", 30, 10, null );
}
if (CrossesOnMultipleTimeframesForSell() &&fastMA.Result.HasCrossedBelow(slowMA.Result, index)&& openSellPosition == null)
{
openSellPosition = ExecuteMarketOrder(TradeType.Sell, SymbolName, lotSize, "Sell Order", 30, 10, null);
}
}
}
private void ClosePosition(TradeResult position)
{
ClosePosition(position);
}
private bool CrossesOnMultipleTimeframes()
{
bool crossesOnFast = fastMA.Result.HasCrossedAbove(slowMA.Result, Bars.ClosePrices.Count - 1);
bool crossesOnHigherTimeframe = CrossesOnTimeframe(higherTimeframe);
// Confirm the signal by checking if both timeframes have a crossover
return crossesOnFast && crossesOnHigherTimeframe;
}
private bool CrossesOnTimeframe(TimeFrame timeframe)
{
// Calculate moving averages on the specified timeframe manually
double[] fastMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, 50);
double[] slowMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, 200);
int lastIndex = Bars.ClosePrices.Count - 1;
bool crossesAbove = fastMASeries[lastIndex] > slowMASeries[lastIndex] && fastMASeries[lastIndex - 1] <= slowMASeries[lastIndex - 1];
bool crossesBelow = fastMASeries[lastIndex] < slowMASeries[lastIndex] && fastMASeries[lastIndex - 1] >= slowMASeries[lastIndex - 1];
// Use a threshold to confirm the crossover
return crossesAbove && fastMASeries[lastIndex] > higherTimeframeThreshold ||
crossesBelow && fastMASeries[lastIndex] < 1 - higherTimeframeThreshold;
}
private bool CrossesOnMultipleTimeframesForSell()
{
bool crossesOnFast = fastMA.Result.HasCrossedBelow(slowMA.Result, Bars.ClosePrices.Count - 1);
bool crossesOnHigherTimeframe = CrossesOnTimeframeForSell(higherTimeframe);
// Confirm the signal by checking if both timeframes have a crossover
return crossesOnFast && crossesOnHigherTimeframe;
}
private bool CrossesOnTimeframeForSell(TimeFrame timeframe)
{
// Calculate moving averages on the specified timeframe manually
double[] fastMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, 50);
double[] slowMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, 200);
int lastIndex = Bars.ClosePrices.Count - 1;
bool crossesAbove = fastMASeries[lastIndex] < slowMASeries[lastIndex] && fastMASeries[lastIndex - 1] >= slowMASeries[lastIndex - 1];
bool crossesBelow = fastMASeries[lastIndex] > slowMASeries[lastIndex] && fastMASeries[lastIndex - 1] <= slowMASeries[lastIndex - 1];
// Use a threshold to confirm the crossover
return crossesAbove && fastMASeries[lastIndex] < 1 - higherTimeframeThreshold ||
crossesBelow && fastMASeries[lastIndex] > higherTimeframeThreshold;
}
private double[] CalculateSimpleMovingAverage(DataSeries source, 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;
}
}
}
Editor is loading...