diff --git a/.vscode/launch.json b/.vscode/launch.json index 16ca2c5..3762613 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,12 +4,33 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { - "name": "(gdb) Launch", + "name": "(gdb) Launch (Linux)", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/bin/debug/algoticks", - "args": ["-D","1", "-s", "7117"], + "args": ["-D","1"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/bin/debug/", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + + { + "name": "(gdb) Launch (Windows)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bin/debug/algoticks.exe", + "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}/bin/debug/", "environment": [], diff --git a/README.md b/README.md index 56f7767..e8b575f 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ upon successful compilation, the binary executable along with config files are f ### Building on Windows (experimental) 1. Install [MSYS2](https://www.msys2.org/) +2. Install [CMake for Windows.](https://cmake.org/download/) 2. Add the following to System PATH: ``` C:\msys64\mingw64\include @@ -67,17 +68,16 @@ C:\msys64\mingw64\lib C:\msys64\usr\bin ``` -Run the following commands in MSYS2 terminal: +Run the following commands in `mingw64.exe` terminal: ``` pacman -S base-devel mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-json-c mingw-w64-x86_64-zeromq -cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug .. ``` -Run the following in CMD from repository root directory: +Run the following commands from repository root directory: ``` mkdir bin cd bin -cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug .. +cmake -G "MSYS Makefiles" .. make ``` diff --git a/assets/configs/linux/benchmark.json b/assets/configs/linux/benchmark.json index 192a25b..f90b8f4 100644 --- a/assets/configs/linux/benchmark.json +++ b/assets/configs/linux/benchmark.json @@ -8,7 +8,7 @@ "quantity": [10], "target": [1.5,2,2.5], "stoploss": [2,2.5,3,3.5], - "is_training_sl": [true,false], + "is_trailing_sl": [true,false], "trailing_sl_val": [1,2,3], "sliding": [true, false], diff --git a/assets/configs/linux/config.json b/assets/configs/linux/config.json index a8ae597..7f41057 100644 --- a/assets/configs/linux/config.json +++ b/assets/configs/linux/config.json @@ -8,7 +8,7 @@ "quantity": 100, "target": 5, "stoploss": 7, - "is_training_sl": false, + "is_trailing_sl": false, "trailing_sl_val": 1, "sliding": true, diff --git a/assets/configs/windows/benchmark.json b/assets/configs/windows/benchmark.json index a071ad1..a235bd6 100644 --- a/assets/configs/windows/benchmark.json +++ b/assets/configs/windows/benchmark.json @@ -8,7 +8,7 @@ "quantity": [10], "target": [1.5,2,2.5], "stoploss": [2,2.5,3,3.5], - "is_training_sl": [true,false], + "is_trailing_sl": [true,false], "trailing_sl_val": [1,2,3], "sliding": [true, false], diff --git a/assets/configs/windows/config.json b/assets/configs/windows/config.json index dd35c40..3bb5684 100644 --- a/assets/configs/windows/config.json +++ b/assets/configs/windows/config.json @@ -8,7 +8,7 @@ "quantity": 100, "target": 5, "stoploss": 7, - "is_training_sl": false, + "is_trailing_sl": false, "trailing_sl_val": 1, "sliding": true, diff --git a/assets/derivative_example.zip b/assets/derivative_example.zip index ee9d208..b7b657b 100644 Binary files a/assets/derivative_example.zip and b/assets/derivative_example.zip differ diff --git a/include/callbacks.h b/include/callbacks.h index f8e8e80..1d30a22 100644 --- a/include/callbacks.h +++ b/include/callbacks.h @@ -1,3 +1,6 @@ -int load_callbacks(algoticks_config config); +int load_callbacks(algoticks_config *config); int send_callbacks(algoticks_event events); int close_callbacks(); +algoticks_event make_event_from_positionresult(algoticks_positionresult positionresult); +algoticks_event make_event_from_signal(algoticks_signal signal); +algoticks_event make_event_from_position(algoticks_row pos_storage, algoticks_dashboard dashboard); diff --git a/include/csvutils.h b/include/csvutils.h index d1edee0..b7b01bf 100644 --- a/include/csvutils.h +++ b/include/csvutils.h @@ -1,5 +1,5 @@ #define MAXCHARPERLINE 1024 -#define MAXCSVHEAD 11 +#define MAXCSVHEAD 12 /* Declarations */ void reset_header_skip(); @@ -9,6 +9,6 @@ int change_in_modified_date(char* filename); int reopen_datasource(char* filename, FILE** fp, char* mode); algoticks_row tokenize_row(char *row); void set_ohlcv_as_header(); -int process_csv_header(algoticks_settings settings, char *row); -int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char *fname, algoticks_row *storage, int seek_offset); +int process_csv_header(algoticks_settings *settings, char *row); +int read_csv(algoticks_settings *settings,algoticks_config *config, FILE *fp, char *fname, algoticks_row *storage, int seek_offset); int is_quoted(char *str); \ No newline at end of file diff --git a/include/dashboard.h b/include/dashboard.h index d051003..32d7420 100644 --- a/include/dashboard.h +++ b/include/dashboard.h @@ -1,3 +1,3 @@ /* Declarations */ float getPnL(algoticks_dashboard dashboard); -void print_dashboard(algoticks_settings settings,algoticks_config config,algoticks_dashboard dashboard); +void print_dashboard(algoticks_settings *settings,algoticks_config *config,algoticks_dashboard dashboard); diff --git a/include/debug.h b/include/debug.h index 18ea77a..fc6ddcd 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,9 +1,9 @@ /* Declarations */ -void debug_msg(algoticks_settings settings, int debug_level, char *op, char *loc, char *remarks); - +void debug_msg(bool settings_debug, int settings_debug_level, int msg_debug_level, char *file_name, const char *function, int line_n, char *message); +void debug_msg_simple(char* msg); /* struct debug */ -void print_config_struct(algoticks_config config); -void print_dashboard_struct(algoticks_dashboard dashboard); -void print_signal_struct(algoticks_signal signal); -void print_simresult_struct(algoticks_simresult simresult); -void print_row_struct(algoticks_row row); \ No newline at end of file +void print_config_struct(algoticks_config *config); +void print_dashboard_struct(algoticks_dashboard *dashboard); +void print_signal_struct(algoticks_signal *signal); +void print_simresult_struct(algoticks_simresult *simresult); +void print_row_struct(algoticks_row *row); \ No newline at end of file diff --git a/include/dtypes.h b/include/dtypes.h index e4f24cb..815cc90 100644 --- a/include/dtypes.h +++ b/include/dtypes.h @@ -5,12 +5,12 @@ typedef struct Settings int debug; int debug_level; - char config_f[512]; - char benchmark_f[512]; + char *config_f; + char *benchmark_f; int is_live_data; int is_live_data_socket; - char socket_port[12]; + char *socket_port; int is_derivative; int is_benchmark; /* for windows usage */ @@ -20,80 +20,80 @@ typedef struct Settings }algoticks_settings; typedef struct Dervative{ - char derivative_datasource[512]; + char *derivative_datasource; int derivative_interval; }algoticks_derivative; + + +typedef struct Config +{ + char *algo; + char *datasource; + algoticks_derivative derivative; + char *symbol; + int candles; + int interval; + + char **callbacks; + int n_callbacks; + + double target; + double stoploss; + int is_trailing_sl; /* FLAG */ + double trailing_sl_val; + int quantity; + + int sliding; /* FLAG */ + int intraday; /* FLAG */ + + int skip_header; /* FLAG */ +}algoticks_config; + typedef struct BenchmarkConfig { - char algo[1024][32]; - int n_algo; - char datasource[1024][512]; + char *symbol; + + int n_algo; + char **algo_arr; + int n_datasource; + char **datasource_arr; algoticks_derivative derivative; - int n_derivative; - - char symbol[32]; - int candles[1024]; int n_candles; + int *candles_arr; - int interval[1024]; int n_interval; + int *interval_arr; - double target[1024]; int n_target; + double *target_arr; - double stoploss[1024]; int n_stoploss; + double *stoploss_arr; + + int n_is_trailing_sl; + int *is_trailing_sl; /* array of bool */ - int is_training_sl[2]; - int n_is_training_sl; - - double trailing_sl_val[1024]; int n_trailing_sl_val; + double *trailing_sl_val_arr; - int quantity[1024]; - int n_quantity; - - int sliding[2]; + int n_quantity; + int *quantity_arr; + int n_sliding; + int *sliding; /* array of bool */ - int intraday[2]; int n_intraday; + int *intraday; /* array of bool */ int skip_header; }algoticks_benchmarkconfig; - -typedef struct Config -{ - char algo[32]; - char datasource[512]; - algoticks_derivative derivative; - char symbol[32]; - int candles; - int interval; - - char callbacks[6][32]; - int n_callbacks; - - double target; - double stoploss; - int is_training_sl; - double trailing_sl_val; - int quantity; - - int sliding; - int intraday; - - int skip_header; -}algoticks_config; - - typedef struct Dashboard { char date[32]; @@ -117,9 +117,9 @@ typedef struct row_ti{ float ti3; int is_ti_others_p; - char ti_others[2048]; + char *ti_others; -}algoticks_tow_ti; +}algoticks_row_ti; typedef struct Row { @@ -131,7 +131,7 @@ typedef struct Row float close; int volume; - algoticks_tow_ti technical_indicators; + algoticks_row_ti technical_indicators; int curr; int n_rows; //this is to be set in case of Row array of non-predetermined size. @@ -194,11 +194,11 @@ typedef struct Event { int t_h; int sl_h; - int tsl; - float tsl_t; - float tsl_sl; + int tsl; /* trailing SL */ + float tsl_t; /* trailing SL target */ + float tsl_sl; /* trailing SL stoploss */ - char date[64]; + char date[32]; float a; float b; float pnl; diff --git a/include/misc.h b/include/misc.h index 3a2c5b0..40e9d43 100644 --- a/include/misc.h +++ b/include/misc.h @@ -2,16 +2,16 @@ algoticks_cb_l load_cb(char *algo); algo_func load_algo_func(char *algo); void close_algo_func(); -void write_simresult_to_csv(algoticks_simresult simresult); +void write_simresult_to_csv(algoticks_simresult *simresult); void create_setting_config_benchmark_files(int type); int is_file_exists(const char * filename); void chomp(char *s); -algoticks_benchmarkconfig parse_benchmark_from_json(char *filename); -algoticks_settings parse_settings_from_json(char *filename); -algoticks_config parse_config_from_json(char *filename); -algoticks_config filter_boundaries(algoticks_config config, int is_short); +void filter_boundaries(algoticks_config *config, int is_short); int is_target_hit(algoticks_dashboard dashboard, float target); int is_stoploss_hit(algoticks_dashboard dashboard, float stoploss); float brokerage_calc(); void convert_to_lowercase(char *str); -void remove_quotes(char *str); \ No newline at end of file +void remove_quotes(char *str); +void free_algoticks_config(algoticks_config *config); +void free_algoticks_settings(algoticks_settings *settings); +void free_algoticks_benchmark(algoticks_benchmarkconfig *benchmark); diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 0000000..78b7233 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,3 @@ +algoticks_settings parse_settings_from_json(char *filename); +algoticks_config parse_config_from_json(char *filename); +algoticks_benchmarkconfig parse_benchmark_from_json(char *filename); \ No newline at end of file diff --git a/include/sim.h b/include/sim.h index 8ed35d6..e45cd8d 100644 --- a/include/sim.h +++ b/include/sim.h @@ -1,3 +1,3 @@ /* Declarations */ -algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config); -algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int curr, algoticks_settings settings, algoticks_config config,algoticks_row lastrow); \ No newline at end of file +algoticks_simresult run_sim(algoticks_settings *settings, algoticks_config *config); +algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int curr, algoticks_settings *settings, algoticks_config *config,algoticks_row lastrow); \ No newline at end of file diff --git a/include/sim_derivative.h b/include/sim_derivative.h index 1a69dc3..d876593 100644 --- a/include/sim_derivative.h +++ b/include/sim_derivative.h @@ -1,3 +1,3 @@ /* Declarations */ -algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_config config); -algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FILE *index_f, FILE *derivative_f, algoticks_settings settings, algoticks_config config, algoticks_row lastrow); \ No newline at end of file +algoticks_simresult run_sim_w_derivative(algoticks_settings *settings, algoticks_config *config); +algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FILE *index_f, FILE *derivative_f, algoticks_settings *settings, algoticks_config *config, algoticks_row lastrow); \ No newline at end of file diff --git a/include/timeutils.h b/include/timeutils.h index f30e1fe..c3403d5 100644 --- a/include/timeutils.h +++ b/include/timeutils.h @@ -2,4 +2,4 @@ int is_date_over_or_eq_intraday(char *date, int intraday_hour, int intraday_min) int is_date_after(char *date_a, char *date_b); int is_date_before(char *date_a, char *date_b); int get_time_with_sscanf_from_string(char* date, struct tm *time_struct); -int sync_curr(algoticks_settings settings, algoticks_config config, FILE *f, char* fname, char *date, int seek_offset, int debug); \ No newline at end of file +int sync_curr(algoticks_settings *settings, algoticks_config *config, FILE *f, char* fname, char *date, int seek_offset, int debug); \ No newline at end of file diff --git a/src/benchmark.c b/src/benchmark.c index e9c809e..2ecbbc2 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -1,15 +1,19 @@ #include #include #include +#include #include "../include/dtypes.h" #include "../include/misc.h" #include "../include/benchmark.h" #include "../include/debug.h" #include "../include/sim.h" #include "../include/sim_derivative.h" +#include "../include/parser.h" void run_benchmark(char *benchmark_config_file, algoticks_settings settings) { + + //disable printing settings.print = false; @@ -17,6 +21,7 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) settings.is_live_data_socket = false; struct BenchmarkConfig benchmarkconfig; benchmarkconfig = parse_benchmark_from_json(benchmark_config_file); + //total 11 fields in config = 11 loops @@ -28,7 +33,7 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) total_combinations *= benchmarkconfig.n_target; total_combinations *= benchmarkconfig.n_stoploss; - total_combinations *= benchmarkconfig.n_is_training_sl; + total_combinations *= benchmarkconfig.n_is_trailing_sl; total_combinations *= benchmarkconfig.n_trailing_sl_val; total_combinations *= benchmarkconfig.n_quantity; total_combinations *= benchmarkconfig.n_sliding; @@ -38,6 +43,7 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) int combination_completed = 1; float progress = 0; + size_t len; for (int n_algo = 0; n_algo < benchmarkconfig.n_algo; n_algo++) { @@ -51,7 +57,7 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) { for (int n_stoploss = 0; n_stoploss < benchmarkconfig.n_stoploss; n_stoploss++) { - for (int n_is_training_sl = 0; n_is_training_sl < benchmarkconfig.n_is_training_sl; n_is_training_sl++) + for (int n_is_training_sl = 0; n_is_training_sl < benchmarkconfig.n_is_trailing_sl; n_is_training_sl++) { for (int n_trailing_sl_val = 0; n_trailing_sl_val < benchmarkconfig.n_trailing_sl_val; n_trailing_sl_val++) { @@ -61,24 +67,39 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) { for (int n_intraday = 0; n_intraday < benchmarkconfig.n_intraday; n_intraday++) { - /* make a new struct here */ - struct Config config; + // make a new config struct + algoticks_config config = {0}; + algoticks_derivative derivative = {0}; + + len = strlen(benchmarkconfig.algo_arr[n_algo]); + config.algo = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.algo, benchmarkconfig.algo_arr[n_algo]); + + len = strlen(benchmarkconfig.datasource_arr[n_datasource]); + config.datasource = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.datasource, benchmarkconfig.datasource_arr[n_datasource]); - strncpy(config.algo, benchmarkconfig.algo[n_algo], 32); - strncpy(config.datasource, benchmarkconfig.datasource[n_datasource], 512); - strncpy(config.symbol, benchmarkconfig.symbol, 32); + len = strlen(benchmarkconfig.symbol); + config.symbol = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.symbol, benchmarkconfig.symbol); + + if (settings.is_derivative){ + derivative.derivative_datasource = (char*) malloc((strlen(benchmarkconfig.derivative.derivative_datasource) + 1) * sizeof(char)); + strcpy(derivative.derivative_datasource, benchmarkconfig.derivative.derivative_datasource); + derivative.derivative_interval = benchmarkconfig.derivative.derivative_interval; + } - config.derivative = benchmarkconfig.derivative; + config.derivative = derivative; - config.candles = benchmarkconfig.candles[n_candles]; - config.interval = benchmarkconfig.interval[n_interval]; + config.candles = benchmarkconfig.candles_arr[n_candles]; + config.interval = benchmarkconfig.interval_arr[n_interval]; - config.target = benchmarkconfig.target[n_target]; - config.stoploss = benchmarkconfig.stoploss[n_stoploss]; - config.is_training_sl = benchmarkconfig.is_training_sl[n_is_training_sl]; - config.trailing_sl_val = benchmarkconfig.trailing_sl_val[n_trailing_sl_val]; - config.quantity = benchmarkconfig.quantity[n_quantity]; - + config.target = benchmarkconfig.target_arr[n_target]; + config.stoploss = benchmarkconfig.stoploss_arr[n_stoploss]; + config.is_trailing_sl = benchmarkconfig.is_trailing_sl[n_is_training_sl]; + config.trailing_sl_val = benchmarkconfig.trailing_sl_val_arr[n_trailing_sl_val]; + config.quantity = benchmarkconfig.quantity_arr[n_quantity]; + config.n_callbacks = 0; //not supported in benchmark config.sliding = benchmarkconfig.sliding[n_sliding]; config.intraday = benchmarkconfig.intraday[n_intraday]; @@ -86,15 +107,16 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) //print config combination to user if debug is enabled and debug level greater then 3. if (settings.debug == true && (settings.debug_level >= 4) == true){ - print_config_struct(config); + print_config_struct(&config); } if (settings.is_derivative){ - run_sim_w_derivative(settings, config); + run_sim_w_derivative(&settings, &config); } else{ - run_sim(settings, config); + run_sim(&settings, &config); } + free_algoticks_config(&config); combination_completed++; @@ -112,4 +134,7 @@ void run_benchmark(char *benchmark_config_file, algoticks_settings settings) } } } + + free_algoticks_benchmark(&benchmarkconfig); + } \ No newline at end of file diff --git a/src/callbacks.c b/src/callbacks.c index 5de8878..4ecb3fc 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1,8 +1,10 @@ #include #include #include +#include #include "../include/dtypes.h" #include "../include/misc.h" +#include "../include/dashboard.h" #ifndef _WIN32 #include @@ -10,23 +12,23 @@ #include #endif -void **cb; +callback_func *cb; void **cb_h; int n; -int load_callbacks(algoticks_config config){ +int load_callbacks(algoticks_config *config){ - if (config.n_callbacks > 0){ - cb = (callback_func *)malloc(config.n_callbacks * sizeof(callback_func)); - cb_h = (void *)malloc(config.n_callbacks * sizeof(void)); - n = config.n_callbacks; + if (config->n_callbacks > 0){ + cb = (callback_func *) malloc(config->n_callbacks * sizeof(callback_func)); + cb_h = (void **) malloc(config->n_callbacks * sizeof(void)); + n = config->n_callbacks; } for (int i = 0; i < n; i++) { algoticks_cb_l l; - l = load_cb(config.callbacks[i]); + l = load_cb(config->callbacks[i]); cb[i] = l.callback_func; cb_h[i] = l.handle; } @@ -63,4 +65,39 @@ for (int i = 0; i < n; i++) return true; +} + +algoticks_event make_event_from_positionresult(algoticks_positionresult positionresult){ + + algoticks_event ev = {0}; + if (strcmp(positionresult.hit_type, "SL") == 0) { + ev.sl_h = true; + } + + if (strcmp(positionresult.hit_type, "T") == 0) { + ev.t_h = true; + } + + ev.pnl = positionresult.pnl; + return ev; +} + +algoticks_event make_event_from_signal(algoticks_signal signal){ + + algoticks_event ev = {0}; + ev.signal = signal; + return ev; +} + +algoticks_event make_event_from_position(algoticks_row pos_storage, algoticks_dashboard dashboard){ + + algoticks_event ev = {0}; + + strncpy(ev.date, pos_storage.date, 32); + ev.a = dashboard.a; + ev.b = dashboard.b; + ev.pnl = getPnL(dashboard); + ev.from_pos = true; + + return ev; } \ No newline at end of file diff --git a/src/csvutils.c b/src/csvutils.c index ca33887..4d0ac3c 100644 --- a/src/csvutils.c +++ b/src/csvutils.c @@ -49,7 +49,7 @@ int check_row_integrity(algoticks_row *row){ /* header_template holds the values that program expects to find in header of csv. -header_map is initially set to -1 (ln ~139) +header_map is initially set to -1 Example: date,open,close,volume,high,low @@ -121,7 +121,6 @@ algoticks_row tokenize_row(char *row){ char *token; struct Row data; memset(&data, 0, sizeof(data)); - strncpy(data.technical_indicators.ti_others, "None", 2048); int row_pos = 0; int header_i = 0; @@ -195,7 +194,8 @@ algoticks_row tokenize_row(char *row){ if (is_quoted(token) == true) { remove_quotes(token); } data.technical_indicators.is_ti_others_p = true; - strncpy(data.technical_indicators.ti_others, token,2048); + data.technical_indicators.ti_others = (char*) malloc((strlen(token) + 1) * sizeof(char)); + strcpy(data.technical_indicators.ti_others, token); } else { @@ -212,7 +212,7 @@ algoticks_row tokenize_row(char *row){ } -int process_csv_header(algoticks_settings settings, char *row){ +int process_csv_header(algoticks_settings *settings, char *row){ char *token; token = strtok(row, ","); int header_i = 0; @@ -228,7 +228,7 @@ int process_csv_header(algoticks_settings settings, char *row){ chomp(token); convert_to_lowercase(token); - debug_msg(settings, 2, "ReadHeader","csvutils.c",token); + debug_msg(settings->debug, settings->debug_level, 4, __FILE__, __FUNCTION__, __LINE__, token); /* "date" = 0, @@ -309,14 +309,14 @@ void set_ohlcv_as_header() { } } -int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char *fname, algoticks_row *storage, int seek_offset){ +int read_csv(algoticks_settings *settings,algoticks_config *config, FILE *fp, char *fname, algoticks_row *storage, int seek_offset){ while(true) { if ( feof(fp) ) { - if (settings.is_live_data == true){ - while ((change_in_modified_date(config.datasource) == false)) + if (settings->is_live_data == true){ + while ((change_in_modified_date(config->datasource) == false)) { - printf("checking for new data in %s ...\r", config.datasource); + printf("checking for new data in %s ...\r", config->datasource); fflush(stdout); } @@ -327,13 +327,13 @@ int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char //set seek fseek(fp, seek_offset, SEEK_SET); - debug_msg(settings, 2, "FileReopen","csvutils.c", config.datasource); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, config->datasource); - }else if (settings.is_live_data_socket == true){ + }else if (settings->is_live_data_socket == true){ if (!is_socket_init){ - client_d = socket_init(settings.socket_port); + client_d = socket_init(settings->socket_port); if (client_d < 0){ printf("error creating socket!\n"); @@ -343,8 +343,8 @@ int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char is_socket_init = true; } - if (settings.debug && settings.debug_level > 2){ - printf("waiting for new data from 127.0.0.1:%s\n", settings.socket_port); + if (settings->debug && settings->debug_level > 2){ + printf("waiting for new data from 127.0.0.1:%s\n", settings->socket_port); } char buffer[4096]; @@ -365,7 +365,7 @@ int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char //set seek fseek(fp, seek_offset, SEEK_SET); - debug_msg(settings, 2, "FileReopen","csvutils.c", config.datasource); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, config->datasource); } else { @@ -384,11 +384,11 @@ int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char int curr_sp; - if (config.interval > 0 && is_header_skipped == true && settings.is_live_data == false){ - for (int i = 0; i < config.interval; i++) + if (config->interval > 0 && is_header_skipped == true && settings->is_live_data == false){ + for (int i = 0; i < config->interval; i++) { fgets(row, MAXCHARPERLINE, fp); - debug_msg(settings, 3, "SkipIntervalRow", "sim.c", row); + debug_msg(settings->debug, settings->debug_level, 4, __FILE__, __FUNCTION__, __LINE__, row); } } @@ -402,7 +402,7 @@ int read_csv(algoticks_settings settings,algoticks_config config, FILE *fp, char chomp(row); if (!is_header_skipped){ - if (config.skip_header == true){ + if (config->skip_header == true){ process_csv_header(settings, row); } else{ diff --git a/src/dashboard.c b/src/dashboard.c index b5c2415..fbf6f49 100644 --- a/src/dashboard.c +++ b/src/dashboard.c @@ -6,8 +6,7 @@ #include "../include/dashboard.h" -char *color_reset = "\033[0m"; -char *pnlcolor; +char color_reset[12] = "\033[0m"; float getPnL(algoticks_dashboard dashboard){ @@ -22,9 +21,9 @@ float getPnL(algoticks_dashboard dashboard){ } -void print_dashboard(algoticks_settings settings,algoticks_config config,algoticks_dashboard dashboard){ +void print_dashboard(algoticks_settings *settings,algoticks_config *config,algoticks_dashboard dashboard){ char buffer[1024]; - char *pnlcolor; + char pnlcolor[12]; char pnl_s[128]; float percentage_change; @@ -33,16 +32,19 @@ void print_dashboard(algoticks_settings settings,algoticks_config config,algotic percentage_change = ((pnl)/(dashboard.q * dashboard.a)) * 100; - if (settings.colors == true){ - if(pnl > 0){ pnlcolor = "\033[0;32m"; }else { pnlcolor = "\033[0;31m"; } + if (settings->colors == true){ + if(pnl > 0){ + strcpy(pnlcolor, "\033[0;32m"); + } + else { + strcpy(pnlcolor, "\033[0;31m"); + } sprintf(pnl_s, "%s%f (%f%%) %f %s", pnlcolor, pnl, percentage_change, pnl_i, color_reset); }else{ sprintf(pnl_s, "%f (%f%%) %f", pnl, percentage_change, pnl_i); } - - - sprintf(buffer, "%s\t%s\t%f\t%f\t%s",dashboard.date, config.symbol,dashboard.a, dashboard.b, pnl_s); + sprintf(buffer, "%s\t%s\t%f\t%f\t%s", dashboard.date, config->symbol, dashboard.a, dashboard.b, pnl_s); printf("%s\n", buffer); } \ No newline at end of file diff --git a/src/debug.c b/src/debug.c index cced05a..58a50c6 100644 --- a/src/debug.c +++ b/src/debug.c @@ -2,121 +2,124 @@ #include #include #include +#include #include "../include/dtypes.h" #include "../include/debug.h" #include "../include/misc.h" +#include "../include/parser.h" -void debug_msg(algoticks_settings settings, int debug_level, char *op, char *loc, char *remarks){ +void debug_msg(bool settings_debug, int settings_debug_level, int msg_debug_level, char *file_name, const char *function, int line_n, char *message){ + //check if debug is enabled! - if (settings.debug != true){ + if (settings_debug != true){ return; } //if debug level less then 0 or greater then 3. - if ( (debug_level <= 0) == true || (settings.debug_level > 3) == true ){ + if ( (settings_debug_level <= 0) == true){ return; } // if less then required debug level. - if (settings.debug_level < debug_level){ + if (settings_debug_level < msg_debug_level){ return; } - //HRT = Human readable time - char hrt[32]; - - time_t now; - - //get time - time(&now); - sprintf(hrt, "%s", ctime(&now)); - - //remove new line at end - chomp(hrt); - - char buffer[5000]; - sprintf(buffer, "{\"date\": \"%s\", \"op\": \"%s\", \"loc\": \"%s\", \"msg\": \"%s\"}\n", hrt, op, loc, remarks); + char *buffer = (char*) malloc(512 * sizeof(char)); + sprintf(buffer, "{\"date\": \"%s %s\", \"file\": \"%s\", \"func\": \"%s\", \"line_n\": %d, \"msg\": \"%s\"}\n", + __DATE__, __TIME__, file_name, function, line_n, message); printf("%s", buffer); + free(buffer); +} +void debug_msg_simple(char *msg){ + + char *buffer; + buffer = (char*) malloc(sizeof(msg)); + sprintf(buffer, "{\"date\": \"%s %s\", \"msg\": \"%s\"}\n", __DATE__, __TIME__, msg); + printf("%s", buffer); + free(buffer); + } -void print_config_struct(algoticks_config config){ +void print_config_struct(algoticks_config *config){ printf("\n===*===\n"); - printf("[DEBUG] config.algo = %s\n", config.algo); - printf("[DEBUG] config.datasource = %s\n", config.datasource); - printf("[DEBUG] config.derivative[derivative_datasource, derivative_interval] = %s %d\n", config.derivative.derivative_datasource, config.derivative.derivative_interval); - printf("[DEBUG] config.symbol = %s\n", config.symbol); - printf("[DEBUG] config.interval = %d\n", config.interval); - printf("[DEBUG] config.n_callbacks = %d\n", config.n_callbacks); - - if (config.n_callbacks > 0){ - printf("[DEBUG] config.callbacks ="); - for (int i = 0; i < config.n_callbacks; i++) + printf("[DEBUG] config->algo = %s\n", config->algo); + printf("[DEBUG] config->datasource = %s\n", config->datasource); + printf("[DEBUG] config->derivative[derivative_datasource, derivative_interval] = %s %d\n", config->derivative.derivative_datasource, config->derivative.derivative_interval); + printf("[DEBUG] config->symbol = %s\n", config->symbol); + printf("[DEBUG] config->interval = %d\n", config->interval); + printf("[DEBUG] config->n_callbacks = %d\n", config->n_callbacks); + + if (config->n_callbacks > 0){ + printf("[DEBUG] config->callbacks ="); + for (int i = 0; i < config->n_callbacks; i++) { - printf(" %s ",config.callbacks[i]); + printf(" %s ",config->callbacks[i]); } - printf("\n"); } - printf("[DEBUG] config.candles = %d\n", config.candles); - printf("[DEBUG] config.target = %f\n", config.target); - printf("[DEBUG] config.stoploss = %f\n", config.stoploss); - printf("[DEBUG] config.is_trailing_sl = %d\n", config.is_training_sl); - printf("[DEBUG] config.trailing_sl_val = %f\n", config.trailing_sl_val); - printf("[DEBUG] config.quantity = %d\n", config.quantity); + printf("[DEBUG] config->candles = %d\n", config->candles); + printf("[DEBUG] config->target = %f\n", config->target); + printf("[DEBUG] config->stoploss = %f\n", config->stoploss); + printf("[DEBUG] config->is_trailing_sl = %d\n", config->is_trailing_sl); + printf("[DEBUG] config->trailing_sl_val = %f\n", config->trailing_sl_val); + printf("[DEBUG] config->quantity = %d\n", config->quantity); - printf("[DEBUG] config.sliding = %d\n", config.sliding); - printf("[DEBUG] config.intraday = %d\n", config.intraday); - printf("[DEBUG] config.skip_header = %d\n", config.skip_header); + printf("[DEBUG] config->sliding = %d\n", config->sliding); + printf("[DEBUG] config->intraday = %d\n", config->intraday); + printf("[DEBUG] config->skip_header = %d\n", config->skip_header); + + printf("\n===*===\n"); } -void print_dashboard_struct(algoticks_dashboard dashboard){ +void print_dashboard_struct(algoticks_dashboard *dashboard){ printf("\n===*===\n"); - printf("[DEBUG] Dashboard.a = %f\n", dashboard.a); - printf("[DEBUG] Dashboard.b = %f\n", dashboard.b); - printf("[DEBUG] Dashboard.date = %s\n", dashboard.date); - printf("[DEBUG] Dashboard.pnl = %f\n", dashboard.pnl); - printf("[DEBUG] Dashboard.is_short = %d\n", dashboard.is_short); + printf("[DEBUG] dashboard->a = %f\n", dashboard->a); + printf("[DEBUG] dashboard->b = %f\n", dashboard->b); + printf("[DEBUG] dashboard->date = %s\n", dashboard->date); + printf("[DEBUG] dashboard->pnl = %f\n", dashboard->pnl); + printf("[DEBUG] dashboard->is_short = %d\n", dashboard->is_short); printf("\n===*===\n"); } -void print_signal_struct(algoticks_signal signal){ +void print_signal_struct(algoticks_signal *signal){ printf("\n===*===\n"); - printf("[DEBUG] signal.buy = %d\n", signal.buy); - printf("[DEBUG] signal.neutral = %d\n", signal.neutral); - printf("[DEBUG] signal.sell = %d\n", signal.sell); + printf("[DEBUG] signal->buy = %d\n", signal->buy); + printf("[DEBUG] signal->neutral = %d\n", signal->neutral); + printf("[DEBUG] signal->sell = %d\n", signal->sell); printf("\n===*===\n"); } -void print_simresult_struct(algoticks_simresult simresult){ +void print_simresult_struct(algoticks_simresult *simresult){ printf("\n===*===\n"); - printf("[DEBUG] signal.pnl = %f\n", simresult.pnl); - printf("[DEBUG] signal.buy_signals = %d\n", simresult.buy_signals); - printf("[DEBUG] signal.sell_signals = %d\n", simresult.sell_signals); - printf("[DEBUG] signal.neutral_signals = %d\n", simresult.neutral_signals); - printf("[DEBUG] signal.trgt_hits = %d\n", simresult.trgt_hits); - printf("[DEBUG] signal.sl_hits = %d\n", simresult.sl_hits); + printf("[DEBUG] signal->pnl = %f\n", simresult->pnl); + printf("[DEBUG] signal->buy_signals = %d\n", simresult->buy_signals); + printf("[DEBUG] signal->sell_signals = %d\n", simresult->sell_signals); + printf("[DEBUG] signal->neutral_signals = %d\n", simresult->neutral_signals); + printf("[DEBUG] signal->trgt_hits = %d\n", simresult->trgt_hits); + printf("[DEBUG] signal->sl_hits = %d\n", simresult->sl_hits); printf("\n===*===\n"); } -void print_row_struct(algoticks_row row){ +void print_row_struct(algoticks_row *row){ printf("\n===*===\n"); - printf("[DEBUG] row.date = %s\n", row.date); - printf("[DEBUG] row.open = %f\n", row.open); - printf("[DEBUG] row.high = %f\n", row.high); - printf("[DEBUG] row.low = %f\n", row.low); - printf("[DEBUG] row.close = %f\n", row.close); - printf("[DEBUG] row.volume = %d\n", row.volume); - - printf("[DEBUG] ti1 ti2 ti3 t_others = %f %f %f %s\n", row.technical_indicators.ti1, - row.technical_indicators.ti2, - row.technical_indicators.ti3, - row.technical_indicators.ti_others); + printf("[DEBUG] row->date = %s\n", row->date); + printf("[DEBUG] row->open = %f\n", row->open); + printf("[DEBUG] row->high = %f\n", row->high); + printf("[DEBUG] row->low = %f\n", row->low); + printf("[DEBUG] row->close = %f\n", row->close); + printf("[DEBUG] row->volume = %d\n", row->volume); + + printf("[DEBUG] ti1 ti2 ti3 t_others = %f %f %f %s\n", row->technical_indicators.ti1, + row->technical_indicators.ti2, + row->technical_indicators.ti3, + row->technical_indicators.ti_others); printf("\n===*===\n"); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index ecc0652..5385b76 100644 --- a/src/main.c +++ b/src/main.c @@ -3,10 +3,11 @@ #include #include #include "../include/dtypes.h" -#include "../include/misc.h" #include "../include/sim.h" #include "../include/sim_derivative.h" #include "../include/benchmark.h" +#include "../include/parser.h" +#include "../include/misc.h" #include "../include/debug.h" struct program_args @@ -34,7 +35,7 @@ struct program_args #include const char *argp_program_version = - "algoticks v1.5"; + "algoticks v2.0"; const char *argp_program_bug_address = ""; @@ -158,8 +159,6 @@ int main(int argc, char **argv) settings.debug_level = atoi(arguments.debug_level); } - strncpy(settings.socket_port, arguments.tcp_socket_port, 5); - if (arguments.derivative){ settings.is_derivative = true; } @@ -170,6 +169,7 @@ int main(int argc, char **argv) if (arguments.live_datasource_socket){ settings.is_live_data_socket = true; + settings.socket_port = (char*) malloc(5 * sizeof(char)); strncpy(settings.socket_port, arguments.tcp_socket_port, 5); } #endif @@ -180,11 +180,14 @@ int main(int argc, char **argv) run_benchmark(arguments.benchmark_f, settings); } else if(arguments.derivative || settings.is_derivative){ - run_sim_w_derivative(settings, config); + run_sim_w_derivative(&settings, &config); } else{ - run_sim(settings, config); + run_sim(&settings, &config); } - + + free_algoticks_config(&config); + free_algoticks_settings(&settings); + return 0; } \ No newline at end of file diff --git a/src/misc.c b/src/misc.c index 8f4a228..40cb7ee 100644 --- a/src/misc.c +++ b/src/misc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "../include/dtypes.h" #include "../include/debug.h" #include "../include/misc.h" @@ -11,12 +12,14 @@ #if defined(__linux__) || defined(__unix__) || defined(__APPLE__) #include -algoticks_cb_l load_cb(char *algo){ +algoticks_cb_l load_cb(char *cb){ void* handle; callback_func callback; - handle = dlopen(algo, RTLD_LAZY); + printf("%s\n", cb); + + handle = dlopen(cb, RTLD_LAZY); if (!handle) { @@ -160,37 +163,37 @@ void close_algo_func() { int simresult_file_header = false; char simresult_csv_header[1000] = "algo,pnl,datasource,derivative,symbol,candles,interval,target,stoploss,is_trailing_sl,trailing_sl_val,quantity,sliding,intraday,buy_signals,sell_signals,neutral_signals,trgt_hits,sl_hits,b_trgt_hits,s_trgt_hits,b_sl_hits,s_sl_hits,peak,bottom\n"; -void write_simresult_to_csv(algoticks_simresult simresult) +void write_simresult_to_csv(algoticks_simresult *simresult) { // config + sim result - char buffer[4000]; + char *buffer = (char*) malloc(4000 * sizeof(char)); sprintf(buffer, "%s,%f,%s,%s,%s,%d,%d,%f,%f,%d,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f\n", - simresult.config.algo, - simresult.pnl, - simresult.config.datasource, - simresult.config.derivative.derivative_datasource, - simresult.config.symbol, - simresult.config.candles, - simresult.config.interval, - simresult.config.target, - simresult.config.stoploss, - simresult.config.is_training_sl, - simresult.config.trailing_sl_val, - simresult.config.quantity, - simresult.config.sliding, - simresult.config.intraday, - simresult.buy_signals, - simresult.sell_signals, - simresult.neutral_signals, - simresult.trgt_hits, - simresult.sl_hits, - simresult.b_trgt_hits, - simresult.s_trgt_hits, - simresult.b_sl_hits, - simresult.s_sl_hits, - simresult.peak, - simresult.bottom); + simresult->config.algo, + simresult->pnl, + simresult->config.datasource, + simresult->config.derivative.derivative_datasource, + simresult->config.symbol, + simresult->config.candles, + simresult->config.interval, + simresult->config.target, + simresult->config.stoploss, + simresult->config.is_trailing_sl, + simresult->config.trailing_sl_val, + simresult->config.quantity, + simresult->config.sliding, + simresult->config.intraday, + simresult->buy_signals, + simresult->sell_signals, + simresult->neutral_signals, + simresult->trgt_hits, + simresult->sl_hits, + simresult->b_trgt_hits, + simresult->s_trgt_hits, + simresult->b_sl_hits, + simresult->s_sl_hits, + simresult->peak, + simresult->bottom); FILE *fp; if (simresult_file_header == false) { @@ -203,6 +206,7 @@ void write_simresult_to_csv(algoticks_simresult simresult) fp = fopen("results.csv", "a"); fprintf(fp, buffer); + free(buffer); fclose(fp); } @@ -220,491 +224,23 @@ int is_file_exists(const char *filename) return 0; } -void create_setting_config_benchmark_files(int type) -{ - - /* - type = 1 = settings.json - type = 2 = config.json - type = 3 = benchmark.json - */ - - char settings[1000] = "{ \n" - "\"print\": true,\n" - "\"colors\": true, \n" - "\"debug\": false, \n" - "\"debug_level\": 1, \n\n" - "\"intraday_hour\": 15, \n" - "\"intraday_min\": 15 \n }"; - - char config[1000] = "{\n" - #ifdef _WIN32 - "\"algo\": \"algorithms/Reds.dll\",\n" - #else - "\"algo\": \"algorithms/Reds.so\",\n" - #endif - "\"datasource\": \"example.csv\",\n" - "\"symbol\": \"EXAMPLE\", \n" - "\"candles\": 3, \n" - "\"interval\": 0, \n\n" - "\"quantity\": 100,\n" - "\"target\": 5, \n" - "\"stoploss\": 7, \n" - "\"is_training_sl\": false, \n" - "\"trailing_sl_val\": 1, \n\n" - "\"sliding\": true, \n" - "\"intraday\": false, \n" - "\"skip_header\": true \n}\n"; - - char benchmark[1000] = "{ \n" - #ifdef _WIN32 - "\"algo\": [\"algorithms/Greens.dll\", \"algorithms/Reds.dll\"],\n" - #else - "\"algo\": [\"algorithms/Greens.so\", \"algorithms/Reds.so\"],\n" - #endif - "\"datasource\": [\"example.csv\"],\n" - "\"symbol\": \"EXAMPLE\",\n" - "\"candles\": [4,6,8],\n" - "\"interval\": [5,10,15],\n\n" - "\"quantity\": [10],\n" - "\"target\": [1.5,2,2.5],\n" - "\"stoploss\": [2,2.5,3,3.5],\n" - "\"is_training_sl\": [true,false],\n" - "\"trailing_sl_val\": [1,2,3],\n\n" - "\"sliding\": [true,false],\n" - "\"intraday\": [true,false], \n" - "\"skip_header\": true \n }\n"; - - // write to file - - if (type == 1) - { - FILE *settingsf; - settingsf = fopen("settings.json", "w+"); - fprintf(settingsf, settings); - fclose(settingsf); - - printf("\nsettings.json created!\n"); - } - - else if (type == 2) - { - FILE *configf; - configf = fopen("config.json", "w+"); - fprintf(configf, config); - fclose(configf); - - printf("\nconfig.json created!\n"); - } - else if (type == 3) - { - FILE *benchf; - benchf = fopen("benchmark.json", "w+"); - fprintf(benchf, benchmark); - fclose(benchf); - - printf("\nbenchmark.json created!\n"); - } - -} - - -algoticks_settings parse_settings_from_json(char *filename) -{ - - - char buffer[4096]; - FILE *fp; - - fp = fopen(filename, "r"); - if (fp == NULL) - { - printf("cannot Read: %s \n", filename); - exit(1); - } - fread(buffer, 1024, 1, fp); - - struct json_object *parsed_json; - struct json_object *print; - struct json_object *colors; - - struct json_object *debug; - struct json_object *debug_level; - - struct json_object *derivative; - struct json_object *benchmark; - - struct json_object *config_f; - struct json_object *benchmark_f; - - struct json_object *is_live_data; - struct json_object *socket; - struct json_object *socket_port; - - struct json_object *intraday_hour; - struct json_object *intraday_min; - - struct Settings settings = {0}; - - parsed_json = json_tokener_parse(buffer); - - if (parsed_json == NULL){ - printf("Invalid JSON!\n"); - exit(1); - } - - json_object_object_get_ex(parsed_json, "print", &print); - json_object_object_get_ex(parsed_json, "colors", &colors); - json_object_object_get_ex(parsed_json, "debug", &debug); - json_object_object_get_ex(parsed_json, "debug_level", &debug_level); - - json_object_object_get_ex(parsed_json, "derivative", &derivative); - json_object_object_get_ex(parsed_json, "benchmark", &benchmark); - - json_object_object_get_ex(parsed_json, "config_f", &config_f); - json_object_object_get_ex(parsed_json, "benchmark_f", &benchmark_f); - - json_object_object_get_ex(parsed_json, "is_live_data", &is_live_data); - json_object_object_get_ex(parsed_json, "socket", &socket); - json_object_object_get_ex(parsed_json, "socket_port", &socket_port); - - json_object_object_get_ex(parsed_json, "intraday_hour", &intraday_hour); - json_object_object_get_ex(parsed_json, "intraday_min", &intraday_min); - - settings.print = json_object_get_boolean(print); - settings.colors = json_object_get_boolean(colors); - settings.debug = json_object_get_boolean(debug); - settings.debug_level = json_object_get_int(debug_level); - - settings.is_derivative = json_object_get_boolean(derivative); - settings.is_benchmark = json_object_get_boolean(benchmark); - - settings.is_live_data = json_object_get_boolean(is_live_data); - - settings.is_live_data_socket = json_object_get_boolean(socket); - strncpy(settings.socket_port, json_object_get_string(socket_port), 5); - - strncpy(settings.config_f, json_object_get_string(config_f), 512); - strncpy(settings.benchmark_f, json_object_get_string(benchmark_f), 512); - - settings.intraday_hour = json_object_get_int(intraday_hour); - settings.intraday_min = json_object_get_int(intraday_min); - - //close config file! - fclose(fp); - - //free json obj. - json_object_put(parsed_json); - - return settings; -} - -algoticks_config parse_config_from_json(char *filename) -{ - - - char buffer[4096]; - FILE *fp; - - fp = fopen(filename, "r"); - if (fp == NULL) - { - printf("cannot Read: %s \n", filename); - exit(1); - } - fread(buffer, 1024, 1, fp); - - struct json_object *parsed_json; - - struct json_object *algo; - struct json_object *datasource; - struct json_object *derivative; - struct json_object *symbol; - struct json_object *candles; - struct json_object *interval; - struct json_object *callbacks; - - struct json_object *target; - struct json_object *stoploss; - struct json_object *is_training_sl; - struct json_object *trailing_sl_val; - struct json_object *quantity; - - struct json_object *sliding; - struct json_object *intraday; - struct json_object *skip_header; - - struct json_object *tmp; - - struct Config config = {0}; - - parsed_json = json_tokener_parse(buffer); - - if (parsed_json == NULL){ - printf("Invalid JSON!\n"); - exit(1); - } - - json_object_object_get_ex(parsed_json, "algo", &algo); - json_object_object_get_ex(parsed_json, "datasource", &datasource); - json_object_object_get_ex(parsed_json, "symbol", &symbol); - json_object_object_get_ex(parsed_json, "candles", &candles); - json_object_object_get_ex(parsed_json, "interval", &interval); - json_object_object_get_ex(parsed_json, "target", &target); - json_object_object_get_ex(parsed_json, "stoploss", &stoploss); - json_object_object_get_ex(parsed_json, "is_training_sl", &is_training_sl); - json_object_object_get_ex(parsed_json, "trailing_sl_val", &trailing_sl_val); - json_object_object_get_ex(parsed_json, "quantity", &quantity); - json_object_object_get_ex(parsed_json, "sliding", &sliding); - json_object_object_get_ex(parsed_json, "intraday", &intraday); - json_object_object_get_ex(parsed_json, "skip_header", &skip_header); - - strncpy(config.algo, json_object_get_string(algo), 32); - strncpy(config.datasource, json_object_get_string(datasource), 512); - strncpy(config.symbol, json_object_get_string(symbol), 32); - config.candles = json_object_get_int(candles); - config.interval = json_object_get_int(interval); - config.quantity = json_object_get_int(quantity); - config.target = json_object_get_double(target); - config.stoploss = json_object_get_double(stoploss); - config.is_training_sl = json_object_get_boolean(is_training_sl); - config.trailing_sl_val = json_object_get_double(trailing_sl_val); - config.sliding = json_object_get_boolean(sliding); - config.intraday = json_object_get_boolean(intraday); - config.skip_header = json_object_get_boolean(skip_header); - - //parse derivative if exists. - int derivative_exists = json_object_object_get_ex(parsed_json, "derivative", &derivative); - - if (derivative_exists){ - struct json_object *derivative_datasource, *derivative_interval; - - int derivative_datasource_exists = json_object_object_get_ex(derivative, "derivative_datasource", &derivative_datasource); - if (derivative_datasource_exists){ - strncpy(config.derivative.derivative_datasource, json_object_get_string(derivative_datasource), 512); - } - - int derivative_interval_exists = json_object_object_get_ex(derivative, "derivative_interval", &derivative_interval); - - if (derivative_interval_exists) { - config.derivative.derivative_interval = json_object_get_int(derivative_interval); - } - - } - else{ - //set to None - strncpy(config.derivative.derivative_datasource, "None", 512); - - } - - //parse callbacks if exists. - int callbacks_exists = json_object_object_get_ex(parsed_json, "callbacks", &callbacks); - - if (callbacks_exists){ - config.n_callbacks = json_object_array_length(callbacks); - - for (int i = 0; i < config.n_callbacks; i++) - { - tmp = json_object_array_get_idx(callbacks, i); - strncpy(config.callbacks[i], json_object_get_string(tmp), 64); - } - } - - //close config file! - fclose(fp); - - //free json obj. - json_object_put(parsed_json); - - return config; -} - -algoticks_benchmarkconfig parse_benchmark_from_json(char *filename) -{ - - - - char buffer[4096]; - FILE *fp; - - fp = fopen(filename, "r"); - if (fp == NULL) - { - printf("cannot Read: %s \n", filename); - exit(1); - } - fread(buffer, 1024, 1, fp); - - struct json_object *parsed_json; - struct json_object *tmp; - - struct json_object *algo; - struct json_object *datasource; - struct json_object *derivative; - struct json_object *symbol; - struct json_object *interval; - - struct json_object *candles; - struct json_object *target; - struct json_object *stoploss; - struct json_object *is_training_sl; - struct json_object *trailing_sl_val; - struct json_object *quantity; - - struct json_object *sliding; - struct json_object *intraday; - struct json_object *skip_header; - - struct BenchmarkConfig benchmarkconfig = {0}; - - parsed_json = json_tokener_parse(buffer); - - json_object_object_get_ex(parsed_json, "algo", &algo); - json_object_object_get_ex(parsed_json, "datasource", &datasource); - json_object_object_get_ex(parsed_json, "symbol", &symbol); - json_object_object_get_ex(parsed_json, "candles", &candles); - json_object_object_get_ex(parsed_json, "interval", &interval); - json_object_object_get_ex(parsed_json, "target", &target); - json_object_object_get_ex(parsed_json, "stoploss", &stoploss); - json_object_object_get_ex(parsed_json, "is_training_sl", &is_training_sl); - json_object_object_get_ex(parsed_json, "trailing_sl_val", &trailing_sl_val); - json_object_object_get_ex(parsed_json, "quantity", &quantity); - json_object_object_get_ex(parsed_json, "sliding", &sliding); - json_object_object_get_ex(parsed_json, "intraday", &intraday); - json_object_object_get_ex(parsed_json, "skip_header", &skip_header); - - benchmarkconfig.n_algo = json_object_array_length(algo); - for (int i = 0; i < benchmarkconfig.n_algo; i++) - { - tmp = json_object_array_get_idx(algo, i); - strncpy(benchmarkconfig.algo[i], json_object_get_string(tmp), 32); - } - - benchmarkconfig.n_datasource = json_object_array_length(datasource); - for (int i = 0; i < benchmarkconfig.n_datasource; i++) - { - tmp = json_object_array_get_idx(datasource, i); - strncpy(benchmarkconfig.datasource[i], json_object_get_string(tmp), 512); - } - - strncpy(benchmarkconfig.symbol, json_object_get_string(symbol), 32); - - benchmarkconfig.n_candles = json_object_array_length(candles); - for (int i = 0; i < benchmarkconfig.n_candles; i++) - { - tmp = json_object_array_get_idx(candles, i); - benchmarkconfig.candles[i] = json_object_get_int(tmp); - } - - benchmarkconfig.n_interval = json_object_array_length(interval); - for (int i = 0; i < benchmarkconfig.n_interval; i++) - { - tmp = json_object_array_get_idx(interval, i); - benchmarkconfig.interval[i] = json_object_get_int(tmp); - } - - benchmarkconfig.n_target = json_object_array_length(target); - for (int i = 0; i < benchmarkconfig.n_target; i++) - { - tmp = json_object_array_get_idx(target, i); - benchmarkconfig.target[i] = json_object_get_double(tmp); - } - - benchmarkconfig.n_stoploss = json_object_array_length(stoploss); - for (int i = 0; i < benchmarkconfig.n_stoploss; i++) - { - tmp = json_object_array_get_idx(stoploss, i); - benchmarkconfig.stoploss[i] = json_object_get_double(tmp); - } - - benchmarkconfig.n_is_training_sl = json_object_array_length(is_training_sl); - for (int i = 0; i < benchmarkconfig.n_is_training_sl; i++) - { - tmp = json_object_array_get_idx(is_training_sl, i); - benchmarkconfig.is_training_sl[i] = json_object_get_boolean(tmp); - } - - benchmarkconfig.n_trailing_sl_val = json_object_array_length(trailing_sl_val); - for (int i = 0; i < benchmarkconfig.n_trailing_sl_val; i++) - { - tmp = json_object_array_get_idx(trailing_sl_val, i); - benchmarkconfig.trailing_sl_val[i] = json_object_get_double(tmp); - } - - benchmarkconfig.n_quantity = json_object_array_length(quantity); - for (int i = 0; i < benchmarkconfig.n_quantity; i++) - { - tmp = json_object_array_get_idx(quantity, i); - benchmarkconfig.quantity[i] = json_object_get_int(tmp); - } - - benchmarkconfig.n_sliding = json_object_array_length(sliding); - for (int i = 0; i < benchmarkconfig.n_sliding; i++) - { - tmp = json_object_array_get_idx(sliding, i); - benchmarkconfig.sliding[i] = json_object_get_boolean(tmp); - } - - benchmarkconfig.n_intraday = json_object_array_length(intraday); - for (int i = 0; i < benchmarkconfig.n_intraday; i++) - { - tmp = json_object_array_get_idx(intraday, i); - benchmarkconfig.intraday[i] = json_object_get_boolean(tmp); - } - - benchmarkconfig.skip_header = json_object_get_boolean(skip_header); - - //parse derivative if exists. - int derivative_exists = json_object_object_get_ex(parsed_json, "derivative", &derivative); - - if (derivative_exists){ - struct json_object *derivative_datasource, *derivative_interval; - - int derivative_datasource_exists = json_object_object_get_ex(derivative, "derivative_datasource", &derivative_datasource); - if (derivative_datasource_exists){ - strncpy(benchmarkconfig.derivative.derivative_datasource, json_object_get_string(derivative_datasource), 512); - } - - int derivative_interval_exists = json_object_object_get_ex(derivative, "derivative_interval", &derivative_interval); - - if (derivative_interval_exists) { - benchmarkconfig.derivative.derivative_interval = json_object_get_int(derivative_interval); - } - - } - else{ - //set to None - strncpy(benchmarkconfig.derivative.derivative_datasource, "None", 512); - - } - //close config file! - fclose(fp); - - //free json obj. - json_object_put(parsed_json); - - return benchmarkconfig; -} - -algoticks_config filter_boundaries(algoticks_config config, int is_short) +void filter_boundaries(algoticks_config *config, int is_short) { if (is_short == true) { - config.target = -(fabs(config.target)); - config.stoploss = fabs(config.stoploss); - config.trailing_sl_val = -(fabs(config.trailing_sl_val)); + config->target = -(fabs(config->target)); + config->stoploss = fabs(config->stoploss); + config->trailing_sl_val = -(fabs(config->trailing_sl_val)); } else { - config.target = fabs(config.target); - config.stoploss = -(fabs(config.stoploss)); - config.trailing_sl_val = fabs(config.trailing_sl_val); + config->target = fabs(config->target); + config->stoploss = -(fabs(config->stoploss)); + config->trailing_sl_val = fabs(config->trailing_sl_val); } - - return config; } //essential boundary checking fuctions @@ -795,4 +331,62 @@ void chomp(char *s) while (*s && *s != '\n' && *s != '\r') s++; *s = 0; +} + +void free_algoticks_config(algoticks_config *config){ + free(config->algo); + free(config->datasource); + free(config->symbol); + + if (config->derivative.derivative_datasource != NULL){ + free(config->derivative.derivative_datasource); + } + + + if (config->n_callbacks != 0) { + for (size_t i = 0; i < config->n_callbacks; i++) + { + free(config->callbacks[i]); + } + } + + +} + +void free_algoticks_settings(algoticks_settings *settings){ + free(settings->config_f); + free(settings->benchmark_f); + free(settings->socket_port); +} + +void free_algoticks_benchmark(algoticks_benchmarkconfig *benchmark){ + + free(benchmark->symbol); + + for (size_t i = 0; i < benchmark->n_algo; i++) + { + free(benchmark->algo_arr[i]); + } + free(benchmark->algo_arr); + + + for (size_t i = 0; i < benchmark->n_datasource; i++) + { + free(benchmark->datasource_arr[i]); + } + free(benchmark->datasource_arr); + + if (benchmark->derivative.derivative_datasource != NULL){ + free(benchmark->derivative.derivative_datasource); + } + + free(benchmark->candles_arr); + free(benchmark->interval_arr); + free(benchmark->target_arr); + free(benchmark->stoploss_arr); + free(benchmark->is_trailing_sl); + free(benchmark->trailing_sl_val_arr); + free(benchmark->quantity_arr); + free(benchmark->sliding); + free(benchmark->intraday); } \ No newline at end of file diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..ff44d05 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,484 @@ +#include +#include +#include +#include +#include +#include +#include "../include/dtypes.h" +#include "../include/debug.h" + +algoticks_settings parse_settings_from_json(char *filename) +{ + + + char buffer[4096]; + size_t len; + FILE *fp; + + fp = fopen(filename, "r"); + if (fp == NULL) + { + printf("cannot Read: %s \n", filename); + exit(1); + } + fread(buffer, 1024, 1, fp); + + struct json_object *parsed_json; + struct json_object *print; + struct json_object *colors; + + struct json_object *debug; + struct json_object *debug_level; + + struct json_object *derivative; + struct json_object *benchmark; + + struct json_object *config_f; + struct json_object *benchmark_f; + + struct json_object *is_live_data; + struct json_object *socket; + struct json_object *socket_port; + + struct json_object *intraday_hour; + struct json_object *intraday_min; + + struct Settings settings = {0}; + + parsed_json = json_tokener_parse(buffer); + + if (parsed_json == NULL){ + printf("Invalid JSON!\n"); + exit(1); + } + + json_object_object_get_ex(parsed_json, "print", &print); + json_object_object_get_ex(parsed_json, "colors", &colors); + json_object_object_get_ex(parsed_json, "debug", &debug); + json_object_object_get_ex(parsed_json, "debug_level", &debug_level); + + json_object_object_get_ex(parsed_json, "derivative", &derivative); + json_object_object_get_ex(parsed_json, "benchmark", &benchmark); + + json_object_object_get_ex(parsed_json, "config_f", &config_f); + json_object_object_get_ex(parsed_json, "benchmark_f", &benchmark_f); + + json_object_object_get_ex(parsed_json, "is_live_data", &is_live_data); + json_object_object_get_ex(parsed_json, "socket", &socket); + json_object_object_get_ex(parsed_json, "socket_port", &socket_port); + + json_object_object_get_ex(parsed_json, "intraday_hour", &intraday_hour); + json_object_object_get_ex(parsed_json, "intraday_min", &intraday_min); + + settings.print = json_object_get_boolean(print); + settings.colors = json_object_get_boolean(colors); + settings.debug = json_object_get_boolean(debug); + settings.debug_level = json_object_get_int(debug_level); + + settings.is_derivative = json_object_get_boolean(derivative); + settings.is_benchmark = json_object_get_boolean(benchmark); + + settings.is_live_data = json_object_get_boolean(is_live_data); + + settings.is_live_data_socket = json_object_get_boolean(socket); + + len = json_object_get_string_len(socket_port); + settings.socket_port = (char*) malloc((len+1) * sizeof(char)); + strcpy(settings.socket_port, json_object_get_string(socket_port)); + + len = json_object_get_string_len(config_f); + settings.config_f = (char*) malloc((len+1) * sizeof(char)); + strcpy(settings.config_f, json_object_get_string(config_f)); + + len = json_object_get_string_len(benchmark_f); + settings.benchmark_f = (char*) malloc((len+1) * sizeof(char)); + strcpy(settings.benchmark_f, json_object_get_string(benchmark_f)); + + + settings.intraday_hour = json_object_get_int(intraday_hour); + settings.intraday_min = json_object_get_int(intraday_min); + + //close config file! + fclose(fp); + + //free json obj. + json_object_put(parsed_json); + + return settings; +} + +algoticks_config parse_config_from_json(char *filename) +{ + + + char buffer[4096]; + size_t len; + FILE *fp; + + fp = fopen(filename, "r"); + if (fp == NULL) + { + printf("cannot Read: %s \n", filename); + exit(1); + } + fread(buffer, 1024, 1, fp); + + struct json_object *parsed_json; + + struct json_object *algo; + struct json_object *datasource; + struct json_object *derivative; + struct json_object *symbol; + struct json_object *candles; + struct json_object *interval; + struct json_object *callbacks; + + struct json_object *target; + struct json_object *stoploss; + struct json_object *is_training_sl; + struct json_object *trailing_sl_val; + struct json_object *quantity; + + struct json_object *sliding; + struct json_object *intraday; + struct json_object *skip_header; + + struct json_object *tmp; + + struct Config config = {0}; + + parsed_json = json_tokener_parse(buffer); + + if (parsed_json == NULL){ + printf("Invalid JSON!\n"); + exit(1); + } + + json_object_object_get_ex(parsed_json, "algo", &algo); + json_object_object_get_ex(parsed_json, "datasource", &datasource); + json_object_object_get_ex(parsed_json, "symbol", &symbol); + json_object_object_get_ex(parsed_json, "candles", &candles); + json_object_object_get_ex(parsed_json, "interval", &interval); + json_object_object_get_ex(parsed_json, "target", &target); + json_object_object_get_ex(parsed_json, "stoploss", &stoploss); + json_object_object_get_ex(parsed_json, "is_training_sl", &is_training_sl); + json_object_object_get_ex(parsed_json, "trailing_sl_val", &trailing_sl_val); + json_object_object_get_ex(parsed_json, "quantity", &quantity); + json_object_object_get_ex(parsed_json, "sliding", &sliding); + json_object_object_get_ex(parsed_json, "intraday", &intraday); + json_object_object_get_ex(parsed_json, "skip_header", &skip_header); + + + len = json_object_get_string_len(algo); + config.algo = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.algo, json_object_get_string(algo)); + + len = json_object_get_string_len(datasource); + config.datasource = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.datasource, json_object_get_string(datasource)); + + len = json_object_get_string_len(symbol); + config.symbol = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.symbol, json_object_get_string(symbol)); + + + + config.candles = json_object_get_int(candles); + config.interval = json_object_get_int(interval); + config.quantity = json_object_get_int(quantity); + config.target = json_object_get_double(target); + config.stoploss = json_object_get_double(stoploss); + config.is_trailing_sl = json_object_get_boolean(is_training_sl); + config.trailing_sl_val = json_object_get_double(trailing_sl_val); + config.sliding = json_object_get_boolean(sliding); + config.intraday = json_object_get_boolean(intraday); + config.skip_header = json_object_get_boolean(skip_header); + + //parse derivative if exists. + int derivative_exists = json_object_object_get_ex(parsed_json, "derivative", &derivative); + + if (derivative_exists){ + struct json_object *derivative_datasource, *derivative_interval; + + int derivative_datasource_exists = json_object_object_get_ex(derivative, "derivative_datasource", &derivative_datasource); + if (derivative_datasource_exists){ + + len = json_object_get_string_len(derivative_datasource); + config.derivative.derivative_datasource = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.derivative.derivative_datasource, json_object_get_string(derivative_datasource)); + + } + + int derivative_interval_exists = json_object_object_get_ex(derivative, "derivative_interval", &derivative_interval); + + if (derivative_interval_exists) { + config.derivative.derivative_interval = json_object_get_int(derivative_interval); + } + + } + else{ + //set to None + config.derivative.derivative_datasource = NULL; + config.derivative.derivative_interval = 0; + } + + //parse callbacks if exists. + int callbacks_exists = json_object_object_get_ex(parsed_json, "callbacks", &callbacks); + + if (callbacks_exists){ + config.n_callbacks = json_object_array_length(callbacks); + config.callbacks = (char**) malloc(config.n_callbacks * sizeof(char)); + assert (config.n_callbacks <= 6); + + for (int i = 0; i < config.n_callbacks; i++) + { + tmp = json_object_array_get_idx(callbacks, i); + len = json_object_get_string_len(tmp); + config.callbacks[i] = (char*) malloc((len+1) * sizeof(char)); + strcpy(config.callbacks[i], json_object_get_string(tmp)); + printf("%s\n", config.callbacks[i]); + } + } + else{ + config.n_callbacks = 0; + } + + //close config file! + fclose(fp); + + //free json obj. + json_object_put(parsed_json); + + return config; +} + +algoticks_benchmarkconfig parse_benchmark_from_json(char *filename) +{ + + + + char buffer[4096]; + size_t len; + FILE *fp; + + fp = fopen(filename, "r"); + if (fp == NULL) + { + printf("cannot Read: %s \n", filename); + exit(1); + } + fread(buffer, 1024, 1, fp); + + struct json_object *parsed_json; + struct json_object *tmp; + + struct json_object *algo; + struct json_object *datasource; + struct json_object *derivative; + struct json_object *symbol; + struct json_object *interval; + + struct json_object *candles; + struct json_object *target; + struct json_object *stoploss; + struct json_object *is_trailing_sl; + struct json_object *trailing_sl_val; + struct json_object *quantity; + + struct json_object *sliding; + struct json_object *intraday; + struct json_object *skip_header; + + struct BenchmarkConfig benchmarkconfig = {0}; + + parsed_json = json_tokener_parse(buffer); + + json_object_object_get_ex(parsed_json, "algo", &algo); + json_object_object_get_ex(parsed_json, "datasource", &datasource); + json_object_object_get_ex(parsed_json, "symbol", &symbol); + json_object_object_get_ex(parsed_json, "candles", &candles); + json_object_object_get_ex(parsed_json, "interval", &interval); + json_object_object_get_ex(parsed_json, "target", &target); + json_object_object_get_ex(parsed_json, "stoploss", &stoploss); + json_object_object_get_ex(parsed_json, "is_trailing_sl", &is_trailing_sl); + json_object_object_get_ex(parsed_json, "trailing_sl_val", &trailing_sl_val); + json_object_object_get_ex(parsed_json, "quantity", &quantity); + json_object_object_get_ex(parsed_json, "sliding", &sliding); + json_object_object_get_ex(parsed_json, "intraday", &intraday); + json_object_object_get_ex(parsed_json, "skip_header", &skip_header); + + len = json_object_get_string_len(symbol); + benchmarkconfig.symbol = (char*) malloc((len+1) * sizeof(char)); + strcpy(benchmarkconfig.symbol, json_object_get_string(symbol)); + + benchmarkconfig.n_algo = json_object_array_length(algo); + benchmarkconfig.algo_arr = (char**) malloc(benchmarkconfig.n_algo * sizeof(char)); + + for (size_t i = 0; i < benchmarkconfig.n_algo; i++) + { + tmp = json_object_array_get_idx(algo, i); + len = json_object_get_string_len(tmp); + benchmarkconfig.algo_arr[i] = (char*) malloc((len+1) * sizeof(char)); + strcpy(benchmarkconfig.algo_arr[i], json_object_get_string(tmp)); + } + + + benchmarkconfig.n_datasource = json_object_array_length(datasource); + benchmarkconfig.datasource_arr = (char**) malloc(benchmarkconfig.n_datasource * sizeof(char)); + + for (size_t i = 0; i < benchmarkconfig.n_datasource; i++) + { + tmp = json_object_array_get_idx(datasource, i); + len = json_object_get_string_len(tmp); + benchmarkconfig.datasource_arr[i] = (char*) malloc((len+1) * sizeof(char)); + strcpy(benchmarkconfig.datasource_arr[i], json_object_get_string(tmp)); + } + + /* DERIVATIVE */ + int derivative_exists = json_object_object_get_ex(parsed_json, "derivative", &derivative); + + if (derivative_exists){ + struct json_object *derivative_datasource, *derivative_interval; + + int derivative_datasource_exists = json_object_object_get_ex(derivative, "derivative_datasource", &derivative_datasource); + if (derivative_datasource_exists){ + + len = json_object_get_string_len(derivative_datasource); + benchmarkconfig.derivative.derivative_datasource = (char*) malloc((len+1) * sizeof(char)); + strcpy(benchmarkconfig.derivative.derivative_datasource, json_object_get_string(derivative_datasource)); + + } + + int derivative_interval_exists = json_object_object_get_ex(derivative, "derivative_interval", &derivative_interval); + + if (derivative_interval_exists) { + benchmarkconfig.derivative.derivative_interval = json_object_get_int(derivative_interval); + } + + } + else{ + //set to None + benchmarkconfig.derivative.derivative_datasource = NULL; + benchmarkconfig.derivative.derivative_interval = 0; + } + + /* CANDLES */ + benchmarkconfig.n_candles = json_object_array_length(candles); + benchmarkconfig.candles_arr = (int*) malloc(benchmarkconfig.n_candles * sizeof(int)); + + for (size_t i = 0; i < benchmarkconfig.n_candles; i++) + { + tmp = json_object_array_get_idx(candles, i); + len = json_object_get_string_len(tmp); + benchmarkconfig.candles_arr[i] = json_object_get_int(tmp); + } + + /* INTERVAL */ + benchmarkconfig.n_interval = json_object_array_length(interval); + benchmarkconfig.interval_arr = (int*) malloc(benchmarkconfig.n_interval * sizeof(int)); + + for (size_t i = 0; i < benchmarkconfig.n_interval; i++) + { + tmp = json_object_array_get_idx(interval, i); + benchmarkconfig.interval_arr[i] = json_object_get_int(tmp); + } + + + /* TARGET */ + + benchmarkconfig.n_target = json_object_array_length(target); + benchmarkconfig.target_arr = (double*) malloc(benchmarkconfig.n_target * sizeof(double)); + + for (size_t i = 0; i < benchmarkconfig.n_target; i++) + { + tmp = json_object_array_get_idx(target, i); + benchmarkconfig.target_arr[i] = json_object_get_double(tmp); + } + + + /* STOPLOSS */ + + benchmarkconfig.n_stoploss = json_object_array_length(stoploss); + benchmarkconfig.stoploss_arr = (double*) malloc(benchmarkconfig.n_stoploss * sizeof(double)); + + for (size_t i = 0; i < benchmarkconfig.n_stoploss; i++) + { + tmp = json_object_array_get_idx(stoploss, i); + benchmarkconfig.stoploss_arr[i] = json_object_get_double(tmp); + } + + /* TRAILING SL */ + + len = json_object_array_length(is_trailing_sl); + benchmarkconfig.n_is_trailing_sl = len; + bool trailing_sl_true; + benchmarkconfig.is_trailing_sl = (int*) malloc(len * sizeof(int)); + for (size_t i = 0; i < len; i++) + { + tmp = json_object_array_get_idx(is_trailing_sl, i); + benchmarkconfig.is_trailing_sl[i] = json_object_get_boolean(tmp); + + if (benchmarkconfig.is_trailing_sl[i] == true){ + trailing_sl_true = true; + } + } + + + if (trailing_sl_true){ + benchmarkconfig.n_trailing_sl_val = json_object_array_length(trailing_sl_val); + benchmarkconfig.trailing_sl_val_arr = (double*) malloc(benchmarkconfig.n_trailing_sl_val * sizeof(double)); + + for (size_t i = 0; i < benchmarkconfig.n_trailing_sl_val; i++) + { + tmp = json_object_array_get_idx(trailing_sl_val, i); + benchmarkconfig.trailing_sl_val_arr[i] = json_object_get_double(tmp); + } + + } + + /* QUANTITY */ + + benchmarkconfig.n_quantity = json_object_array_length(quantity); + benchmarkconfig.quantity_arr = (int*) malloc(benchmarkconfig.n_quantity* sizeof(int)); + + for (size_t i = 0; i < benchmarkconfig.n_quantity; i++) + { + tmp = json_object_array_get_idx(quantity, i); + benchmarkconfig.quantity_arr[i] = json_object_get_int(tmp); + } + + + /* SLIDING */ + + len = json_object_array_length(sliding); + benchmarkconfig.n_sliding = len; + benchmarkconfig.sliding = (int*) malloc(len * sizeof(int)); + for (size_t i = 0; i < len; i++) + { + tmp = json_object_array_get_idx(sliding, i); + benchmarkconfig.sliding[i] = json_object_get_boolean(tmp); + } + + /* INTRADAY */ + + len = json_object_array_length(intraday); + benchmarkconfig.n_intraday = len; + benchmarkconfig.intraday = (int*) malloc(len * sizeof(int)); + for (size_t i = 0; i < len; i++) + { + tmp = json_object_array_get_idx(intraday, i); + benchmarkconfig.intraday[i] = json_object_get_boolean(tmp); + } + + /* SKIP_HEADER */ + + benchmarkconfig.skip_header = json_object_get_boolean(skip_header); + + //close config file! + fclose(fp); + + //free json obj. + json_object_put(parsed_json); + + return benchmarkconfig; +} \ No newline at end of file diff --git a/src/sim.c b/src/sim.c index cfcb08a..50f4a05 100644 --- a/src/sim.c +++ b/src/sim.c @@ -13,17 +13,17 @@ #include "../include/callbacks.h" -algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config){ +algoticks_simresult run_sim(algoticks_settings *settings, algoticks_config *config){ // open and read CSV file. FILE *fp; - fp = fopen(config.datasource, "rb"); + fp = fopen(config->datasource, "rb"); int curr = 0; // exit if file cannot be opened. if (fp == NULL) { - printf("cannot Read datasource: %s \n", config.datasource); + printf("cannot Read datasource: %s \n", config->datasource); exit(1); } @@ -32,49 +32,49 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config struct SimResult simresult = {0}; struct PositionResult positionresult = {0}; - //add config to simresult - simresult.config = config; + //add config to simresult. required for writing result to csv. + simresult.config = *config; - algo_func analyze = load_algo_func(config.algo); + algo_func analyze = load_algo_func(config->algo); load_callbacks(config); //initialize and malloc for series struct Row* series; - series = (algoticks_row*)malloc((config.candles) * sizeof(algoticks_row)); + series = (algoticks_row*) malloc((config->candles) * sizeof(algoticks_row)); while (curr != EOF) { - for (int i = 0; i < config.candles && curr != -1; i++) + for (int i = 0; i < config->candles && curr != -1; i++) { - curr = read_csv(settings,config, fp, config.datasource, &series[i], curr); - debug_msg(settings, 3, "SeriesRow", "sim.c", series[i].date); + curr = read_csv(settings, config, fp, config->datasource, &series[i], curr); + debug_msg(settings->debug, settings->debug_level, 3, __FILE__, __FUNCTION__, __LINE__, series[i].date); } if (curr == -1){ break; } - curr = read_csv(settings, config, fp, config.datasource, &storage, curr); + curr = read_csv(settings, config, fp, config->datasource, &storage, curr); struct Signal signal; - signal = analyze(series, config.candles); + signal = analyze(series, config->candles); if (signal.buy == true) { simresult.buy_signals += 1; - debug_msg(settings, 1, "signal", "sim.c", "Buy"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Buy"); } else if (signal.sell == true) { simresult.sell_signals += 1; - debug_msg(settings, 1, "signal", "sim.c", "Sell"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Sell"); } else if (signal.neutral == true) { simresult.neutral_signals += 1; - debug_msg(settings, 3, "signal", "sim.c", "Neutral"); + debug_msg(settings->debug, settings->debug_level, 2, __FILE__, __FUNCTION__, __LINE__, "Neutral"); } else { @@ -85,13 +85,12 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config if (signal.neutral != true) { { - algoticks_event ev={0}; - ev.signal = signal; + algoticks_event ev = make_event_from_signal(signal); send_callbacks(ev); } - if (config.intraday == true){ - if (is_date_over_or_eq_intraday(storage.date, settings.intraday_hour, settings.intraday_min) == true){ + if (config->intraday == true){ + if (is_date_over_or_eq_intraday(storage.date, settings->intraday_hour, settings->intraday_min) == true){ continue; } } @@ -116,20 +115,22 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config simresult.trgt_hits += 1; if (signal.buy == true){ simresult.b_trgt_hits += 1; } else if (signal.sell == true){ simresult.s_trgt_hits += 1; } - {algoticks_event ev={0}; ev.t_h=true; ev.pnl = simresult.pnl; send_callbacks(ev);} } else if (strcmp(positionresult.hit_type, "SL") == 0) { simresult.sl_hits += 1; if (signal.buy == true){ simresult.b_sl_hits += 1; } else if (signal.sell == true){ simresult.s_sl_hits += 1; } - {algoticks_event ev={0}; ev.sl_h=true; ev.pnl = simresult.pnl; send_callbacks(ev);} } else { - debug_msg(settings, 1, "Hit", "sim.c", "Position did not hit any boundary"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Position did not hit any boundary"); } + //send callback + algoticks_event ev = make_event_from_positionresult(positionresult); + send_callbacks(ev); + if (positionresult.eof == true) { break; @@ -143,7 +144,7 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config } // -1 from back +1 from front. easy way to do it it set curr to 1st index of series. - if (config.sliding == true && (config.candles > 2) == true){ + if (config->sliding == true && (config->candles > 2) == true){ if (curr != -1){ curr = series[0].curr; } @@ -153,7 +154,7 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config memset(&storage, 0, sizeof(storage)); //zero out series - for (int i = 0; i < config.candles; i++) + for (int i = 0; i < config->candles; i++) { memset(&series[i], 0, sizeof(series[i])); } @@ -161,8 +162,7 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config //print simresult.pnl char pnl[32]; sprintf(pnl, "%f", simresult.pnl); - debug_msg(settings, 1, "SimPnl", "sim.c", pnl); - + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, pnl); } //close datasource file. @@ -175,11 +175,12 @@ algoticks_simresult run_sim(algoticks_settings settings, algoticks_config config //free series mem. free(series); - write_simresult_to_csv(simresult); + write_simresult_to_csv(&simresult); + return simresult; } -algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int curr, algoticks_settings settings, algoticks_config config, algoticks_row lastrow){ +algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int curr, algoticks_settings *settings, algoticks_config *config, algoticks_row lastrow){ //declare buffer for debug messages char *debug_msg_buffer; @@ -192,7 +193,7 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu //set dashboard values dashboard.a = lastrow.close; - dashboard.q = config.quantity; + dashboard.q = config->quantity; if (signal.buy == true) { @@ -209,7 +210,7 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu } //filter targets - config = filter_boundaries(config, dashboard.is_short); + filter_boundaries(config, dashboard.is_short); struct Row pos_storage; @@ -220,11 +221,11 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu if (curr == EOF || curr == -1) { - if (settings.debug) + if (settings->debug) { - debug_msg(settings, 1, "EOF", "sim.c", config.datasource); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, config->datasource); sprintf(debug_msg_buffer, "%d", curr); - debug_msg(settings, 2, "fp_curr", "sim.c", debug_msg_buffer); + debug_msg(settings->debug, settings->debug_level, 2, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); } positionresult.pnl = getPnL(dashboard); @@ -241,7 +242,7 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu break; } - curr = read_csv(settings,config, fp, config.datasource, &pos_storage, curr); + curr = read_csv(settings,config, fp, config->datasource, &pos_storage, curr); if ((pos_storage.date == NULL) || (pos_storage.close == 0)) { @@ -252,23 +253,22 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu strncpy(dashboard.date, pos_storage.date, 32); positionresult.curr = curr; - if (settings.print == true) + if (settings->print == true) { print_dashboard(settings, config, dashboard); } //intraday check condition. - if (config.intraday) + if (config->intraday) { //check if over intraday squareoff time! - int intraday_check = is_date_over_or_eq_intraday(pos_storage.date, settings.intraday_min, settings.intraday_hour); + int intraday_check = is_date_over_or_eq_intraday(pos_storage.date, settings->intraday_min, settings->intraday_hour); if (intraday_check == true) { - //debug msg - sprintf(debug_msg_buffer, "H: %d S: %d Date: %s", settings.intraday_hour, settings.intraday_min, pos_storage.date); - debug_msg(settings, 2, "intraday_squareoff", "sim.c", debug_msg_buffer); + sprintf(debug_msg_buffer, "H: %d S: %d Date: %s", settings->intraday_hour, settings->intraday_min, pos_storage.date); + debug_msg(settings->debug, settings->debug_level, 2, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); positionresult.pnl = getPnL(dashboard); @@ -285,28 +285,28 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu } } - if (is_target_hit(dashboard, config.target) == true) + if (is_target_hit(dashboard, config->target) == true) { - debug_msg(settings, 1, "Hit", "sim.c", "Target Hit!"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Target Hit!"); strncpy(positionresult.hit_type, "T", 4); positionresult.pnl = getPnL(dashboard); - if (config.is_training_sl) + if (config->is_trailing_sl) { - config.target = (dashboard.b - dashboard.a) + config.trailing_sl_val; + config->target = (dashboard.b - dashboard.a) + config->trailing_sl_val; if (dashboard.is_short) { - config.stoploss += config.trailing_sl_val; + config->stoploss += config->trailing_sl_val; } else { - config.stoploss -= -config.trailing_sl_val; + config->stoploss -= -config->trailing_sl_val; } - sprintf(debug_msg_buffer, "T:%f SL:%f", config.target, config.stoploss); - debug_msg(settings, 1, "TSL_Adjust", "sim.c", debug_msg_buffer); + sprintf(debug_msg_buffer, "T:%f SL:%f", config->target, config->stoploss); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); continue; } @@ -314,9 +314,9 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu break; } - if (is_stoploss_hit(dashboard, config.stoploss) == true) + if (is_stoploss_hit(dashboard, config->stoploss) == true) { - debug_msg(settings, 1, "Hit", "sim.c", "SL Hit!"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "SL Hit!"); positionresult.pnl = getPnL(dashboard); @@ -332,16 +332,11 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu break; } - { + //send callback from pos - algoticks_event ev = {0}; - ev.from_pos = true; - strncpy(ev.date, pos_storage.date, 64); - ev.a = dashboard.a; - ev.b = dashboard.b; - ev.pnl = getPnL(dashboard); + algoticks_event ev = make_event_from_position(pos_storage, dashboard); send_callbacks(ev); - } + //zero out pos_stotage memset(&pos_storage, 0, sizeof(pos_storage)); @@ -349,7 +344,7 @@ algoticks_positionresult take_position(algoticks_signal signal, FILE *fp, int cu if (positionresult.n_steps > 0){ sprintf(debug_msg_buffer, "%f", positionresult.pnl); - debug_msg(settings, 1, "PosPnl", "sim.c", debug_msg_buffer); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); } free(debug_msg_buffer); diff --git a/src/sim_derivative.c b/src/sim_derivative.c index 7a5f0ac..01ed56f 100644 --- a/src/sim_derivative.c +++ b/src/sim_derivative.c @@ -14,82 +14,83 @@ int curr_i = 0; int curr_d = 0; -char index_datasource[64]; +char *index_datasource_ptr; +char *derivative_datasource_ptr; -algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_config config) +algoticks_simresult run_sim_w_derivative(algoticks_settings *settings, algoticks_config *config) { - strncpy(index_datasource, config.datasource, 64); + index_datasource_ptr = config->datasource; + derivative_datasource_ptr = config->derivative.derivative_datasource; // open and read CSV file. FILE *index; - index = fopen(config.datasource, "rb"); + index = fopen(config->datasource, "rb"); // exit if file cannot be opened. if (index == NULL) { - printf("cannot read datasource: %s \n", config.datasource); + printf("cannot read datasource: %s \n", config->datasource); exit(1); } // open and read CSV file. FILE *derivative; - derivative = fopen(config.derivative.derivative_datasource, "rb"); + derivative = fopen(config->derivative.derivative_datasource, "rb"); // exit if file cannot be opened. if (derivative == NULL) { - printf("cannot read derivative datasource: %s \n", config.derivative.derivative_datasource); + printf("cannot read derivative datasource: %s \n", config->derivative.derivative_datasource); exit(1); } - struct Row storage; - + struct Row storage = {0}; struct SimResult simresult = {0}; - //add config to simresult - simresult.config = config; + //add config to simresult. required for writing result to csv. + simresult.config = *config; - algo_func analyze = load_algo_func(config.algo); + algo_func analyze = load_algo_func(config->algo); load_callbacks(config); //initialize and malloc for series struct Row *series; - series = (algoticks_row *)malloc((config.candles) * sizeof(algoticks_row)); + series = (algoticks_row *)malloc((config->candles) * sizeof(algoticks_row)); while (curr_i != EOF) - { + { - for (int i = 0; i < config.candles && curr_i != -1; i++) + for (int i = 0; i < config->candles && curr_i != -1; i++) { - curr_i = read_csv(settings, config, index, config.datasource, &series[i], curr_i); - debug_msg(settings, 3, "SeriesRow", "sim_derivative.c", series[i].date); + curr_i = read_csv(settings, config, index, config->datasource, &series[i], curr_i); + debug_msg(settings->debug, settings->debug_level, 3, __FILE__, __FUNCTION__, __LINE__, series[i].date); } - curr_i = read_csv(settings, config, index, config.datasource, &storage, curr_i); + curr_i = read_csv(settings, config, index, config->datasource, &storage, curr_i); - if (curr_i == -1){ + if (curr_i == -1) + { break; } - struct Signal signal; - signal = analyze(series, config.candles); + signal = analyze(series, config->candles); if (signal.buy == true) { simresult.buy_signals += 1; - debug_msg(settings, 1, "signal", "sim_derivative.c", "Buy"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Buy"); } else if (signal.sell == true) { simresult.sell_signals += 1; - debug_msg(settings, 1, "signal", "sim_derivative.c", "Sell"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Sell"); } else if (signal.neutral == true) { simresult.neutral_signals += 1; - debug_msg(settings, 3, "signal", "sim_derivative.c", "Neutral"); + debug_msg(settings->debug, settings->debug_level, 2, __FILE__, __FUNCTION__, __LINE__, "Neutral"); } else { @@ -101,16 +102,15 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ { { - algoticks_event ev={0}; - ev.signal = signal; + algoticks_event ev = make_event_from_signal(signal); send_callbacks(ev); } struct PositionResult positionresult = {0}; - if (config.intraday == true) + if (config->intraday == true) { - if (is_date_over_or_eq_intraday(storage.date, settings.intraday_hour, settings.intraday_min) == true) + if (is_date_over_or_eq_intraday(storage.date, settings->intraday_hour, settings->intraday_min) == true) { continue; } @@ -142,7 +142,6 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ { simresult.s_trgt_hits += 1; } - {algoticks_event ev={0}; ev.t_h=true; ev.pnl = simresult.pnl; send_callbacks(ev);} } else if (strcmp(positionresult.hit_type, "SL") == 0) { @@ -155,13 +154,16 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ { simresult.s_sl_hits += 1; } - {algoticks_event ev={0}; ev.sl_h=true; ev.pnl = simresult.pnl; send_callbacks(ev);} } else { - debug_msg(settings, 1, "Hit", "sim_derivative.c", "Position did not hit any boundary"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Position did not hit any boundary"); } + //send callback + algoticks_event ev = make_event_from_positionresult(positionresult); + send_callbacks(ev); + if (positionresult.eof == true) { break; @@ -175,7 +177,7 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ } // -1 from back +1 from front. easy way to do it it set curr to 1st index of series. - if (config.sliding == true && (config.candles > 2) == true) + if (config->sliding == true && (config->candles > 2) == true) { if (curr_i != -1) { @@ -187,7 +189,7 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ memset(&storage, 0, sizeof(storage)); //zero out series - for (int i = 0; i < config.candles; i++) + for (int i = 0; i < config->candles; i++) { memset(&series[i], 0, sizeof(series[i])); } @@ -195,7 +197,7 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ //print simresult.pnl char pnl[32]; sprintf(pnl, "%f", simresult.pnl); - debug_msg(settings, 1, "SimPnl", "sim_derivative.c", pnl); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, pnl); } //close datasource(s) file. @@ -212,15 +214,16 @@ algoticks_simresult run_sim_w_derivative(algoticks_settings settings, algoticks_ curr_i = 0; curr_d = 0; - write_simresult_to_csv(simresult); + write_simresult_to_csv(&simresult); + return simresult; } -algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FILE *index_f, FILE *derivative_f, algoticks_settings settings, algoticks_config config, algoticks_row lastrow) +algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FILE *index_f, FILE *derivative_f, algoticks_settings *settings, algoticks_config *config, algoticks_row lastrow) { //declare buffer for debug messages char *debug_msg_buffer; - debug_msg_buffer = (char*)malloc(512 * sizeof(char)); + debug_msg_buffer = (char *)malloc(512 * sizeof(char)); struct Row pos_storage; @@ -230,23 +233,21 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL struct Dashboard dashboard; //reset curr that matches derivate - curr_d = sync_curr(settings, config, derivative_f, config.derivative.derivative_datasource, lastrow.date, curr_d, settings.debug); - if (curr_d == -1){ - printf("Error: Date:%s NIF %s\n", lastrow.date, config.derivative.derivative_datasource); + curr_d = sync_curr(settings, config, derivative_f, config->derivative.derivative_datasource, lastrow.date, curr_d, settings->debug); + if (curr_d == -1) + { + printf("Error: %s not in file %s", lastrow.date, config->derivative.derivative_datasource); positionresult.eof = true; return positionresult; } - curr_d = read_csv(settings, config, derivative_f, config.derivative.derivative_datasource, &pos_storage, curr_d); - + curr_d = read_csv(settings, config, derivative_f, config->derivative.derivative_datasource, &pos_storage, curr_d); - // swap datasource with derivative_datasource. - strncpy(config.datasource, config.derivative.derivative_datasource, 512); + config->datasource = derivative_datasource_ptr; //set required details in dashboard dashboard.a = pos_storage.close; - dashboard.q = config.quantity; - + dashboard.q = config->quantity; if (signal.buy == true) { @@ -263,7 +264,7 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL } //filter targets - config = filter_boundaries(config, dashboard.is_short); + filter_boundaries(config, dashboard.is_short); // infinite loop while (true) @@ -272,11 +273,11 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL if (curr_d == EOF || curr_d == -1) { - if (settings.debug) + if (settings->debug) { - debug_msg(settings, 1, "EOF", "sim_derivative.c", config.datasource); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, config->datasource); sprintf(debug_msg_buffer, "%d", curr_d); - debug_msg(settings, 2, "derivative_curr", "sim_derivative.c", debug_msg_buffer); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); } positionresult.pnl = getPnL(dashboard); @@ -293,7 +294,7 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL break; } - curr_d = read_csv(settings, config, derivative_f, config.derivative.derivative_datasource, &pos_storage, curr_d); + curr_d = read_csv(settings, config, derivative_f, config->derivative.derivative_datasource, &pos_storage, curr_d); if ((pos_storage.date == NULL) || (pos_storage.close == 0)) { @@ -304,23 +305,22 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL strncpy(dashboard.date, pos_storage.date, 32); positionresult.curr = curr_d; - if (settings.print == true) + if (settings->print == true) { print_dashboard(settings, config, dashboard); } //intraday check condition. - if (config.intraday) + if (config->intraday) { //check if over intraday squareoff time! - int intraday_check = is_date_over_or_eq_intraday(pos_storage.date, settings.intraday_min, settings.intraday_hour); + int intraday_check = is_date_over_or_eq_intraday(pos_storage.date, settings->intraday_min, settings->intraday_hour); if (intraday_check == true) { - //debug msg - sprintf(debug_msg_buffer, "H: %d S: %d Date: %s", settings.intraday_hour, settings.intraday_min, pos_storage.date); - debug_msg(settings, 2, "intraday_squareoff", "sim_derivative.c", debug_msg_buffer); + sprintf(debug_msg_buffer, "H: %d S: %d Date: %s", settings->intraday_hour, settings->intraday_min, pos_storage.date); + debug_msg(settings->debug, settings->debug_level, 2, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); positionresult.pnl = getPnL(dashboard); @@ -337,28 +337,28 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL } } - if (is_target_hit(dashboard, config.target) == true) + if (is_target_hit(dashboard, config->target) == true) { - debug_msg(settings, 1, "Hit", "sim_derivative.c", "Target Hit!"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "Target Hit!"); strncpy(positionresult.hit_type, "T", 4); positionresult.pnl = getPnL(dashboard); - if (config.is_training_sl) + if (config->is_trailing_sl) { - config.target = (dashboard.b - dashboard.a) + config.trailing_sl_val; + config->target = (dashboard.b - dashboard.a) + config->trailing_sl_val; if (dashboard.is_short) { - config.stoploss += config.trailing_sl_val; + config->stoploss += config->trailing_sl_val; } else { - config.stoploss -= -config.trailing_sl_val; + config->stoploss -= -config->trailing_sl_val; } - sprintf(debug_msg_buffer, "T:%f SL:%f", config.target, config.stoploss); - debug_msg(settings, 1, "TSL_Adjust", "sim_derivative.c", debug_msg_buffer); + sprintf(debug_msg_buffer, "T:%f SL:%f", config->target, config->stoploss); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); continue; } @@ -366,9 +366,9 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL break; } - if (is_stoploss_hit(dashboard, config.stoploss) == true) + if (is_stoploss_hit(dashboard, config->stoploss) == true) { - debug_msg(settings, 1, "Hit", "sim_derivative.c", "SL Hit!"); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, "SL Hit!"); positionresult.pnl = getPnL(dashboard); @@ -385,15 +385,10 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL } { - //send callback from pos - algoticks_event ev = {0}; - ev.from_pos = true; - strncpy(ev.date, pos_storage.date, 64); - ev.a = dashboard.a; - ev.b = dashboard.b; - ev.pnl = getPnL(dashboard); - send_callbacks(ev); - } + //send callback from pos + algoticks_event ev = make_event_from_position(pos_storage, dashboard); + send_callbacks(ev); + } //zero out pos_stotage memset(&pos_storage, 0, sizeof(pos_storage)); @@ -402,21 +397,23 @@ algoticks_positionresult take_position_w_derivative(algoticks_signal signal, FIL if (positionresult.n_steps > 0) { sprintf(debug_msg_buffer, "%f", positionresult.pnl); - debug_msg(settings, 1, "PosPnl", "sim_derivative.c", debug_msg_buffer); + debug_msg(settings->debug, settings->debug_level, 1, __FILE__, __FUNCTION__, __LINE__, debug_msg_buffer); } - //reset curr that matches index - curr_i = sync_curr(settings, config, index_f, index_datasource, pos_storage.date, curr_i, settings.debug); - if (curr_i == -1 && check_row_integrity(&lastrow) == false){ - printf("Error: %s not found in %s\n", pos_storage.date, index_datasource); + curr_i = sync_curr(settings, config, index_f, index_datasource_ptr, pos_storage.date, curr_i, settings->debug); + if (curr_i == -1 && check_row_integrity(&lastrow) == false) + { + printf("Error: %s not found in %s\n", pos_storage.date, index_datasource_ptr); positionresult.eof = true; } - else{ - positionresult.curr = curr_i; + else + { + positionresult.curr = curr_i; } - + free(debug_msg_buffer); positionresult.lastrow = pos_storage; + config->datasource = index_datasource_ptr; return positionresult; } \ No newline at end of file diff --git a/src/timeutils.c b/src/timeutils.c index 396c3d5..7a21a80 100644 --- a/src/timeutils.c +++ b/src/timeutils.c @@ -6,7 +6,9 @@ #include "../include/dtypes.h" #include "../include/csvutils.h" #include "../include/timeutils.h" +#include "../include/debug.h" +char debug_buffer[512]; const char *strp_format_1 = "%Y-%m-%d %H:%M:%S"; const char *scanf_format_notime = "%4d-%2d-%2d"; const char *scanf_time_format_1 = "%4d-%2d-%2d %2d:%2d:%2d"; @@ -18,7 +20,7 @@ const char *scanf_time_format_2 = "%4d/%2d/%2d %2d:%2d:%2d"; int is_date_over_or_eq_intraday(char *date, int intraday_hour, int intraday_min) { - struct tm date_ts; + struct tm date_ts = {0}; #ifdef _WIN32 if (!get_time_with_sscanf_from_string(date, &date_ts)) @@ -52,8 +54,8 @@ int is_date_over_or_eq_intraday(char *date, int intraday_hour, int intraday_min) int is_date_after(char *date_a, char *date_b) { - struct tm date_a_ts; - struct tm date_b_ts; + struct tm date_a_ts = {0}; + struct tm date_b_ts = {0}; time_t x; time_t y; @@ -83,8 +85,8 @@ int is_date_after(char *date_a, char *date_b) int is_date_before(char *date_a, char *date_b) { - struct tm date_a_ts; - struct tm date_b_ts; + struct tm date_a_ts = {0}; + struct tm date_b_ts = {0}; time_t x; time_t y; @@ -111,13 +113,13 @@ int is_date_before(char *date_a, char *date_b) } -int get_time_with_sscanf_from_string(char* date, struct tm *time_struct){ +int get_time_with_sscanf_from_string(char *date, struct tm *time_struct){ int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0; if ( sscanf(date, scanf_time_format_1, &year, &month, &day, &hour, &min, &sec) == 6 ) { - time_struct->tm_year = year; - time_struct->tm_mon = month; + time_struct->tm_year = year - 1900; + time_struct->tm_mon = month - 1; time_struct->tm_mday = day; time_struct->tm_hour = hour; time_struct->tm_min = min; @@ -127,8 +129,8 @@ int get_time_with_sscanf_from_string(char* date, struct tm *time_struct){ } else if ( sscanf(date, scanf_time_format_2, &year, &month, &day, &hour, &min, &sec) == 6 ) { - time_struct->tm_year = year; - time_struct->tm_mon = month; + time_struct->tm_year = year - 1900; + time_struct->tm_mon = month - 1; time_struct->tm_mday = day; time_struct->tm_hour = hour; time_struct->tm_min = min; @@ -139,8 +141,8 @@ int get_time_with_sscanf_from_string(char* date, struct tm *time_struct){ else if ( sscanf(date, scanf_format_notime, &year, &month, &day) == 3 ) { - time_struct->tm_year = year; - time_struct->tm_mon = month; + time_struct->tm_year = year - 1900; + time_struct->tm_mon = month - 1; time_struct->tm_mday = day; time_struct->tm_hour = hour; time_struct->tm_min = min; @@ -151,8 +153,8 @@ int get_time_with_sscanf_from_string(char* date, struct tm *time_struct){ else if ( sscanf(date, scanf_format2_notime, &year, &month, &day) == 3 ) { - time_struct->tm_year = year; - time_struct->tm_mon = month; + time_struct->tm_year = year - 1900; + time_struct->tm_mon = month - 1; time_struct->tm_mday = day; time_struct->tm_hour = hour; time_struct->tm_min = min; @@ -166,26 +168,29 @@ int get_time_with_sscanf_from_string(char* date, struct tm *time_struct){ } -int sync_curr(algoticks_settings settings, algoticks_config config, FILE *f, char* fname, char *date, int seek_offset, int debug){ - +int sync_curr(algoticks_settings *settings, algoticks_config *config, FILE *f, char* fname, char *date, int seek_offset, int debug){ + + algoticks_config sync_config = {0}; int curr = seek_offset; - if (debug) { printf("finding %s in %s\n", date, fname); } + + sprintf(debug_buffer, "finding %s in %s\n", date, fname); + debug_msg(settings->debug, settings->debug_level, 3, __FILE__, __FUNCTION__, __LINE__, debug_buffer); while(curr != EOF || curr != -1){ struct Row r; - curr = read_csv(settings, config, f, fname, &r, curr); - if (debug){ printf("is %s > %s : %d\n", r.date, date, is_date_after(r.date, date)); } + curr = read_csv(settings, &sync_config, f, fname, &r, curr); + sprintf(debug_buffer, "is %s > %s : %d", r.date, date, is_date_after(r.date, date)); + debug_msg(settings->debug, settings->debug_level, 4, __FILE__, __FUNCTION__, __LINE__, debug_buffer); + int res = is_date_after(r.date, date); - if (is_date_after(r.date, date) == true){ + if (res == true){ return curr; } - else if (is_date_after(r.date, date) == -1){ + else if (res == -1){ break; } - } - //if nothing, return null + //if nothing, return -1 indicating error. return -1; - } \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dddc1b3..ac7db30 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,10 +7,11 @@ include_directories(C:/vcpkg/installed/x64-windows/include) link_directories(C:/vcpkg/installed/x64-windows/lib) endif() -add_executable(algoticks_tests algoticks_tests.c ../src/misc.c ../src/dashboard.c ../src/timeutils.c ../src/csvutils.c ../src/debug.c) +add_executable(algoticks_tests algoticks_tests.c ../src/misc.c ../src/parser.c ../src/dashboard.c ../src/timeutils.c ../src/csvutils.c ../src/debug.c) target_link_libraries(algoticks_tests PRIVATE check) target_link_libraries(algoticks_tests PRIVATE json-c) +target_link_libraries(algoticks_tests PRIVATE zmq) if(NOT WIN32) target_link_libraries(algoticks_tests PRIVATE dl) diff --git a/tests/algoticks_tests.c b/tests/algoticks_tests.c index f5b6b5f..79d3c00 100644 --- a/tests/algoticks_tests.c +++ b/tests/algoticks_tests.c @@ -9,15 +9,17 @@ #include "../include/misc.h" #include "../include/timeutils.h" #include "../include/csvutils.h" +#include "../include/parser.h" #include "../include/dashboard.h" /* Tests for: + + from misc.c: void write_simresult_to_csv(algoticks_simresult simresult); -void create_setting_config_benchmark_files(int type); algoticks_config filter_boundaries(algoticks_config config, int is_short); int is_target_hit(algoticks_dashboard dashboard, float target); int is_stoploss_hit(algoticks_dashboard dashboard, float stoploss); @@ -52,43 +54,29 @@ START_TEST (__misc_c__write_simresult_to_csv) { algoticks_simresult sr = {0}; - write_simresult_to_csv(sr); + write_simresult_to_csv(&sr); int res = is_file_exists("results.csv"); ck_assert_int_eq(res, true); } END_TEST -START_TEST -(__misc_c__create_setting_config_benchmark_files) { - - create_setting_config_benchmark_files(1); - create_setting_config_benchmark_files(2); - create_setting_config_benchmark_files(3); - - ck_assert_int_eq(is_file_exists("settings.json"), true); - ck_assert_int_eq(is_file_exists("config.json"), true); - ck_assert_int_eq(is_file_exists("benchmark.json"), true); - -} -END_TEST START_TEST (__misc_c__filter_boundaries) { algoticks_config x = parse_config_from_json("../assets/configs/linux/config.json"); - algoticks_config y; x.target = 15; x.stoploss = 20; - y = filter_boundaries(x,false); - ck_assert_int_eq(y.target, 15); - ck_assert_int_eq(y.stoploss, -20); + filter_boundaries(&x, false); + ck_assert_int_eq(x.target, 15); + ck_assert_int_eq(x.stoploss, -20); - y = filter_boundaries(x,true); - ck_assert_int_eq(y.target, -15); - ck_assert_int_eq(y.stoploss, 20); + filter_boundaries(&x,true); + ck_assert_int_eq(x.target, -15); + ck_assert_int_eq(x.stoploss, 20); } END_TEST @@ -229,8 +217,11 @@ START_TEST (__timeutils_c__is_date_after) { //is a > b - ck_assert_int_eq(is_date_after("2019-02-02 09:25:00","2015-02-02 09:20:00"), true); - ck_assert_int_eq(is_date_after("2014-01-01 09:25:00","2015-01-01 09:00:00"), false); + ck_assert_int_eq(is_date_after("2019-02-02 09:25:00", "2015-02-02 09:20:00"), true); + ck_assert_int_eq(is_date_after("2014-02-02 09:25:00", "2015-02-02 09:20:00"), false); + + ck_assert_int_eq(is_date_before("2014-01-01 09:25:00", "2015-01-01 09:00:00"), true); + ck_assert_int_eq(is_date_before("2013-01-01 09:25:00", "2010-01-01 09:00:00"), false); } END_TEST diff --git a/tests/stream_to_csv.py b/tests/stream_to_csv.py index b687b8f..919c5d9 100644 --- a/tests/stream_to_csv.py +++ b/tests/stream_to_csv.py @@ -11,7 +11,7 @@ csv_file = open("../bin/debug/example.csv", "a") for line in open("AAPL.csv", "r").readlines(): - csv_file.write(line); + csv_file.write(line) time.sleep(1) except KeyboardInterrupt: