NullReferenceException thrown when injecting dependency in class constructor with Symbol as parameter
NullReferenceException thrown when injecting dependency in class constructor with Symbol as parameter
05 Aug 2020, 13:24
Hello,
I'm trying to work on a cBot that treats multiple currency pairs and tries to extract different data (Bid, Ask, DOM) among other things for each currency, I've implemented a CurrencyPair class whose constructor takes a Symbol interface as a parameter and assigns it to a class field of type Symbol in order to use the properties bid, ask, name.. The cBot builds successfully but as soon as I run it, it throws a NullReferenceException and the problem seems to originate from the first invocation of a property of the Symbol interface from within the CurrencyPair class. Here is a part of the code:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
public class CurrencyPair : Robot
{
public Symbol _symbol;
public Dictionary<double, double> BUY = new Dictionary<double, double>();
public Dictionary<double, double> SELL = new Dictionary<double, double>();
(...)
public CurrencyPair(Symbol sym)
{
_symbol = sym;
}
public void StartCurrency()
{
_marketDepth = MarketData.GetMarketDepth(_symbol.Name); //problem here
_marketDepth.Updated += MarketDepthUpdated;
}
(...)
public void MarketDepthUpdated()
{
Print("Started Event MarketDepthUpdated");
_marketDepth = MarketData.GetMarketDepth(_symbol.Name);
curBSpot = _symbol.Bid;
curASpot = _symbol.Ask;
SELL.Clear();
BUY.Clear();
foreach (var entry in _marketDepth.AskEntries)
SELL.Add(entry.Price, entry.VolumeInUnits);
foreach (var entry in _marketDepth.BidEntries)
BUY.Add(entry.Price, entry.VolumeInUnits);
prevBSpot = _symbol.Bid;
prevASpot = _symbol.Ask;
Print("Exited Event MarketDepthUpdated");
}
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Playing_DoM_Sequential : Robot
{
protected override void OnStart()
{
CurrencyPair EURUSD = new CurrencyPair(Symbols.GetSymbol("EURUSD"));
EURUSD.StartCurrency(); //problem here
CurrencyPair GBPUSD = new CurrencyPair(Symbols.GetSymbol("GBPUSD"));
CurrencyPair EURJPY = new CurrencyPair(Symbols.GetSymbol("EURJPY"));
}
}
}
What is it that I am doing wrong?
Replies
galaaoui.salma
05 Aug 2020, 14:46
RE:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
public class CurrencyPair : Robot
{
public Symbol _symbol;
public Dictionary<double, double> BUY = new Dictionary<double, double>();
public Dictionary<double, double> SELL = new Dictionary<double, double>();
public static Dictionary<KeyValuePair<DateTime, double>, double> BOUGHT = new Dictionary<KeyValuePair<DateTime, double>, double>();
public static Dictionary<KeyValuePair<DateTime, double>, double> SOLD = new Dictionary<KeyValuePair<DateTime, double>, double>();
public static double curASpot = 0;
public static double curBSpot = 0;
public double prevASpot = 0;
public double prevBSpot = 0;
public static double score;
public static double totAScore;
public static double totBScore;
public MarketDepth _marketDepth;
public CurrencyPair(Symbol sym)
{
this._symbol = sym;
}
public void StartCurrency()
{
_marketDepth = MarketData.GetMarketDepth(_symbol.Name);
_marketDepth.Updated += MarketDepthUpdated;
}
public void MarketDepthUpdated()
{
Print("Started Event MarketDepthUpdated");
_marketDepth = MarketData.GetMarketDepth(_symbol.Name);
curBSpot = _symbol.Bid;
curASpot = _symbol.Ask;
Offset();
SELL.Clear();
BUY.Clear();
foreach (var entry in _marketDepth.AskEntries)
SELL.Add(entry.Price, entry.VolumeInUnits);
foreach (var entry in _marketDepth.BidEntries)
BUY.Add(entry.Price, entry.VolumeInUnits);
prevBSpot = _symbol.Bid;
prevASpot = _symbol.Ask;
Print("Exited Event MarketDepthUpdated");
}
public void Offset()
{
DateTime now;
Print("Offset Started");
if ((prevBSpot == 0) || (prevBSpot == 0) || (curBSpot == 0) || (curASpot == 0))
return;
Print(score);
foreach (var ask in SELL.Reverse())
if (curASpot >= ask.Key)
{
now = DateTime.UtcNow;
BOUGHT.Add(new KeyValuePair<DateTime, double>(now, ask.Key), ask.Value);
Print("{0} : BOUGHT : {1}, {2}, {3}", _symbol.Name, now, ask.Key, ask.Value);
}
else
break;
foreach (var bid in BUY)
if (curBSpot <= bid.Key)
{
now = DateTime.UtcNow;
SOLD.Add(new KeyValuePair<DateTime, double>(now, bid.Key), bid.Value);
Print("{0} : BOUGHT : {1}, {2}, {3}", _symbol.Name, now, bid.Key, bid.Value);
}
else
break;
}
}
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Playing_DoM_Sequential : Robot
{
protected override void OnStart()
{
Print("1");
CurrencyPair EURUSD = new CurrencyPair(Symbols.GetSymbol("EURUSD"));
EURUSD.StartCurrency();
Print("2");
CurrencyPair GBPUSD = new CurrencyPair(Symbols.GetSymbol("GBPUSD"));
Print("3");
CurrencyPair EURJPY = new CurrencyPair(Symbols.GetSymbol("EURJPY"));
Print("4");
}
}
}
PanagiotisCharalampous said:
Hi galaaoui.salma,
Can you please provide the compete cBot code so that we can reproduce this behavior?
Best Regards,
Panagiotis
Hi Panagiotis, here you go, the code prints "1" and crashes with NullReferenceException
@galaaoui.salma
PanagiotisCharalampous
06 Aug 2020, 08:12
Hi galaaoui.salma,
Your problem lies here
You cannot use MarketData in a robot object that is not attached on a chart. Try passing this object as a parameter to the class.
Best Regards,
Panagiotis
@PanagiotisCharalampous
galaaoui.salma
06 Aug 2020, 11:44
( Updated at: 21 Dec 2023, 09:22 )
RE:
PanagiotisCharalampous said:
Hi galaaoui.salma,
Your problem lies here
You cannot use MarketData in a robot object that is not attached on a chart. Try passing this object as a parameter to the class.
Best Regards,
Panagiotis
Hi Panagiotis,
The problem isn't only the invocation of GetMarketDepth(Symbol.Name); inside the CurrencyPair projects, passing it as a parameter to the constructor does not solve the issue because the problem is also caused by the subscription to the Updated even inside the class.
Kind Regards,
Salma Galaaoui.
@galaaoui.salma
PanagiotisCharalampous
06 Aug 2020, 11:54
Hi galaaoui.salma,
The root of the problem is the same. You cannot use CurrencyPair.MarketData since it is not initialized anywhere. This property is only initialized when the cBot is attached to a chart.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
05 Aug 2020, 14:13
Hi galaaoui.salma,
Can you please provide the compete cBot code so that we can reproduce this behavior?
Best Regards,
Panagiotis
Join us on Telegram
@PanagiotisCharalampous