Skip to content

Commit 4f50d61

Browse files
committed
release v1.3.2
1 parent d78a874 commit 4f50d61

File tree

11 files changed

+104
-87
lines changed

11 files changed

+104
-87
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.vscode
33
Release
44
Debug
5+
*.aps

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
v1.3.2
2+
- Set the market data feed for the free market data plan to IEX. This ensures accurate and reliable data for users on the free plan.
3+
- Fixed an issue where the market was incorrectly marked as closed.
4+
- Corrected the application of some log types that were not being applied correctly.
5+
- Fixed an issue where failed WebSocket login might cause crash.
6+
17
v1.3.1
28
- Rollback the sandbox WebSocket endpoint for Paper account. The endpoint doesn't work.
39

alpaca_zorro_plugin/AlpacaZorroPlugin.cpp

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -125,17 +125,9 @@ namespace alpaca
125125
//attempt login
126126
if (wsClient)
127127
{
128-
//if (isPaperTrading)
129-
//{
130-
// if (!wsClient->login(User, Pwd, s_config.alpacaPaidPlan ? ALPACA_PAPER_PRO_DATA_WS_URL : ALPACA_PAPER_BASIC_DATA_WS_URL)) {
131-
// BrokerError("Unable to open Alpaca websocket. Prices will be pulled from REST API.");
132-
// }
133-
//}
134-
//else
135-
{
136-
if (!wsClient->login(User, Pwd, s_config.alpacaPaidPlan ? ALPACA_PRO_DATA_WS_URL : ALPACA_BASIC_DATA_WS_URL)) {
137-
BrokerError("Unable to open Alpaca websocket. Prices will be pulled from REST API.");
138-
}
128+
if (!wsClient->login(User, Pwd, s_config.alpacaPaidPlan ? ALPACA_PRO_DATA_WS_URL : ALPACA_BASIC_DATA_WS_URL)) {
129+
BrokerError("Unable to open Alpaca websocket. Prices will be pulled from REST API.");
130+
wsClient.reset();
139131
}
140132
}
141133

@@ -179,7 +171,6 @@ namespace alpaca
179171
}
180172

181173
auto& clock = response.content();
182-
183174
*pTimeGMT = convertTime(clock.timestamp);
184175
return clock.is_open ? 2 : 1;
185176
}
@@ -434,14 +425,14 @@ namespace alpaca
434425
auto populateTicks = [&barsDownloaded, nTickMinutes, &end, &ticks, nTicks](std::vector<Bar>& bars) {
435426
for (int i = bars.size() - 1; i >= 0 && barsDownloaded < nTicks; --i) {
436427
auto& bar = bars[i];
437-
// change time to bar close time
438-
__time32_t barCloseTime = bar.time + nTickMinutes * 60;
439-
if (barCloseTime > end) {
440-
// end time cannot exceeds tEnd
441-
continue;
442-
}
428+
//// change time to bar close time
429+
//__time32_t barCloseTime = bar.time + nTickMinutes * 60;
430+
//if (barCloseTime > end) {
431+
// // end time cannot exceeds tEnd
432+
// continue;
433+
//}
443434
auto& tick = ticks[barsDownloaded++];
444-
tick.time = convertTime(barCloseTime);
435+
tick.time = convertTime(static_cast<__time32_t>(bar.time));
445436
tick.fOpen = static_cast<float>(bar.open_price);
446437
tick.fHigh = static_cast<float>(bar.high_price);
447438
tick.fLow = static_cast<float>(bar.low_price);
@@ -450,31 +441,6 @@ namespace alpaca
450441
}
451442
};
452443

