using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)] public class newCBot : Robot { [Parameter(" Volume Percent", DefaultValue = 1, MinValue = 0)] public double VolumePercent { get; set; } [Parameter("Stop Loss", DefaultValue = 100)] public int StopLoss { get; set; } [Parameter("Take Profit", DefaultValue = 100)] public int TakeProfit { get; set; } [Parameter()] public DataSeries Source { get; set; } [Parameter("RSI", DefaultValue = 10)] public int PeriodRSI { get; set; } [Parameter("MA1", DefaultValue = 10)] public int Period1 { get; set; } [Parameter("MA2", DefaultValue = 14)] public int Period2 { get; set; } [Parameter("MA3", DefaultValue = 18)] public int Period3 { get; set; } [Parameter("MA4", DefaultValue = 24)] public int Period4 { get; set; } [Parameter("MA5", DefaultValue = 28)] public int Period5 { get; set; } [Parameter(DefaultValue = 70)] public int MaxLevel { get; set; } [Parameter(DefaultValue = 30)] public int MinLevel { get; set; } [Parameter(DefaultValue = 1)] public int NumberOfLots { get; set; } private MovingAverage _ma1; private MovingAverage _ma2; private MovingAverage _ma3; private MovingAverage _ma4; private MovingAverage _ma5; private RelativeStrengthIndex _rs1; private double FirstPrice = 0; private double Denominator = 0; private double MinPrice = 0; protected override void OnStart() { //System.Diagnostics.Debugger.Launch(); _ma1 = Indicators.MovingAverage(Source, Period1, MovingAverageType.Simple); _ma2 = Indicators.MovingAverage(Source, Period2, MovingAverageType.Simple); _ma3 = Indicators.MovingAverage(Source, Period3, MovingAverageType.Simple); _ma4 = Indicators.MovingAverage(Source, Period4, MovingAverageType.Simple); _ma5 = Indicators.MovingAverage(Source, Period5, MovingAverageType.Simple); _rs1 = Indicators.RelativeStrengthIndex(Source, PeriodRSI); } private int count = 0; private double Normalize(double price) { price = ((price - MinPrice) / (Denominator)) * 100; return (Double.IsNaN(price)) ? 0.5 : price; } protected override void OnBar() { FirstPrice = Bars.LastBar.Close; List ma1List = _ma1.Result.Where(number => !double.IsNaN(number)).ToList(); List ma2List = _ma2.Result.Where(number => !double.IsNaN(number)).ToList(); List ma3List = _ma3.Result.Where(number => !double.IsNaN(number)).ToList(); List ma4List = _ma4.Result.Where(number => !double.IsNaN(number)).ToList(); List ma5List = _ma5.Result.Where(number => !double.IsNaN(number)).ToList(); MinPrice = ma1List.Min(); Denominator = ma1List.Max() - MinPrice; int startIndex = Math.Max(0, ma1List.Count - 30); List last10Ma1 = ma1List.GetRange(startIndex, ma1List.Count - startIndex); List last10Ma2 = ma2List.GetRange(startIndex, ma2List.Count - startIndex); List last10Ma3 = ma3List.GetRange(startIndex, ma3List.Count - startIndex); List last10Ma4 = ma4List.GetRange(startIndex, ma4List.Count - startIndex); List last10Ma5 = ma5List.GetRange(startIndex, ma5List.Count - startIndex); double norm1 = Normalize(ma1List.Last()); double norm2 = Normalize(ma2List.Last()); double norm3 = Normalize(ma3List.Last()); double norm4 = Normalize(ma4List.Last()); double norm5 = Normalize(ma5List.Last()); double rsi = _rs1.Result.LastValue; double perc = 0.1; if (last10Ma1.Count >= 1 && last10Ma2.Count >= 1 && last10Ma3.Count >= 1 && last10Ma4.Count >= 1 && last10Ma5.Count >= 1) { bool pricesLessThanThreshold = true; if (Math.Abs(1 - last10Ma1[0] / last10Ma2[0]) >= perc) { pricesLessThanThreshold = false; } if (Math.Abs(1 - last10Ma1[0] / last10Ma3[0]) >= perc) { pricesLessThanThreshold = false; } if (Math.Abs(1 - last10Ma1[0] / last10Ma4[0]) >= perc) { pricesLessThanThreshold = false; } if (Math.Abs(1 - last10Ma1[0] / last10Ma5[0]) >= perc) { pricesLessThanThreshold = false; } if (pricesLessThanThreshold) { if ((norm1 > MaxLevel && norm5 > MaxLevel)) { if (Positions.Count == 0) { var toPass = Bars.ToList().GetRange(startIndex, ma1List.Count - startIndex).Select(x => x.Close).ToList(); var stddev = CalculateStandardDeviation(toPass); double buy = 0; for (int i = 1; i < toPass.Count; i++) { var volume = Bars.TickVolumes[0]; buy += volume * NormCdf((toPass[i] - toPass[i - 1]) / stddev); } double totVol = Bars.TickVolumes[0] * toPass.Count; double sellVol = totVol - buy; if (Math.Abs(0.5 - sellVol / totVol) < 0.1) { var x = ExecuteMarketOrder(TradeType.Sell, SymbolName, NumberOfLots * Symbol.VolumeInUnitsMin, "-", StopLoss, TakeProfit); } } } else if ((norm1 < MinLevel && norm5 < MaxLevel)) { if (Positions.Count == 0) { var toPass = Bars.ToList().GetRange(startIndex, ma1List.Count - startIndex).Select(x => x.Close).ToList(); var stddev = CalculateStandardDeviation(toPass); double buy = 0; for (int i = 1; i < toPass.Count; i++) { var volume = Bars.TickVolumes[0]; buy += volume * NormCdf((toPass[i] - toPass[i - 1]) / stddev); } double totVol = Bars.TickVolumes[0] * toPass.Count; double sellVol = totVol - buy; if (Math.Abs(0.5 - sellVol / totVol) < 0.1) { var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, NumberOfLots * Symbol.VolumeInUnitsMin, "-", StopLoss, TakeProfit); } } } } } } static double NormCdf(double x) { double k = 1.0 / (1.0 + 0.2316419 * x); double kSum = k * (0.319381530 + k * (-0.356563782 + k * (1.781477937 + k * (-1.821255978 + 1.330274429 * k)))); if (x >= 0.0) { return 1.0 - (1.0 / Math.Sqrt(2 * Math.PI)) * Math.Exp(-0.5 * x * x) * kSum; } else { return 1.0 - NormCdf(-x); } } static double CalculateStandardDeviation(List values) { double mean = CalculateMean(values); double sumOfSquaredDifferences = 0.0; foreach (double value in values) { double difference = value - mean; sumOfSquaredDifferences += difference * difference; } double variance = sumOfSquaredDifferences / values.Count; double standardDeviation = Math.Sqrt(variance); return standardDeviation; } static double CalculateMean(List values) { double sum = 0.0; foreach (double value in values) { sum += value; } double mean = sum / values.Count; return mean; } } }