aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntony Kellermann2018-05-15 23:41:44 -0400
committerAntony Kellermann2018-05-15 23:41:44 -0400
commit05ea99079fa0e2feed917dd76e7e6ae0e8950499 (patch)
tree07111d81545e42b9fb8576b6aa01166b151842aa
parentbbc00165b1bd6e72fefbe41541613ba8845e3dcd (diff)
downloadaur-05ea99079fa0e2feed917dd76e7e6ae0e8950499.tar.gz
Implemented compare command
-rw-r--r--graph.c103
-rw-r--r--graph.h5
-rw-r--r--main.c8
3 files changed, 99 insertions, 17 deletions
diff --git a/graph.c b/graph.c
index 9f7e0718ae65..06d8e1ba3fb1 100644
--- a/graph.c
+++ b/graph.c
@@ -2,15 +2,38 @@
int zoom_months[] = {60, 48, 36, 24, 12, 9, 6, 3, 1}, zoom_change_x_months[] = {12, 12, 12, 12, 12, 3, 3, 3, 2};
-void graph_main(const char* ticker_name_string) {
- double* price_data = api_get_hist_5y(ticker_name_string);
- if (price_data == NULL) // If invalid symbol or cryptocurrency
- RET_MSG("Invalid symbol.")
-
+void graph_main(const char* ticker_name_string, const char* ticker_name_string2) {
initscr();
+ if (ticker_name_string2 != NULL && !has_colors()) {
+ endwin();
+ puts("Your terminal does not support color.");
+ return;
+ }
+
+ puts("Loading data...");
+ double* price_data = api_get_hist_5y(ticker_name_string), * price_data2 = NULL;
+ if (price_data == NULL) { // If invalid symbol or cryptocurrency
+ endwin();
+ puts("Invalid symbol.");
+ return;
+ }
+
+ if (ticker_name_string2 != NULL) {
+ price_data2 = api_get_hist_5y(ticker_name_string2);
+ if (price_data2 == NULL) { // If invalid symbol or cryptocurrency
+ free(price_data);
+ endwin();
+ puts("Invalid symbol.");
+ return;
+ }
+ }
noecho(); // Don't echo keystrokes
keypad(stdscr, TRUE); // Enables extra keystrokes
curs_set(0); // Hides cursor
+ if (ticker_name_string2 != NULL) {
+ start_color(); // Enable colors
+ init_pair(1, COLOR_RED, COLOR_BLACK);
+ }
time_t now = time(NULL);
struct tm today_date = *localtime(&now), start_date = today_date, furthest_back_date = today_date, end;
start_date.tm_year -= 5, furthest_back_date.tm_year -= 5;
@@ -19,15 +42,21 @@ void graph_main(const char* ticker_name_string) {
double seconds = difftime(mktime(&today_date), mktime(&furthest_back_date));
int trading_days = (int) ((1.0 / DAYS_TO_BUSINESS_DAYS_RATIO) * seconds / 86400.0); // Total trading days to print
- int total_data_points = 0;
+ int total_data_points = 0, total_data_points2 = 0;
for (int i = 0; price_data[i] != '\0'; i++)
total_data_points++;
- int difference = trading_days - total_data_points;
- if (difference > 0) // On initial print, scrub to make sure that there are 5 years worth of data points
+ if (price_data2 != NULL)
+ for (int i = 0; price_data2[i] != '\0'; i++)
+ total_data_points2++;
+
+ if (trading_days - total_data_points > 0) // On initial print, scrub to make sure that there are 5 years worth of data points
price_data = graph_fill_empty(price_data, total_data_points, trading_days);
- graph_print(price_data, &start_date, zoom); // Initial graph of 5 year history
+ if (ticker_name_string2 != NULL && trading_days - total_data_points2 > 0) // On initial print, scrub to make sure that there are 5 years worth of data points
+ price_data2 = graph_fill_empty(price_data2, total_data_points2, trading_days);
+
+ graph_print(price_data, price_data2, &start_date, zoom, ticker_name_string, ticker_name_string2); // Initial graph of 5 year history
while ((ch = getch()) != 'q') { // Main input loop -- end if keypress 'q'
if ((ch == KEY_UP && zoom != ZOOM_1m) || (ch == KEY_DOWN && zoom != ZOOM_5y) ||
@@ -55,21 +84,24 @@ void graph_main(const char* ticker_name_string) {
if (difftime(mktime(&start_date), mktime(&furthest_back_date)) < 0)
start_date = furthest_back_date; // Can't go back past furthest_date
}
- graph_print(price_data, &start_date, zoom);
+ graph_print(price_data, price_data2, &start_date, zoom, ticker_name_string, ticker_name_string2);
}
}
endwin();
free(price_data);
+ if (price_data2 != NULL)
+ free(price_data2);
}
-void graph_print(const double* points, struct tm* start_time, int zoom) {
+void graph_print(const double* points, const double* points2, struct tm* start_time, int zoom,
+ const char* ticker_name_string, const char* ticker_name_string2) {
move(0, 0); // Instead of clear()ing, move to the top left corner and re-print
int cols, rows;
getmaxyx(stdscr, rows, cols);
cols -= 11; // 10 offset to give space for graph labels + 1 for right side
rows -= 3; // Make space for zoom indicator
rows -= rows % ROWS_SPACING; // Round down to multiple of 5
- if (cols < 10 || rows < 10) // Exits if the terminal is too small
+ if (cols < 50 || rows < 25) // Exits if the terminal is too small
RET_MSG("Terminal not large enough.")
time_t now = time(NULL);
@@ -88,7 +120,6 @@ void graph_print(const double* points, struct tm* start_time, int zoom) {
max = points[++k];
if (k > 0) // Do the same thing with min
min = max;
-
for (int i = starting_index + 1; i < trading_days + starting_index; i++) {
if (points[i] != EMPTY) { // Ignore EMPTY values
if (points[i] > max) // Find max and min values for graph upper/lower bounds
@@ -99,14 +130,46 @@ void graph_print(const double* points, struct tm* start_time, int zoom) {
}
double line_diff = (max - min) / rows, dat; // Each line includes data point up to line_diff below
+ double max2 = 0, min2 = 0, line_diff2 = 0, dat2 = 0;
+ if (points2 != NULL) {
+ max2 = points2[starting_index], min2 = points2[starting_index];
+ k = 0;
+ while (max2 == EMPTY) // If initial max is EMPTY, get first non-EMPTY value
+ max2 = points2[++k];
+ if (k > 0) // Do the same thing with min
+ min2 = max2;
+ for (int i = starting_index + 1; i < trading_days + starting_index; i++) {
+ if (points2[i] != EMPTY) { // Ignore EMPTY values
+ if (points2[i] > max2) // Find max and min values for graph upper/lower bounds
+ max2 = points2[i];
+ if (points2[i] < min2)
+ min2 = points2[i];
+ }
+ }
+ line_diff2 = (max2 - min2) / rows;
+ }
+
for (int i = rows; i >= 0; i--) {
if (i % ROWS_SPACING == 0) // Print y-axis price labels with width 10
printw("%9.2lf ", (max - ((rows - i) * line_diff)));
+ else if (points2 != NULL && (i - 1 ) % ROWS_SPACING == 0) {// Print y-axis price labels with width 10
+ attron(COLOR_PAIR(1));
+ printw("%9.2lf ", (max2 - ((rows - i) * line_diff2)));
+ attroff(COLOR_PAIR(1));
+ }
else printw(" "); // Indent width 10
for (int j = 0; j < cols; j++) {
dat = points[starting_index + (int) ((double) j * trading_days / cols)];
+ if (points2 != NULL)
+ dat2 = points2[starting_index + (int) ((double) j * trading_days / cols)];
if (dat <= (max - ((rows - i) * line_diff)) && dat > (min + ((i - 1) * line_diff)))
addch(ACS_DIAMOND);
+ else if (points2 != NULL && dat2 <= (max2 - ((rows - i) * line_diff2)) &&
+ dat2 > (min2 + ((i - 1) * line_diff2))) {
+ attron(COLOR_PAIR(1));
+ addch(ACS_DIAMOND);
+ attroff(COLOR_PAIR(1));
+ }
else if (i % ROWS_SPACING == 0 && j % COLS_SPACING == 0) // Cross on corners
addch(ACS_PLUS);
else if (i % ROWS_SPACING == 0) // Horizontal line every ROWS_SPACING lines
@@ -134,7 +197,19 @@ void graph_print(const double* points, struct tm* start_time, int zoom) {
}
printw("\n\n"); // Empty line as spacing
- for (int i = 0; i < cols / 2 - 8; i++)
+ printw(" %s", ticker_name_string);
+ addch(ACS_DIAMOND);
+ if (points2 != NULL) {
+ attron(COLOR_PAIR(1));
+ printw(" %s", ticker_name_string2);
+ addch(ACS_DIAMOND);
+ attroff(COLOR_PAIR(1));
+ }
+ addch(' ');
+ size_t offset = (cols / 2) - (11 + strlen(ticker_name_string));
+ if (points2 != NULL)
+ offset -= strlen(ticker_name_string2) + 2;
+ for (unsigned int i = 0; i < offset; i++)
addch(' '); // Center text
const char* str[9] = {"5y", "4y", "3y", "2y", "1y", "9m", "6m", "3m", "1m"}; // Zoom level
for (int i = 0; i < 9; i++) {
diff --git a/graph.h b/graph.h
index de3438c0452b..bddfbb1f9239 100644
--- a/graph.h
+++ b/graph.h
@@ -33,7 +33,7 @@ extern int zoom_months[9], zoom_change_x_months[9];
* RIGHT: moves start date forward by one year, three months, or one month.
* @param ticker_name_string symbol
*/
-void graph_main(const char* ticker_name_string);
+void graph_main(const char* ticker_name_string, const char* ticker_name_string2);
/**
* Prints out a NCurses based graph given an array of daily close prices.
@@ -43,7 +43,8 @@ void graph_main(const char* ticker_name_string);
* @param start_time the starting date of prices to print
* @param zoom the zoom level
*/
-void graph_print(const double* points, struct tm* start_time, int zoom);
+void graph_print(const double* points, const double* points2, struct tm* start_time, int zoom,
+ const char* ticker_name_string, const char* ticker_name_string2);
/**
* Reallocates the given array with size trading days. Moves all values to end of the array and sets
diff --git a/main.c b/main.c
index ddaf8b490cb5..f493659b4ba2 100644
--- a/main.c
+++ b/main.c
@@ -42,7 +42,13 @@ int main(int argc, char* argv[]) {
else if (strcmp(cmd, "info") == 0 && argc == 3)
api_print_info(sym);
else if (strcmp(cmd, "graph") == 0 && argc == 3)
- graph_main(sym);
+ graph_main(sym, NULL);
+ else if (strcmp(cmd, "compare") == 0 && argc == 4) {
+ char sym2[strlen(argv[3]) + 1];
+ strcpy(sym2, argv[3]);
+ strtoupper(sym2);
+ graph_main(sym, sym2);
+ }
// Check
else if (strcmp(cmd, "check") == 0) {