453-
if (!s_config.alpacaPaidPlan) {
454-
LOG_DEBUG("BrokerHistory %s start: %d end: %d nTickMinutes: %d nTicks: %d\n", Asset, start, end, nTickMinutes, nTicks);
455-
auto now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
456-
if ((now - end) <= 900) {
457-
//if (s_config.fillDelayedDataWithPolygon && polygon) {
458-
// // Fill missed delay data from Polygon
459-
// s_logger->logInfo("Fill 15 minutes delay data with polygon\n", Asset, start, end, nTickMinutes, std::max<int>((30 / nTickMinutes), 1));
460-
// auto response = polygon->getBars(Asset, start, end, nTickMinutes, nTicks);
461-
// if (response) {
462-
// populateTicks(response.content());
463-
// if (!response.content().empty()) {
464-
// end = response.content()[0].time - 30;
465-
// }
466-
// else {
467-
// end = static_cast<__time32_t>(now) - 900;
468-
// }
469-
// }
470-
//}
471-
//else {
472-
end = static_cast<__time32_t>(now) - 900;
473-
LOG_INFO("Alpaca Basic Plan. Adjust end to %d\n", end);
474-
//}
475-
}
476-
}
477-
478444
while(true) {
479445
LOG_DEBUG("BrokerHistory %s start: %s(%d) end: %s(%d) nTickMinutes: %d nTicks: %d\n", Asset, timeToString(start).c_str(), start, timeToString(end).c_str(), end, nTickMinutes, nTicks);
480446

@@ -900,12 +866,11 @@ namespace alpaca
900866
return 0; // historical data in UTC time
901867

902868
case GET_MAXTICKS:
903-
return 10000;
869+
return 9999;
904870

905871
case GET_MAXREQUESTS:
906-
// Alpaca rate limit is 200 requests per minutes.
907-
// The rate is throttled by throtter
908-
return 0;
872+
// Alpaca rate limit is 200 requests per minutes for Free plan.
873+
return s_config.alpacaPaidPlan ? 0 : 200;
909874

910875
case GET_LOCK:
911876
return 1;

alpaca_zorro_plugin/alpaca/client.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ namespace alpaca {
6666
}
6767

6868
Response<Clock> Client::getClock() const {
69-
return request<Clock, Client>(baseUrl_ + "/v2/clock", headers_.c_str(), nullptr);
69+
auto rsp = request<Clock, Client>(baseUrl_ + "/v2/clock", headers_.c_str(), nullptr, LogLevel::L_TRACE, LogType::LT_DEFAULT);
70+
if (rsp)
71+
{
72+
is_open_ = rsp.content().is_open;
73+
}
74+
return rsp;
7075
}
7176

7277
Response<std::vector<Asset>> Client::getAssets(bool active_only) const {
@@ -256,9 +261,9 @@ namespace alpaca {
256261
writer.EndObject();
257262
auto data = s.GetString();
258263

259-
LOG_DEBUG("--> POST %s/v2/orders\n", baseUrl_.c_str());
264+
LOG_DEBUG_EXT(LogType::LT_ORDER, "--> POST %s/v2/orders\n", baseUrl_.c_str());
260265
if (data) {
261-
LOG_TRACE("Data:\n%s\n", data);
266+
LOG_TRACE_EXT(LogType::LT_ORDER, "Data:\n%s\n", data);
262267
}
263268
response = request<Order, Client>(baseUrl_ + "/v2/orders", headers_.c_str(), data, LogLevel::L_DEBUG, LT_ORDER);
264269
if (!response && response.what() == "client_order_id must be unique") {

alpaca_zorro_plugin/alpaca/client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ namespace alpaca {
8585
const std::string baseUrl_;
8686
const std::string apiKey_;
8787
const std::string headers_;
88-
mutable bool is_open_ = false;
88+
mutable bool is_open_ = true;
8989
const bool isLiveMode_;
9090
};
9191

alpaca_zorro_plugin/alpaca_zorro_plugin.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ END
5151
//
5252

5353
VS_VERSION_INFO VERSIONINFO
54-
FILEVERSION 1,3,1,0
55-
PRODUCTVERSION 1,3,1,0
54+
FILEVERSION 1,3,2,0
55+
PRODUCTVERSION 1,3,2,0
5656
FILEFLAGSMASK 0x3fL
5757
#ifdef _DEBUG
5858
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
6868
BLOCK "040904b0"
6969
BEGIN
7070
VALUE "FileDescription", "Alpaca Zorro Plugin"
71-
VALUE "FileVersion", "1.3.1.0"
71+
VALUE "FileVersion", "1.3.2.0"
7272
VALUE "InternalName", "alpaca_z.dll"
7373
VALUE "LegalCopyright", "Copyright (C) 2021"
7474
VALUE "OriginalFilename", "alpaca_z.dll"
7575
VALUE "ProductName", "AlpacaZorroPlugin"
76-
VALUE "ProductVersion", "1.3.1.0"
76+
VALUE "ProductVersion", "1.3.2.0"
7777
END
7878
END
7979
BLOCK "VarFileInfo"

alpaca_zorro_plugin/logger.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,19 @@ namespace alpaca {
138138
#define LOG_DEBUG(format, ...) Logger::instance().log(L_DEBUG, LT_ALL, format, __VA_ARGS__);
139139
#define LOG_DEBUG_EXT(type, format, ...) Logger::instance().log(L_DEBUG, type, format, __VA_ARGS__);
140140
#define LOG_INFO(format, ...) Logger::instance().log(L_INFO, LT_ALL, format, __VA_ARGS__);
141-
//#define LOG_INFO_EXT(type, format, ...) Logger::instance().log(L_INFO, type, format, __VA_ARGS__);
141+
#define LOG_INFO_EXT(type, format, ...) Logger::instance().log(L_INFO, type, format, __VA_ARGS__);
142142
#define LOG_WARNING(format, ...) Logger::instance().log(L_WARNING, LT_ALL, format, __VA_ARGS__);
143-
//#define LOG_WARNING_EXT(type, format, ...) Logger::instance().log(L_WARNING, type, format, __VA_ARGS__);
143+
#define LOG_WARNING_EXT(type, format, ...) Logger::instance().log(L_WARNING, type, format, __VA_ARGS__);
144144
#define LOG_ERROR(format, ...) Logger::instance().log(L_ERROR, LT_ALL, format, __VA_ARGS__);
145-
//#define LOG_ERROR_EXT(type, format, ...) Logger::instance().log(L_ERROR, type, format, __VA_ARGS__);
145+
#define LOG_ERROR_EXT(type, format, ...) Logger::instance().log(L_ERROR, type, format, __VA_ARGS__);
146146
#define LOG_TRACE(format, ...) Logger::instance().log(L_TRACE, LT_ALL, format, __VA_ARGS__);
147-
//#define LOG_TRACE_EXT(type, format, ...) Logger::instance().log(L_TRACE, type, format, __VA_ARGS__);
147+
#define LOG_TRACE_EXT(type, format, ...) Logger::instance().log(L_TRACE, type, format, __VA_ARGS__);
148148
#ifdef _DEBUG
149149
#define LOG_DIAG(format, ...) Logger::instance().log(L_DEBUG, LT_ALL, format, __VA_ARGS__);
150+
#define LOG_DIAG_EXT(type, format, ...) Logger::instance().log(L_DEBUG, type, format, __VA_ARGS__);
150151
#else
151152
#define LOG_DIAG(format, ...)
153+
#define LOG_DIAG_EXT(type, format, ...)
152154
#endif
153155
#endif
154156
}

alpaca_zorro_plugin/market_data/alpaca_market_data.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ Response<std::vector<Bar>> AlpacaMarketData::downloadBars(
252252
return false;
253253
}
254254

255+
// change time to bar close time
256+
bar.time += nTickMinutes * 60;
257+
if (static_cast<__time32_t>(bar.time) > e) {
258+
// end time cannot exceeds tEnd
259+
LOG_DIAG_EXT(LogType::LT_HISTORY, "Drop bar at %s\n", bar.time_string.c_str());
260+
continue;
261+
}
262+
255263
if (n == 1) {
256264
bars.emplace_back(std::move(bar));
257265
--limit;
@@ -262,27 +270,27 @@ Response<std::vector<Bar>> AlpacaMarketData::downloadBars(
262270
auto duration = nTickMinutes * 60;
263271
if (((int)(e - bar.time) < duration) && ((e % duration) > (int)(bar.time % duration))) {
264272
// drop incompleted bar data
265-
LOG_DIAG("Drop bar at %s\n", bar.time_string.c_str());
273+
LOG_DIAG_EXT(LogType::LT_HISTORY, "Drop bar at %s\n", bar.time_string.c_str());
266274
continue;
267275
}
268276
bFirstBar = false;
269277
}
270278
rtBar = bar;
271279
bar_end_time = rtBar.time;
272-
LOG_DIAG("Bar end at %s\n", rtBar.time_string.c_str());
280+
LOG_DIAG_EXT(LogType::LT_HISTORY, "Bar end at %s\n", rtBar.time_string.c_str());
273281
}
274282
else {
275283
if ((int)(bar_end_time - bar.time) > ((nTickMinutes - 1) * 60)) {
276-
LOG_WARNING("Some data is missing, the data at %s belongs to different bar.\n", bar.time_string.c_str());
277-
LOG_DIAG("Bar end at %s\n", bar.time_string.c_str());
284+
LOG_WARNING_EXT(LogType::LT_HISTORY, "Some data is missing, the data at %s belongs to different bar.\n", bar.time_string.c_str());
285+
LOG_DIAG_EXT(LogType::LT_HISTORY, "Bar end at %s\n", bar.time_string.c_str());
278286
bars.emplace_back(std::move(rtBar));
279287
rtBar = bar;
280288
bar_end_time = bar.time;
281289
i = 0;
282290
--limit;
283291
}
284292
else {
285-
LOG_DIAG("Bar at %s\n", bar.time_string.c_str());
293+
LOG_DIAG_EXT(LogType::LT_HISTORY, "Bar at %s\n", bar.time_string.c_str());
286294
rtBar.high_price = std::max<double>(rtBar.high_price, bar.high_price);
287295
rtBar.low_price = std::min<double>(rtBar.low_price, bar.low_price);
288296
rtBar.open_price = bar.open_price;
@@ -313,9 +321,14 @@ Response<std::vector<Bar>> AlpacaMarketData::downloadBars(
313321
std::string sEnd = timeToString(e);
314322
std::stringstream url;
315323
url << baseUrl_ << "/v2/stocks/" << symbol << "/bars?start=" << sStart
316-
<< "&end=" << sEnd << "&limit=" << 10000 << "&timeframe=" << timeframe
324+
<< "&end=" << sEnd << "&limit=10000&timeframe=" << timeframe
317325
<< "&sort=desc&adjustment=" << to_string(Config::get().adjustment);
318326

327+
if (!Config::get().alpacaPaidPlan)
328+
{
329+
url << "&feed=iex";
330+
}
331+
319332
if (!page_token.empty()) {
320333
url << "&page_token=" << page_token;
321334
}
@@ -339,10 +352,10 @@ Response<std::vector<Bar>> AlpacaMarketData::downloadBars(
339352

340353
auto& retrvievedBars = retrieved.content().bars;
341354
if (!retrvievedBars.empty()) {
342-
LOG_TRACE("%d bars downloaded. %s-%s\n", retrvievedBars.size(), retrvievedBars.front().time_string.c_str(), retrvievedBars.back().time_string.c_str());
355+
LOG_TRACE_EXT(LogType::LT_HISTORY, "%d bars downloaded. %s-%s\n", retrvievedBars.size(), retrvievedBars.front().time_string.c_str(), retrvievedBars.back().time_string.c_str());
343356

344-
if (!retrieved.content().next_page_token.empty()) {
345-
LOG_DIAG("data pagenated\n");
357+
if (!retrieved.content().next_page_token.empty() && retrvievedBars.size() != 10000) {
358+
LOG_DIAG_EXT(LogType::LT_HISTORY, "data pagenated\n");
346359
// need to get more data entil reach the end;
347360
page_token = retrieved.content().next_page_token;
348361
}
@@ -356,18 +369,18 @@ Response<std::vector<Bar>> AlpacaMarketData::downloadBars(
356369
break;
357370
}
358371
} else {
359-
LOG_TRACE("0 bars downloaded.\n");
372+
LOG_TRACE_EXT(LogType::LT_HISTORY, "0 bars downloaded.\n");
360373
break;
361374
}
362375
} while (limit || !page_token.empty());
363-
LOG_DIAG("limit: %d\n", limit);
376+
LOG_DIAG_EXT(LogType::LT_HISTORY, "limit: %d, bar size=%d\n", limit, bars.size());
364377
return response;
365378
}
366379

367380
void AlpacaMarketData::getFromDownloadedBars(std::vector<Bar>& bars, __time32_t& end, uint32_t& limit) const {
368381
if (!downloaded_bars_.empty()) {
369382
// found in bars we already downloaded
370-
LOG_DIAG("check dowloaded bars. returned_index_=%d, bar=%s\n", returned_index_, timeToString(downloaded_bars_[returned_index_].time).c_str());
383+
LOG_DIAG_EXT(LogType::LT_HISTORY, "check dowloaded bars. returned_index_=%d, bar=%s\n", returned_index_, timeToString(downloaded_bars_[returned_index_].time).c_str());
371384

372385
for (returned_index_; returned_index_ >= 0 && returned_index_ < downloaded_bars_.size();) {
373386
auto& bar = downloaded_bars_[returned_index_];
@@ -383,7 +396,7 @@ void AlpacaMarketData::getFromDownloadedBars(std::vector<Bar>& bars, __time32_t&
383396
auto upperbound = returned_index_;
384397
returned_index_ = std::max<int>(returned_index_ - limit + 1, 0);
385398
if (returned_index_ > 0 || ((upperbound - returned_index_ + 1) == limit)) {
386-
LOG_DIAG("have enough data in downloaded. returned_index_=%d, upperbound=%d, first bar=%s, last bar=%s\n", returned_index_, upperbound, timeToString(downloaded_bars_[returned_index_].time).c_str(), timeToString(downloaded_bars_[upperbound].time).c_str());
399+
LOG_DIAG_EXT(LogType::LT_HISTORY, "have enough data in downloaded. returned_index_=%d, upperbound=%d, first bar=%s, last bar=%s\n", returned_index_, upperbound, timeToString(downloaded_bars_[returned_index_].time).c_str(), timeToString(downloaded_bars_[upperbound].time).c_str());
387400
// dwonloaded bars contains enough bars
388401
for (auto i = returned_index_; i <= upperbound; ++i, --limit) {
389402
bars.emplace_back(std::move(downloaded_bars_[i]));
@@ -404,7 +417,7 @@ void AlpacaMarketData::getFromDownloadedBars(std::vector<Bar>& bars, __time32_t&
404417
}
405418

406419
if (!leftover_bars_.empty()) {
407-
LOG_DIAG("%d bars already downloaded, first bar %s, last bar %s\n", leftover_bars_.size(), timeToString(leftover_bars_[0].time).c_str(), timeToString(leftover_bars_.back().time).c_str());
420+
LOG_DIAG_EXT(LogType::LT_HISTORY, "%d bars already downloaded, first bar %s, last bar %s\n", leftover_bars_.size(), timeToString(leftover_bars_[0].time).c_str(), timeToString(leftover_bars_.back().time).c_str());
408421
end = leftover_bars_[0].time;
409422
}
410423
}

0 commit comments

Comments
 (0)