diff options
author | Antony Kellermann | 2018-05-15 23:41:44 -0400 |
---|---|---|
committer | Antony Kellermann | 2018-05-15 23:41:44 -0400 |
commit | 05ea99079fa0e2feed917dd76e7e6ae0e8950499 (patch) | |
tree | 07111d81545e42b9fb8576b6aa01166b151842aa /graph.c | |
parent | bbc00165b1bd6e72fefbe41541613ba8845e3dcd (diff) | |
download | aur-05ea99079fa0e2feed917dd76e7e6ae0e8950499.tar.gz |
Implemented compare command
Diffstat (limited to 'graph.c')
-rw-r--r-- | graph.c | 103 |
1 files changed, 89 insertions, 14 deletions
@@ -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++) { |