I’m using TWS API in a C++ implementation. I’m getting a bad memory allocation exception when running a market scanner. The code is designed to connect and then start a couple market scanners.
Driver
const unsigned MAX_ATTEMPTS = 50;
const unsigned SLEEP_TIME = 10;
int main(int argc, char** argv)
{
const char* host = argc > 1 ? argv[1] : "";
//string host = "";
int port = argc > 2 ? atoi(argv[2]) : 0;
if (port <= 0)
port = 4002;
string connectOptions = "";
int clientId = 0;
unsigned attempt = 0;
printf("Start of C++ Socket Client Test %u\n", attempt);
Strategy client;
EClientSocket* socketpointer = client.m_pClient;
for (;;) {
++attempt;
printf("Attempt %u of %u\n", attempt, MAX_ATTEMPTS);
client.connect(host, port, clientId);
while (client.isConnected())
{
client.mainLoop();
}
if (attempt >= MAX_ATTEMPTS) {
printf("Sending Message to Admin");
//add code to message me in case;
break;
}
printf("Sleeping %u seconds before next attempt\n", SLEEP_TIME);
std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME));
}
//…
}
Most of the logic is handled with Strategy:
Strategy::Strategy()
{
m_osSignal = new EReaderOSSignal(2000);
m_pClient = new EClientSocket(this, m_osSignal);
m_sleepDeadline = 0;
m_orderId = 0;
m_pReader = 0;
m_extraAuth = false;
Singleton = this;
TagPrice = "Close";
TagFloat = "Float";
TagVolume = "Volume";
StockInstrument = "STK";
USLocation = "STK.US";
}
bool Strategy::connect(const char *host, int port, int clientId)
{
Logger::logToSystemAndMaster("Connecting to client with Host:" + string(host) +
" and port:" + to_string(port) + " and clientId:" + to_string(clientId) );
printf("Connecting to %s:%d clientId:%d\n", !(host && *host) ? "127.0.0.1" : host, port, clientId);
//! [connect]
bool bRes = m_pClient->eConnect(host, port, clientId, m_extraAuth);
//! [connect]
if (bRes) {
printf("Connected to %s:%d clientId:%d\n", host, port, clientId);
Logger::logToSystemAndMaster("Connected to client with Host:" + string(host) +
" and port:" + to_string(port) + " and clientId:" + to_string(clientId));
//! [ereader]
m_pReader = new EReader(m_pClient, m_osSignal);
m_pReader->start();
//! [ereader]
StartMarketScanners();
}
else
{
cout << "Failed to connect to client with Host:" + string(host) +
" and port:" + to_string(port) + " and clientId:" + to_string(clientId) + "\n";
Logger::logToSystemAndMaster("Failed to connect to client with Host:" + string(host) +
" and port:" + to_string(port) + " and clientId:" + to_string(clientId));
}
return bRes;
}
void Strategy::StartMarketScanners()
{
cout << "scanning\n";
RunGapAndGoScan();
RunHaltScan();
}
void Strategy::RunGapAndGoScan()
{
m_pClient->reqScannerParameters();
TagValueSPtr priceFilter(new TagValue(TagPrice, to_string(MinimumPrice)));// .ToString()));
TagValueSPtr volumeFilter(new TagValue(TagVolume, to_string(MinimumVolume)));
TagValueSPtr marketCapFilter(new TagValue(TagFloat, to_string(MinimumFloat)));
TagValueListSPtr GapAndGoFilters(new TagValueList());
GapAndGoFilters->push_back(priceFilter);
GapAndGoFilters->push_back(volumeFilter);
GapAndGoFilters->push_back(marketCapFilter);
gapAndGoSubscriptionId = GetNextAccountReqId();
//m_pClient->reqScannerSubscription(gapAndGoSubscriptionId, GapAndGo(), TagValueListSPtr(), GapAndGoFilters); // requires TWS v973+
ScannerSubscription scanSub;
scanSub.instrument = "STK";
scanSub.locationCode = "STK.US.MAJOR";
scanSub.scanCode = "HOT_BY_VOLUME";
cout << "running subscription once\n";
m_pClient->reqScannerSubscription(7001, scanSub, TagValueListSPtr(), GapAndGoFilters);
cout << "ran subscription once\n";
}
ScannerSubscription Strategy::GapAndGo()
{
ScannerSubscription scanSub;
scanSub.instrument = "STK";
scanSub.locationCode = "STK.US";// "STK.US.MAJOR";
return scanSub;
}
void Strategy::RunHaltScan()
{
m_pClient->reqScannerParameters();
TagValueListSPtr TagValues(new TagValueList());
HaltScanSubscriptionId = GetNextAccountReqId();
m_pClient->reqScannerSubscription(HaltScanSubscriptionId, HaltSubscription(), TagValueListSPtr(), TagValues);
}
ScannerSubscription Strategy::HaltSubscription()
{
ScannerSubscription haltSubscription;
haltSubscription.instrument = "STK";
haltSubscription.locationCode = "STK.US";
haltSubscription.scanCode = "Halted";
return haltSubscription;
}
Strategy.h :
//…
public:
//EClientSocket * const m_pClient;
EClientSocket* m_pClient;
EReaderOSSignal * m_osSignal;
EReader * m_pReader;
//…
I get a bad_alloc exception upon running reqScannerSubscription(). I'm new to this API and I get a lot of exceptions when calling the m_pClient and m_pReader functions.
This problem was finally solved by changing the build settings. Several build files were not included and the project settings had to be updated to include additional directories. If you find a badAlloc message, consider that your source code may be fine but perhaps some unexpected configuration files such as additional directories need to be included.