Untitled
unknown
plain_text
a year ago
5.2 kB
2
Indexable
Never
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.Weekly; // Define the higher timeframe private double higherTimeframeThreshold = 0.5; private double lotSize; private MovingAverage fastMA; private MovingAverage slowMA; private DateTime lastBarTime; private Color regularStopLossColor = Color.Red; private Color trailingStopLossColor = Color.Blue; private Color currentStopLossColor; private double trailingStopDistanceInPips = 1000; // Adjust this value according to your preference private double minProfitForTrailing = 1000; // Minimum profit in pips before trailing stop becomes active 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 OnBar() { // 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) { double unrealizedProfitInPips = position.Pips; if (unrealizedProfitInPips >= minProfitForTrailing) { string lineName = $"StopLossLine_{position.Id}"; double trailingStopPrice = Symbol.Bid - trailingStopDistanceInPips * Symbol.PipSize; ModifyPosition(position, trailingStopPrice, position.TakeProfit); currentStopLossColor = trailingStopLossColor; Chart.RemoveObject(lineName); // Draw Stop Loss Line if it exists if (position.StopLoss.HasValue) { double stopLossPrice = position.StopLoss.Value; Chart.DrawHorizontalLine(lineName, stopLossPrice, currentStopLossColor, 1, LineStyle.Solid); } } if(!isHigherTimeframeUptrend && Positions.Count > 0) { ClosePosition(position); Chart.RemoveAllObjects(); } } if ( fastMA.Result.HasCrossedAbove(slowMA.Result, index)&& isHigherTimeframeUptrend) { ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", 2000, 2000, 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; } } }