could you help me about my code errors?
could you help me about my code errors?
18 Sep 2024, 15:12
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using System;
using System.Collections.Generic;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class ThreePairsTradeBot : Robot
{
private Symbol gbpjpySymbol, gbpusdSymbol, usdjpySymbol;
private RelativeStrengthIndex gbpjpyRsi, gbpusdRsi, usdjpyRsi;
private BollingerBands gbpjpyBollinger, gbpusdBollinger, usdjpyBollinger;
private List<string> profitLossLog = new List<string>();
private double currentHourMaxProfit = double.MinValue;
private double currentHourMaxLoss = double.MaxValue;
private DateTime currentHourMaxProfitTime, currentHourMaxLossTime;
private DateTime startTime;
private DateTime lastLogTime;
private DateTime endTime;
private const int checkPeriodHours = 1;
private const int totalHours = 24;
private const int lookbackPeriod = 3;
private bool gbpjpyOpened = false;
private bool gbpusdOpened = false;
private bool usdjpyOpened = false;
protected override void OnStart()
{
gbpjpySymbol = Symbols.GetSymbol("GBPJPY");
gbpusdSymbol = Symbols.GetSymbol("GBPUSD");
usdjpySymbol = Symbols.GetSymbol("USDJPY");
gbpjpyRsi = Indicators.RelativeStrengthIndex(MarketData.GetBars(TimeFrame.Hour, "GBPJPY").ClosePrices, 14);
gbpusdRsi = Indicators.RelativeStrengthIndex(MarketData.GetBars(TimeFrame.Hour, "GBPUSD").ClosePrices, 14);
usdjpyRsi = Indicators.RelativeStrengthIndex(MarketData.GetBars(TimeFrame.Hour, "USDJPY").ClosePrices, 14);
gbpjpyBollinger = Indicators.BollingerBands(MarketData.GetBars(TimeFrame.Hour, "GBPJPY").ClosePrices, 20, 2, MovingAverageType.Simple);
gbpusdBollinger = Indicators.BollingerBands(MarketData.GetBars(TimeFrame.Hour, "GBPUSD").ClosePrices, 20, 2, MovingAverageType.Simple);
usdjpyBollinger = Indicators.BollingerBands(MarketData.GetBars(TimeFrame.Hour, "USDJPY").ClosePrices, 20, 2, MovingAverageType.Simple);
startTime = Server.Time;
lastLogTime = startTime;
endTime = startTime.AddHours(totalHours);
}
protected override void OnTick()
{
int gbpjpySignal = GetRsiBollingerSignal(gbpjpyRsi, gbpjpyBollinger, gbpjpySymbol);
int gbpusdSignal = GetRsiBollingerSignal(gbpusdRsi, gbpusdBollinger, gbpusdSymbol);
int usdjpySignal = GetRsiBollingerSignal(usdjpyRsi, usdjpyBollinger, usdjpySymbol);
HandleOrder(gbpjpySignal, gbpjpySymbol, ref gbpjpyOpened);
HandleOrder(gbpusdSignal, gbpusdSymbol, ref gbpusdOpened);
HandleOrder(usdjpySignal, usdjpySymbol, ref usdjpyOpened);
double currentProfit = 0;
foreach (var position in Positions)
{
currentProfit += position.GrossProfit;
}
if (currentProfit > currentHourMaxProfit)
{
currentHourMaxProfit = currentProfit;
currentHourMaxProfitTime = Server.Time;
}
if (currentProfit < currentHourMaxLoss)
{
currentHourMaxLoss = currentProfit;
currentHourMaxLossTime = Server.Time;
}
if ((Server.Time - lastLogTime).TotalHours >= checkPeriodHours)
{
string logEntry = $"Hour {((Server.Time - startTime).TotalHours):F0}: Max Profit: {currentHourMaxProfit}, Time: {currentHourMaxProfitTime}, Max Loss: {currentHourMaxLoss}, Time: {currentHourMaxLossTime}";
profitLossLog.Add(logEntry);
Print(logEntry);
currentHourMaxProfit = double.MinValue;
currentHourMaxLoss = double.MaxValue;
lastLogTime = Server.Time;
}
if (Server.Time >= endTime)
{
Print("24-hour Max Profit and Max Loss:");
foreach (var entry in profitLossLog)
{
Print(entry);
}
Stop();
}
}
private int GetRsiBollingerSignal(RelativeStrengthIndex rsi, BollingerBands bollingerBands, Symbol symbol)
{
double rsiValue = rsi.Result.LastValue;
var bars = MarketData.GetBars(TimeFrame.Hour, symbol.Name);
if (bars.Count < 2)
return 0;
var previousBar = bars[bars.Count - 2];
double previousBarLow = previousBar.Low;
double previousBarHigh = previousBar.High;
double bollingerTop = bollingerBands.Top.LastValue;
double bollingerBottom = bollingerBands.Bottom.LastValue;
double previousVolume = bars[bars.Count - 2].Volume;
bool isDoubleTop = DetectDoubleTop(symbol);
bool isDoubleBottom = DetectDoubleBottom(symbol);
if (rsiValue > 70)
{
if (previousBarLow > bollingerTop || isDoubleTop)
{
Print($"Overbought condition met: Previous bar low {previousBarLow}, Bollinger Bands top {bollingerTop}, RSI {rsiValue}");
if (MarketData.GetBars(TimeFrame.Hour, symbol.Name)[bars.Count - 2].Volume <= previousVolume / 2)
{
Print("Volume condition met for overbought: Opening short positions");
return -1;
}
}
else
{
return rsiValue > 50 ? 1 : -1;
}
}
else if (rsiValue < 20)
{
if (previousBarHigh < bollingerBottom || isDoubleBottom)
{
Print($"Oversold condition met: Previous bar high {previousBarHigh}, Bollinger Bands bottom {bollingerBottom}, RSI {rsiValue}");
if (MarketData.GetBars(TimeFrame.Hour, symbol.Name)[bars.Count - 2].Volume <= previousVolume / 2)
{
Print("Volume condition met for oversold: Opening long positions");
return 1;
}
}
else
{
return rsiValue > 50 ? 1 : -1;
}
}
else
{
return rsiValue > 50 ? 1 : -1;
}
return 0;
}
private bool DetectDoubleTop(Symbol symbol)
{
var bars = MarketData.GetBars(TimeFrame.Hour, symbol.Name);
if (bars.Count < lookbackPeriod * 2)
return false;
double peak1 = bars[bars.Count - lookbackPeriod - 1].High;
double peak2 = bars[bars.Count - 1].High;
for (int i = 1; i < lookbackPeriod; i++)
{
if (Math.Abs(bars[bars.Count - i].High - peak1) < 0.01 && Math.Abs(bars[bars.Count - i].High - peak2) < 0.01)
{
return true;
}
}
return false;
}
private bool DetectDoubleBottom(Symbol symbol)
{
var bars = MarketData.GetBars(TimeFrame.Hour, symbol.Name);
if (bars.Count < lookbackPeriod * 2)
return false;
double trough1 = bars[bars.Count - lookbackPeriod - 1].Low;
double trough2 = bars[bars.Count - 1].Low;
for (int i = 1; i < lookbackPeriod; i++)
{
if (Math.Abs(bars[bars.Count - i].Low - trough1) < 0.01 && Math.Abs(bars[bars.Count - i].Low - trough2) < 0.01)
{
return true;
}
}
return false;
}
private void HandleOrder(int signal, Symbol symbol, ref bool opened)
{
if (signal != 0)
{
if (opened)
return;
double volume = (signal > 0) ? 0.02 : 0.01;
double stopLoss = 50;
double takeProfit = 50;
if (signal > 0)
{
Print($"Opening long position: {symbol.Name}");
ExecuteMarketOrder(TradeType.Buy, symbol.Name, volume, "RSI Strategy", stopLoss, takeProfit);
}
else
{
Print($"Opening short position: {symbol.Name}");
ExecuteMarketOrder(TradeType.Sell, symbol.Name, volume, "RSI Strategy", stopLoss, takeProfit);
}
opened = true;
}
else if (opened)
{
foreach (var position in Positions.FindAll("RSI Strategy", symbol.Name))
{
Print($"Closing position: {symbol.Name}");
ClosePosition(position);
}
opened = false;
}
}
protected override void OnStop()
{
// Final logging
Print("Final 24-hour Max Profit and Max Loss:");
foreach (var entry in profitLossLog)
{
Print(entry);
}
}
}
}
PanagiotisCharalampous
19 Sep 2024, 05:48
Hi there,
The problem is that your are calling a property that does not exist. Bars do not have a Volume property.
Best regards,
Panagiotis
@PanagiotisCharalampous