/****************************************************************************** * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ #include "../exchanges777.h" #define USD 0 #define EUR 1 #define JPY 2 #define GBP 3 #define AUD 4 #define CAD 5 #define CHF 6 #define NZD 7 #define CNY 8 #define RUB 9 #define NZDUSD 0 #define NZDCHF 1 #define NZDCAD 2 #define NZDJPY 3 #define GBPNZD 4 #define EURNZD 5 #define AUDNZD 6 #define CADJPY 7 #define CADCHF 8 #define USDCAD 9 #define EURCAD 10 #define GBPCAD 11 #define AUDCAD 12 #define USDCHF 13 #define CHFJPY 14 #define EURCHF 15 #define GBPCHF 16 #define AUDCHF 17 #define EURUSD 18 #define EURAUD 19 #define EURJPY 20 #define EURGBP 21 #define GBPUSD 22 #define GBPJPY 23 #define GBPAUD 24 #define USDJPY 25 #define AUDJPY 26 #define AUDUSD 27 #define USDNUM 28 #define EURNUM 29 #define JPYNUM 30 #define GBPNUM 31 #define AUDNUM 32 #define CADNUM 33 #define CHFNUM 34 #define NZDNUM 35 #define NUM_CONTRACTS 28 #define NUM_CURRENCIES 8 #define NUM_COMBINED (NUM_CONTRACTS + NUM_CURRENCIES) #define MAX_SPLINES 64 #define MAX_LOOKAHEAD 72 #define MAX_CURRENCIES 32 #define SATOSHIDEN ((uint64_t)100000000L) #define dstr(x) ((double)(x) / SATOSHIDEN) #define SMALLVAL 0.000000000000001 #define PRICE_RESOLUTION_ROOT ((int64_t)3163) #define PRICE_RESOLUTION (PRICE_RESOLUTION_ROOT * PRICE_RESOLUTION_ROOT) // 10004569 #define PRICE_RESOLUTION2 (PRICE_RESOLUTION * PRICE_RESOLUTION) // 100091400875761 #define PRICE_RESOLUTION_MAXPVAL ((int64_t)3037000500u) // 303.5613528178975 vs 64 bits: 4294967295 429.30058206405493, #define PRICE_RESOLUTION_MAXUNITS ((int16_t)((int64_t)0x7fffffffffffffffLLu / (SATOSHIDEN * PRICE_RESOLUTION))) // 9219 #define SCALED_PRICE(val,scale) (((scale) * (val)) / PRICE_RESOLUTION) #define Pval(r) ((double)(r)->Pval / PRICE_RESOLUTION) // for display only! #define PERCENTAGE(perc) (((perc) * PRICE_RESOLUTION) / 100) #ifndef MAX #define MAX(a,b) ((a) >= (b) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif struct price_resolution { int64_t Pval; }; struct PAX_spline { char name[64]; int32_t splineid,lasti,basenum,num,firstx,dispincr,spline32[MAX_SPLINES][4]; uint32_t utc32[MAX_SPLINES]; int64_t spline64[MAX_SPLINES][4]; double dSplines[MAX_SPLINES][4],pricevals[MAX_SPLINES+MAX_LOOKAHEAD],lastutc,lastval,aveslopeabs; }; struct PAX_data { uint32_t ttimestamps[128]; double tbids[128],tasks[128]; uint32_t ftimestamps[128]; double fbids[128],fasks[128]; uint32_t itimestamps[128]; double ibids[128],iasks[128]; char edate[128]; double ecbmatrix[MAX_CURRENCIES][MAX_CURRENCIES],dailyprices[MAX_CURRENCIES * MAX_CURRENCIES],metals[4]; uint32_t lastupdate; int32_t ecbdatenum,ecbyear,ecbmonth,ecbday; double RTmatrix[MAX_CURRENCIES][MAX_CURRENCIES],RTprices[128],RTmetals[4]; double basevals[MAX_CURRENCIES],cryptovols[2][9][2],BTCDBTC,BTCUSD,KMDBTC,CNYUSD,btcusd,kmdbtc,cryptos[8]; struct PAX_spline splines[128]; }; #define _extrapolate_Spline(Splines,gap) ((double)(Splines)[0] + ((gap) * ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))))) #define _extrapolate_Slope(Splines,gap) ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))) #define PRICE_BLEND(oldval,newval,decay,oppodecay) ((oldval == 0.) ? newval : ((oldval * decay) + (oppodecay * newval))) #define PRICE_BLEND64(oldval,newval,decay,oppodecay) ((oldval == 0) ? newval : ((oldval * decay) + (oppodecay * newval) + 0.499)) #define dto64(x) ((int64_t)((x) * (double)SATOSHIDEN * SATOSHIDEN)) #define dto32(x) ((int32_t)((x) * (double)SATOSHIDEN)) #define i64tod(x) ((double)(x) / ((double)SATOSHIDEN * SATOSHIDEN)) #define i32tod(x) ((double)(x) / (double)SATOSHIDEN) #define _extrapolate_spline64(spline64,gap) ((double)i64tod((spline64)[0]) + ((gap) * ((double)i64tod(.001*.001*(spline64)[1]) + ((gap) * ((double)i64tod(.001*.001*.001*.001*(spline64)[2]) + ((gap) * (double)i64tod(.001*.001*.001*.001*.001*.001*(spline64)[3]))))))) #define _extrapolate_spline32(spline32,gap) ((double)i32tod((spline32)[0]) + ((gap) * ((double)i32tod(.001*.001*(spline32)[1]) + ((gap) * ((double)i32tod(.001*.001*.001*.001*(spline32)[2]) + ((gap) * (double)i32tod(.001*.001*.001*.001*.001*.001*(spline32)[3]))))))) int32_t sprimes[168] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 }; int32_t Peggy_inds[539] = {289, 404, 50, 490, 59, 208, 87, 508, 366, 288, 13, 38, 159, 440, 120, 480, 361, 104, 534, 195, 300, 362, 489, 108, 143, 220, 131, 244, 133, 473, 315, 439, 210, 456, 219, 352, 153, 444, 397, 491, 286, 479, 519, 384, 126, 369, 155, 427, 373, 360, 135, 297, 256, 506, 322, 425, 501, 251, 75, 18, 420, 537, 443, 438, 407, 145, 173, 78, 340, 240, 422, 160, 329, 32, 127, 128, 415, 495, 372, 522, 60, 238, 129, 364, 471, 140, 171, 215, 378, 292, 432, 526, 252, 389, 459, 350, 233, 408, 433, 51, 423, 19, 62, 115, 211, 22, 247, 197, 530, 7, 492, 5, 53, 318, 313, 283, 169, 464, 224, 282, 514, 385, 228, 175, 494, 237, 446, 105, 150, 338, 346, 510, 6, 348, 89, 63, 536, 442, 414, 209, 216, 227, 380, 72, 319, 259, 305, 334, 236, 103, 400, 176, 267, 355, 429, 134, 257, 527, 111, 287, 386, 15, 392, 535, 405, 23, 447, 399, 291, 112, 74, 36, 435, 434, 330, 520, 335, 201, 478, 17, 162, 483, 33, 130, 436, 395, 93, 298, 498, 511, 66, 487, 218, 65, 309, 419, 48, 214, 377, 409, 462, 139, 349, 4, 513, 497, 394, 170, 307, 241, 185, 454, 29, 367, 465, 194, 398, 301, 229, 212, 477, 303, 39, 524, 451, 116, 532, 30, 344, 85, 186, 202, 517, 531, 515, 230, 331, 466, 147, 426, 234, 304, 64, 100, 416, 336, 199, 383, 200, 166, 258, 95, 188, 246, 136, 90, 68, 45, 312, 354, 184, 314, 518, 326, 401, 269, 217, 512, 81, 88, 272, 14, 413, 328, 393, 198, 226, 381, 161, 474, 353, 337, 294, 295, 302, 505, 137, 207, 249, 46, 98, 27, 458, 482, 262, 253, 71, 25, 0, 40, 525, 122, 341, 107, 80, 165, 243, 168, 250, 375, 151, 503, 124, 52, 343, 371, 206, 178, 528, 232, 424, 163, 273, 191, 149, 493, 177, 144, 193, 388, 1, 412, 265, 457, 255, 475, 223, 41, 430, 76, 102, 132, 96, 97, 316, 472, 213, 263, 3, 317, 324, 274, 396, 486, 254, 205, 285, 101, 21, 279, 58, 467, 271, 92, 538, 516, 235, 332, 117, 500, 529, 113, 445, 390, 358, 79, 34, 488, 245, 83, 509, 203, 476, 496, 347, 280, 12, 84, 485, 323, 452, 10, 146, 391, 293, 86, 94, 523, 299, 91, 164, 363, 402, 110, 321, 181, 138, 192, 469, 351, 276, 308, 277, 428, 182, 260, 55, 152, 157, 382, 121, 507, 225, 61, 431, 31, 106, 327, 154, 16, 49, 499, 73, 70, 449, 460, 187, 24, 248, 311, 275, 158, 387, 125, 67, 284, 35, 463, 190, 179, 266, 376, 221, 42, 26, 290, 357, 268, 43, 167, 99, 374, 242, 156, 239, 403, 339, 183, 320, 180, 306, 379, 441, 20, 481, 141, 77, 484, 69, 410, 502, 172, 417, 118, 461, 261, 47, 333, 450, 296, 453, 368, 359, 437, 421, 264, 504, 281, 270, 114, 278, 56, 406, 448, 411, 521, 418, 470, 123, 455, 148, 356, 468, 109, 204, 533, 365, 8, 345, 174, 370, 28, 57, 11, 2, 231, 310, 196, 119, 82, 325, 44, 342, 37, 189, 142, 222, 9, 54, }; uint64_t Currencymasks[NUM_CURRENCIES+1]; short Contract_base[NUM_COMBINED+1] = { 7, 7, 7, 7, 3, 1, 4, 5, 5, 0, 1, 3, 4, 0, 6, 1, 3, 4, 1, 1, 1, 1, 3, 3, 3, 0, 4, 4, 0,1,2,3,4,5,6,7, 8 };// Contract_base }; short Contract_rel[NUM_COMBINED+1] = { 0, 6, 5, 2, 7, 7, 7, 2, 6, 5, 5, 5, 5, 6, 2, 6, 6, 6, 0, 4, 2, 3, 0, 2, 4, 2, 2, 0, 0,1,2,3,4,5,6,7,8 };// Contract_rel short Baserel_contractdir[NUM_CURRENCIES+1][NUM_CURRENCIES+1] = { { 1, -1, 1, -1, -1, 1, 1, -1, -1 }, { 1, 1, 1, 1, 1, 1, 1, 1, -1 }, { -1, -1, 1, -1, -1, -1, -1, -1, 0 }, { 1, -1, 1, 1, 1, 1, 1, 1, -1 }, { 1, -1, 1, -1, 1, 1, 1, 1, -1 }, { -1, -1, 1, -1, -1, 1, 1, -1, 0 }, { -1, -1, 1, -1, -1, -1, 1, -1, -1 }, { 1, -1, 1, -1, -1, 1, 1, 1, 0 }, { -1, -1, 0, -1, -1, 0, -1, 0, 1 }, }; short Currency_contracts[NUM_CURRENCIES+1][NUM_CURRENCIES] = { { 0, 9, 13, 18, 22, 25, 27, 28, }, { 5, 10, 15, 18, 19, 20, 21, 29, }, { 3, 7, 14, 20, 23, 25, 26, 30, }, { 4, 11, 16, 21, 22, 23, 24, 31, }, { 6, 12, 17, 19, 24, 26, 27, 32, }, { 2, 7, 8, 9, 10, 11, 12, 33, }, { 1, 8, 13, 14, 15, 16, 17, 34, }, { 0, 1, 2, 3, 4, 5, 6, 35, }, { 36, 37, -1, 38, 39, -1, 40, 41, }, }; short Currency_contractothers[NUM_CURRENCIES+1][NUM_CURRENCIES] = // buggy! { { 7, 5, 6, 1, 3, 2, 4, 0, }, { 7, 5, 6, 0, 4, 2, 3, 1, }, { 7, 5, 6, 1, 3, 0, 4, 2, }, { 7, 5, 6, 1, 0, 2, 4, 3, }, { 7, 5, 6, 1, 3, 2, 0, 4, }, { 7, 2, 6, 0, 1, 3, 4, 5, }, { 7, 5, 0, 2, 1, 3, 4, 6, }, { 0, 6, 5, 2, 1, 3, 4, 7, }, { 0, 1,-1, 3, 4,-1, 5,-1, }, }; short Baserel_contractnum[NUM_CURRENCIES+1][NUM_CURRENCIES+1] = { { 28, 18, 25, 22, 27, 9, 13, 0, 36 }, { 18, 29, 20, 21, 19, 10, 15, 5, 37 }, { 25, 20, 30, 23, 26, 7, 14, 3, -1 }, { 22, 21, 23, 31, 24, 11, 16, 4, 38 }, { 27, 19, 26, 24, 32, 12, 17, 6, 39 }, { 9, 10, 7, 11, 12, 33, 8, 2, -1 }, { 13, 15, 14, 16, 17, 8, 34, 1, 40 }, { 0, 5, 3, 4, 6, 2, 1, 35, -1 }, { 36, 37, -1, 38, 39, -1, 40, -1, 74 }, }; short Currency_contractdirs[NUM_CURRENCIES+1][NUM_CURRENCIES] = { { -1, 1, 1, -1, -1, 1, -1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1 }, { -1, -1, -1, -1, -1, -1, -1, 1 }, { 1, 1, 1, -1, 1, 1, 1, 1 }, { 1, 1, 1, -1, -1, 1, 1, 1 }, { -1, 1, 1, -1, -1, -1, -1, 1 }, { -1, -1, -1, 1, -1, -1, -1, 1 }, { 1, 1, 1, 1, -1, -1, -1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1 }, }; char *PAX_bases[64] = { "KMD", "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "ETCBTC", "XMRBTC", "KMDBTC", "XCPBTC", // BTC priced "XAUUSD", "XAGUSD", "XPTUSD", "XPDUSD", "COPPER", "NGAS", "UKOIL", "USOIL", // USD priced "BUND", "NAS100", "SPX500", "US30", "EUSTX50", "UK100", "JPN225", "GER30", "SUI30", "AUS200", "HKG33", "XAUUSD", "BTCRUB", "BTCCNY", "BTCUSD" // abstract }; uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies 45434000000000, 16827000000000, 3473357229000, 306435000000, 27139000000000, 2150641000000, 347724099000, 1469583000000, 749543000000, 1826110000000, 2400434000000, 1123925000000, 3125276000000, 13975000000000, 317657000000, 759706000000000, 354902000000, 2797061000000, 162189000000, 163745000000, 1712000000000, 39093000000, 1135490000000000, 80317000000, 100000000 }; #define MIND 1000 uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies 10*MIND, 100*MIND, 10*MIND, MIND, 100*MIND, 10*MIND, MIND, 10*MIND, MIND, 10*MIND, 10*MIND, 10*MIND, 10*MIND, 100*MIND, MIND, 1000*MIND, MIND, 10*MIND, MIND, MIND, 10*MIND, MIND, 10000*MIND, 10*MIND, // end of currencies 10*MIND, }; uint64_t komodo_paxvol(uint64_t volume,uint64_t price) { if ( volume < 10000000000 ) return((volume * price) / 1000000000); else if ( volume < (uint64_t)10 * 10000000000 ) return((volume * (price / 10)) / 100000000); else if ( volume < (uint64_t)100 * 10000000000 ) return(((volume / 10) * (price / 10)) / 10000000); else if ( volume < (uint64_t)1000 * 10000000000 ) return(((volume / 10) * (price / 100)) / 1000000); else if ( volume < (uint64_t)10000 * 10000000000 ) return(((volume / 100) * (price / 100)) / 100000); else if ( volume < (uint64_t)100000 * 10000000000 ) return(((volume / 100) * (price / 1000)) / 10000); else if ( volume < (uint64_t)1000000 * 10000000000 ) return(((volume / 1000) * (price / 1000)) / 1000); else if ( volume < (uint64_t)10000000 * 10000000000 ) return(((volume / 1000) * (price / 10000)) / 100); else return(((volume / 10000) * (price / 10000)) / 10); } void pax_rank(uint64_t *ranked,uint32_t *pvals) { int32_t i; uint64_t vals[32],sum = 0; for (i=0; i<32; i++) { vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); sum += vals[i]; } for (i=0; i<32; i++) { ranked[i] = (vals[i] * 1000000000) / sum; printf("%.6f ",(double)ranked[i]/1000000000.); } }; #define YAHOO_METALS "XAU", "XAG", "XPT", "XPD" static char *Yahoo_metals[] = { YAHOO_METALS }; char CURRENCIES[][65] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies "XAU", "XAG", "XPT", "XPD", // metals, gold must be first "BTCD", "BTC", "NXT", "ETC", "ETH", "KMD", "BTS", "MAID", "XCP", "XMR" // cryptos }; char CONTRACTS[][16] = { "NZDUSD", "NZDCHF", "NZDCAD", "NZDJPY", "GBPNZD", "EURNZD", "AUDNZD", "CADJPY", "CADCHF", "USDCAD", "EURCAD", "GBPCAD", "AUDCAD", "USDCHF", "CHFJPY", "EURCHF", "GBPCHF", "AUDCHF", "EURUSD", "EURAUD", "EURJPY", "EURGBP", "GBPUSD", "GBPJPY", "GBPAUD", "USDJPY", "AUDJPY", "AUDUSD", "USDCNY", "USDHKD", "USDMXN", "USDZAR", "USDTRY", "EURTRY", "TRYJPY", "USDSGD", "EURNOK", "USDNOK","USDSEK","USDDKK","EURSEK","EURDKK","NOKJPY","SEKJPY","USDPLN","EURPLN","USDILS", // no more currencies "XAUUSD", "XAGUSD", "XPTUSD", "XPDUSD", "COPPER", "NGAS", "UKOIL", "USOIL", // commodities // cryptos "NAS100", "SPX500", "US30", "BUND", "EUSTX50", "UK100", "JPN225", "GER30", "SUI30", "AUS200", "HKG33", "FRA40", "ESP35", "ITA40", "USDOLLAR", // indices "SuperNET" // assets }; int32_t isdecimalstr(char *str) { int32_t i; if ( str == 0 || str[0] == 0 ) return(0); for (i=0; str[i]!=0; i++) if ( str[i] < '0' || str[i] > '9' ) return(0); return(i); } int32_t PAX_ispair(char *base,char *rel,char *contract) { int32_t i,j; base[0] = rel[0] = 0; for (i=0; i 0.655564 USDCNY 6.204146 -> 0.652686 USDHKD 7.753400 -> 0.749321 USDHKD 7.746396 -> 0.746445 USDZAR 12.694000 -> 1.101688 USDZAR 12.682408 -> 1.098811 USDTRY 2.779700 -> 0.341327 EURTRY 3.048500 -> 0.386351 TRYJPY 44.724000 -> 0.690171 TRYJPY 44.679966 -> 0.687290 USDSGD 1.375200 -> 0.239415*/ //if ( strcmp(contract,"USDCNY") == 0 || strcmp(contract,"TRYJPY") == 0 || strcmp(contract,"USDZAR") == 0 ) // printf("i.%d j.%d base.%s rel.%s\n",i,j,base,rel); return((i<<8) | j); } break; } } return(-1); } int32_t PAX_basenum(char *_base) { int32_t i,j; char base[65]; strcpy(base,_base); touppercase(base); if ( 1 ) { for (i=0; i=3; numprimes--) { for (p=1; p SMALLVAL ) printf("x.%d error %.20f != %.20f [%.20f]\n",x,smoothbuf[5000 - x],smoothbuf[5000 + x],smoothbuf[5000 - x] - smoothbuf[5000 + x]); _coeffs[x-1] = (smoothbuf[5000 - x] + smoothbuf[5000 + x]) / 2.; } sum = 0.; for (x=0; x= 64 ) return(10000); else if ( PAX_bases[i] != 0 ) { if ( isdecimalstr(PAX_bases[i]+strlen(PAX_bases[i])-2) != 0 || strcmp(PAX_bases[i],"BTCRUB") == 0 ) minmils = 1; else if ( strncmp(PAX_bases[i],"XAU",3) == 0 || strcmp(PAX_bases[i],"BTCCNY") == 0 || strcmp(PAX_bases[i],"BTCUSD") == 0 || strncmp(PAX_bases[i],"XPD",3) == 0 || strncmp(PAX_bases[i],"XPT",3) == 0 ) minmils = 10; else if ( strcmp(PAX_bases[i],"BUND") == 0 || strcmp(PAX_bases[i],"UKOIL") == 0 || strcmp(PAX_bases[i],"USOIL") == 0 ) minmils = 100; else if ( strncmp(PAX_bases[i],"ETC",3) == 0 || strcmp(PAX_bases[i],"SuperNET") == 0 || strncmp(PAX_bases[i],"XAG",3) == 0 || strncmp(PAX_bases[i],"ETH",3) == 0 || strncmp(PAX_bases[i],"XCP",3) == 0 ) minmils = 1000; else if ( strncmp(PAX_bases[i],"XMR",3) == 0 ) minmils = 10000; else if ( strncmp(PAX_bases[i],"NXT",3) == 0 || strncmp(PAX_bases[i],"BTS",3) == 0 ) minmils = 1000000; else if ( strncmp(PAX_bases[i],"KMD",5) == 0 ) minmils = 1000; else minmils = 10000; } return(minmils); } int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double kmdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) { double kmdusd,price_in_kmd,dprice,usdcny,usdrub,btccny,btcrub,xauusd,usdprice=0.,usdval,btcprice=0.; int32_t contractnum,base,nonz = 0; if ( btcusd > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) { xauusd = usdcny = usdrub = btccny = btcrub = 0.; for (contractnum=0; contractnum SMALLVAL ) { usdcny = (basevals[0] * peggy_mils(8)) / (basevals[8] * peggy_mils(0)); btccny = 1000 * btcusd * usdcny; } if ( basevals[9] > SMALLVAL ) { usdrub = (basevals[0] * peggy_mils(9)) / (basevals[9] * peggy_mils(0)); btcrub = 1000 * btcusd * usdrub; } if ( kmdbtc < SMALLVAL ) kmdbtc = 0.0001; kmdusd = (btcusd * kmdbtc); printf("xauusd %f usdval %f %f %f usdcny %f usdrub %f btcusd %f kmdbtc %f kmdusd %f btccny %f btcrub %f\n",xauusd,usdval,basevals[8],basevals[9],usdcny,usdrub,btcusd,kmdbtc,kmdusd,btccny,btcrub); prices[0].Pval = (PRICE_RESOLUTION * 100. * kmdbtc); for (base=0,contractnum=1; base<32; base++,contractnum++) { if ( strcmp(contracts[contractnum],CURRENCIES[base]) == 0 ) { if ( (dprice= basevals[base]) > SMALLVAL ) { nonz++; if ( base == 0 ) usdprice = price_in_kmd = (1. / kmdusd); else price_in_kmd = (dprice / (kmdusd * usdval)); prices[contractnum].Pval = (PRICE_RESOLUTION * price_in_kmd); } } else printf("unexpected list entry %s vs %s at %d\n",contracts[contractnum],CURRENCIES[base],contractnum); } if ( strcmp(contracts[contractnum],"BTCUSD") != 0 ) printf("unexpected contract (%s) at %d\n",contracts[contractnum],contractnum); btcprice = (1. / kmdbtc); prices[contractnum++].Pval = (PRICE_RESOLUTION / kmdbtc) / 1000.; printf("btcprice %f = 1/%f %llu\n",btcprice,1./kmdbtc,(long long)prices[contractnum-1].Pval); for (; contractnum<64; contractnum++) { //dprice = 0; if ( contractnum == 63 && strcmp(contracts[contractnum],"BTCUSD") == 0 ) dprice = btcusd; else if ( contractnum == 62 && strcmp(contracts[contractnum],"BTCCNY") == 0 ) dprice = btccny; else if ( contractnum == 61 && strcmp(contracts[contractnum],"BTCRUB") == 0 ) dprice = btcrub; else if ( contractnum == 60 && strcmp(contracts[contractnum],"XAUUSD") == 0 ) dprice = xauusd; else { dprice = cprices[contractnum]; if ( dprice > SMALLVAL && strlen(contracts[contractnum]) > 3 ) { if ( strcmp(contracts[contractnum]+strlen(contracts[contractnum])-3,"USD") == 0 || strcmp(contracts[contractnum],"COPPER") == 0 || strcmp(contracts[contractnum],"NGAS") == 0 || strcmp(contracts[contractnum],"UKOIL") == 0 || strcmp(contracts[contractnum],"USOIL") == 0 ) dprice *= usdprice; else if ( strcmp(contracts[contractnum],"SuperNET") == 0 ) { printf("SuperNET %f -> %f\n",dprice,dprice*btcprice); dprice *= btcprice; } else if ( strcmp(contracts[contractnum]+strlen(contracts[contractnum])-3,"BTC") == 0 ) dprice *= btcprice; } } prices[contractnum].Pval = (uint64_t)((PRICE_RESOLUTION * dprice) * ((double)peggy_mils(contractnum) / 10000.)); //if ( Debuglevel > 2 ) { struct price_resolution tmp; tmp = peggy_scaleprice(prices[contractnum],peggy_mils(contractnum)); printf("%.8f btcprice %.6f %f -->>> %s %.6f -> %llu %.6f mils.%d\n",cprices[contractnum],btcprice,cprices[contractnum]*btcprice,contracts[contractnum],Pval(&tmp),(long long)prices[contractnum].Pval,Pval(&prices[contractnum]),peggy_mils(contractnum)); } } } return(nonz); } void init_Currencymasks() { int32_t base,j,c; uint64_t basemask; for (base=0; base= 0 ) { basemask |= (1L << c); //printf("(%s %lx) ",CONTRACTS[c],1L<num - 1); if ( timestamp >= spline->utc32[ind] ) { gap = (timestamp - spline->utc32[ind]); if ( gap < lookahead ) return(_extrapolate_spline64(spline->spline64[ind],gap)); else return(0.); } else if ( timestamp <= spline->utc32[0] ) { gap = (spline->utc32[0] - timestamp); if ( gap < lookahead ) return(_extrapolate_spline64(spline->spline64[0],gap)); else return(0.); } for (i=0; inum-1; i++) { ind = (i + spline->lasti) % (spline->num - 1); if ( timestamp >= spline->utc32[ind] && timestamp < spline->utc32[ind+1] ) { spline->lasti = ind; return(_extrapolate_spline64(spline->spline64[ind],timestamp - spline->utc32[ind])); } } return(0.); } double PAX_calcspline(struct PAX_spline *spline,double *outputs,double *slopes,int32_t dispwidth,uint32_t *utc32,double *splinevals,int32_t num) { static double errsums[3]; static int errcount; double c[MAX_SPLINES],f[MAX_SPLINES],dd[MAX_SPLINES],dl[MAX_SPLINES],du[MAX_SPLINES],gaps[MAX_SPLINES]; int32_t n,i,lasti,x,numsplines,nonz; double vx,vy,vw,vz,gap,sum,xval,yval,abssum,lastval,lastxval,yval64,yval32,yval3; uint32_t gap32; sum = lastxval = n = lasti = nonz = 0; for (i=0; i 0 ) { if ( (gaps[n-1]= utc32[i] - lastxval) < 0 ) { printf("illegal gap %f to t%d\n",lastxval,utc32[i]); return(0); } } spline->utc32[n] = lastxval = utc32[i]; n++; } } if ( (numsplines= n) < 4 ) return(0); for (i=0; i=0; i--) c[i] -= c[i+1] * du[i]; //tridiagonal(n-2, dl, dd, du, c); for (i=n-3; i>=0; i--) c[i+1] = c[i]; c[0] = (1.0 + (double)gaps[0] / gaps[1]) * c[1] - ((double)gaps[0] / gaps[1] * c[2]); c[n-1] = (1.0 + (double)gaps[n-2] / gaps[n-3] ) * c[n-2] - ((double)gaps[n-2] / gaps[n-3] * c[n-3]); //printf("c[n-1] %f, n-2 %f, n-3 %f\n",c[n-1],c[n-2],c[n-3]); abssum = nonz = lastval = 0; outputs[spline->firstx] = f[0]; spline->num = numsplines; for (i=0; iutc32[i],(vx),vy*1000*1000,vz*1000*1000*1000*1000,vw*1000*1000*1000*1000*1000*1000,gap,conv_unixtime(&tmp,spline->utc32[i])); spline->dSplines[i][0] = vx, spline->dSplines[i][1] = vy, spline->dSplines[i][2] = vz, spline->dSplines[i][3] = vw; spline->spline64[i][0] = dto64(vx), spline->spline64[i][1] = dto64(vy*1000*1000), spline->spline64[i][2] = dto64(vz*1000*1000*1000*1000), spline->spline64[i][3] = dto64(vw*1000*1000*1000*1000*1000*1000); spline->spline32[i][0] = dto32(vx), spline->spline32[i][1] = dto32(vy*1000*1000), spline->spline32[i][2] = dto32(vz*1000*1000*1000*1000), spline->spline32[i][3] = dto32(vw*1000*1000*1000*1000*1000*1000); gap32 = gap = spline->dispincr; xval = spline->utc32[i] + gap; lastval = vx; while ( i < n-1 ) { x = spline->firstx + ((xval - spline->utc32[0]) / spline->dispincr); if ( x > dispwidth-1 ) x = dispwidth-1; if ( x < 0 ) x = 0; if ( (i < n-2 && gap > gaps[i] + spline->dispincr) ) break; if ( i == n-2 && xval > spline->utc32[n-1] + MAX_LOOKAHEAD*spline->dispincr ) { //printf("x.%d dispwidth.%d xval %f > utc[n-1] %f + %f\n",x,dispwidth,xval,utc[n-1],MAX_LOOKAHEAD*incr); break; } if ( x >= 0 ) { yval = _extrapolate_Spline(spline->dSplines[i],gap); yval64 = _extrapolate_spline64(spline->spline64[i],gap32); if ( (yval3 = PAX_splineval(spline,gap32 + spline->utc32[i],MAX_LOOKAHEAD*spline->dispincr)) != 0 ) { yval32 = _extrapolate_spline32(spline->spline32[i],gap32); errsums[0] += fabs(yval - yval64), errsums[1] += fabs(yval - yval32), errsums[2] += fabs(yval - yval3), errcount++; if ( fabs(yval - yval3) > SMALLVAL ) printf("(%.10f vs %.10f %.10f %.10f [%.16f %.16f %.16f]) ",yval,yval64,yval32,yval3, errsums[0]/errcount,errsums[1]/errcount,errsums[2]/errcount); } if ( yval > 5000. ) yval = 5000.; else if ( yval < -5000. ) yval = -5000.; if ( isnan(yval) == 0 ) { outputs[x] = yval; spline->lastval = outputs[x], spline->lastutc = xval; if ( 1 && fabs(lastval) > SMALLVAL ) { if ( lastval != 0 && outputs[x] != 0 ) { if ( slopes != 0 ) slopes[x] = (outputs[x] - lastval), abssum += fabs(slopes[x]); nonz++; } } } //else outputs[x] = 0.; //printf("x.%-4d %d %f %f %f i%-4d: gap %9.6f %9.6f last %9.6f slope %9.6f | %9.1f [%9.1f %9.6f %9.6f %9.6f %9.6f]\n",x,firstx,xval,utc[0],incr,i,gap,yval,lastval,slopes[x],xval,utc[i+1],dSplines[i][0],dSplines[i][1]*1000*1000,dSplines[i][2]*1000*1000*1000*1000,dSplines[i][3]*1000*1000*1000*1000*1000*1000); } gap32 += spline->dispincr, gap += spline->dispincr, xval += spline->dispincr; } //double pred = (i>0) ? _extrapolate_Spline(dSplines[i-1],gaps[i-1]) : 0.; //printf("%2d: w%8.1f [gap %f -> %9.6f | %9.6f %9.6f %9.6f %9.6f %9.6f]\n",i,weekinds[i],gap,pred,f[i],dSplines[i].x,1000000*dSplines[i].y,1000000*1000000*dSplines[i].z,1000000*1000000*1000*dSplines[i].w); } if ( nonz != 0 ) abssum /= nonz; spline->aveslopeabs = abssum; return(lastval); } int32_t PAX_genspline(struct PAX_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t maxsplines,double *refvals) { int32_t i; double output[2048],slopes[2048],origvals[MAX_SPLINES]; memset(spline,0,sizeof(*spline)), memset(output,0,sizeof(output)), memset(slopes,0,sizeof(slopes)); spline->dispincr = 3600, spline->basenum = splineid, strcpy(spline->name,name); memcpy(origvals,splinevals,sizeof(*splinevals) * MAX_SPLINES); spline->lastval = PAX_calcspline(spline,output,slopes,sizeof(output)/sizeof(*output),utc32,splinevals,maxsplines); for (i=0; inum; i++) { if ( i < spline->num ) { if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] ) printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i); spline->pricevals[i] = output[i * 24]; } } //printf("spline.%s num.%d\n",name,spline->num); return(spline->num); } int32_t PAX_calcmatrix(double matrix[MAX_CURRENCIES][MAX_CURRENCIES]) { int32_t basenum,relnum,nonz,vnum,iter,numbase,numerrs = 0; double sum,vsum,price,price2,basevals[32],errsum=0; memset(basevals,0,sizeof(basevals)); for (iter=0; iter<2; iter++) { numbase = MAX_CURRENCIES; for (basenum=0; basenum price ) // printf("base.%d rel.%d price2 %f vs %f\n",basenum,relnum,1/price2,price); } } if ( iter == 0 ) sum += 1., vsum += 1.; if ( nonz != 0 ) sum /= nonz; if ( vnum != 0 ) vsum /= vnum; if ( iter == 0 ) basevals[basenum] = (sum + 1./vsum) / 2.; else errsum += (sum + vsum)/2, numerrs++;//, printf("(%.8f %.8f) ",sum,vsum); //printf("date.%d (%.8f/%d %.8f/%d).%02d -> %.8f\n",i,sum,nonz,vsum,vnum,basenum,basevals[basenum]); } if ( iter == 0 ) { for (sum=relnum=0; relnumecbmatrix,sizeof(dp->ecbmatrix)); PAX_calcmatrix(Hmatrix); /*for (i=0; i<32; i++) { for (j=0; j<32; j++) printf("%.6f ",Hmatrix[i][j]); printf("%s\n",CURRENCIES[i]); }*/ btcusd = dp->btcusd; kmdbtc = dp->kmdbtc; if ( btcusd > SMALLVAL ) dxblend(&dp->BTCUSD,btcusd,.9); if ( kmdbtc > SMALLVAL ) dxblend(&dp->KMDBTC,kmdbtc,.9); // char *cryptostrs[8] = { "btc", "nxt", "unity", "eth", "ltc", "xmr", "bts", "xcp" }; // "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "ETCBTC", "XMRBTC", "KMDBTC", "XCPBTC", // BTC priced for (i=0; iBTCUSD; continue; } else if ( i == num-2 && strcmp(contracts[i],"BTCCNY") == 0 ) { continue; } else if ( i == num-3 && strcmp(contracts[i],"BTCRUB") == 0 ) { continue; } else if ( i == num-4 && strcmp(contracts[i],"XAUUSD") == 0 ) { continue; } if ( strcmp(contracts[i],"NXTBTC") == 0 ) RTprices[i] = dp->cryptos[1]; else if ( strcmp(contracts[i],"SuperNET") == 0 ) RTprices[i] = dp->cryptos[2]; else if ( strcmp(contracts[i],"ETHBTC") == 0 ) RTprices[i] = dp->cryptos[3]; else if ( strcmp(contracts[i],"ETCBTC") == 0 ) RTprices[i] = dp->cryptos[4]; else if ( strcmp(contracts[i],"XMRBTC") == 0 ) RTprices[i] = dp->cryptos[5]; else if ( strcmp(contracts[i],"KMDBTC") == 0 ) RTprices[i] = dp->cryptos[6]; else if ( strcmp(contracts[i],"XCPBTC") == 0 ) RTprices[i] = dp->cryptos[7]; else if ( i < MAX_CURRENCIES ) { dp->RTmatrix[i][i] = basevals[i] = Hmatrix[i][i]; //if ( Debuglevel > 2 ) //printf("(%s %f).%d ",CURRENCIES[i],basevals[i],i); } else if ( (c= PAX_contractnum(contracts[i],0)) >= 0 ) { RTprices[i] = dp->RTprices[c]; //if ( isdecimalstr(contracts[i]+strlen(contracts[i])-2) != 0 ) // cprices[i] *= .0001; } else { for (j=0; jRTmetals[j]; break; } } } if ( Debuglevel > 2 ) printf("(%f %f) i.%d num.%d %s %f\n",dp->BTCUSD,dp->KMDBTC,i,num,contracts[i],RTprices[i]); //printf("RT.(%s %f) ",contracts[i],RTprices[i]); } return(dp->ecbdatenum); } int32_t PAX_emitprices(uint32_t pvals[32],struct PAX_data *dp) { double matrix[MAX_CURRENCIES][MAX_CURRENCIES],RTmatrix[MAX_CURRENCIES][MAX_CURRENCIES],cprices[64],basevals[64]; struct price_resolution prices[256]; int32_t i,nonz = 0; memset(cprices,0,sizeof(cprices)); if ( PAX_getmatrix(basevals,dp,matrix,cprices+1,PAX_bases+1,sizeof(PAX_bases)/sizeof(*PAX_bases)-1) > 0 ) { cprices[0] = dp->KMDBTC; /*for (i=0; i<32; i++) dp->RTmatrix[i][i] = basevals[i]; for (i=0; i<32; i++) printf("%.6f ",basevals[i]); printf("basevals\n"); for (i=0; i<64; i++) printf("%.6f ",cprices[i]); printf("cprices\n");*/ memset(prices,0,sizeof(prices)); memset(matrix,0,sizeof(matrix)); memset(RTmatrix,0,sizeof(RTmatrix)); //peggy_prices(prices,dp->BTCUSD,dp->KMDBTC,PAX_bases,sizeof(PAX_bases)/sizeof(*PAX_bases),cprices,basevals); for (i=0; i 0xffffffff ) printf("Pval[%d] overflow error %lld\n",i,(long long)prices[i].Pval); else pvals[i] = (uint32_t)prices[i].Pval; } if ( Debuglevel > 2 ) printf("{%s %.6f %u}.%d ",PAX_bases[i],Pval(&prices[i]),(uint32_t)prices[i].Pval,peggy_mils(i)); } } else printf("pricematrix returned null\n"); //printf("nonz.%d\n",nonz); return(nonz); } double PAX_baseprice(struct PAX_spline splines[],uint32_t timestamp,int32_t basenum) { double btc,kmd,kmdusd,usdval; btc = 1000. * _pairaved(PAX_splineval(&splines[MAX_CURRENCIES+0],timestamp,0),PAX_splineval(&splines[MAX_CURRENCIES+1],timestamp,0)); kmd = .01 * PAX_splineval(&splines[MAX_CURRENCIES+2],timestamp,0); if ( btc != 0. && kmd != 0. ) { kmdusd = (btc * kmd); usdval = PAX_splineval(&splines[USD],timestamp,0); if ( basenum == USD ) return(1. / kmdusd); else return(PAX_splineval(&splines[basenum],timestamp,0) / (kmdusd * usdval)); } return(0.); } double PAX_getprice(char *retbuf,char *base,char *rel,char *contract,struct PAX_data *dp) { int32_t i,c,basenum,relnum,n = 0; double yprice,daily,revdaily,price; price = yprice = daily = revdaily = 0.; PAX_ispair(base,rel,contract); if ( base[0] != 0 && rel[0] != 0 ) { basenum = PAX_basenum(base), relnum = PAX_basenum(rel); if ( basenum >= 0 && relnum >= 0 && basenum < MAX_CURRENCIES && relnum < MAX_CURRENCIES ) daily = dp->dailyprices[basenum*MAX_CURRENCIES + relnum], revdaily = dp->dailyprices[relnum*MAX_CURRENCIES + basenum]; } for (i=0; imetals[i]; break; } sprintf(retbuf,"{\"result\":\"success\",\"contract\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\"",contract,base,rel); if ( (c= PAX_contractnum(contract,0)) >= 0 ) { if ( dp->tbids[c] != 0. && dp->tasks[c] != 0. ) { price += (dp->tbids[c] + dp->tasks[c]), n += 2; sprintf(retbuf+strlen(retbuf),",\"truefx\":{\"timestamp\":\"%u\",\"bid\":%.8f,\"ask\":%.8f}",dp->ttimestamps[c],dp->tbids[c],dp->tasks[c]); } if ( dp->fbids[c] != 0. && dp->fasks[c] != 0. ) { price += (dp->fbids[c] + dp->fasks[c]), n += 2; sprintf(retbuf+strlen(retbuf),",\"fxcm\":{\"bid\":%.8f,\"ask\":%.8f}",dp->fbids[c],dp->fasks[c]); } /*if ( dp->ibids[c] != 0. && dp->iasks[c] != 0. ) { price += (dp->ibids[c] + dp->iasks[c]), n += 2; sprintf(retbuf+strlen(retbuf),",\"instaforex\":{\"timestamp\":%u,\"bid\":%.8f,\"ask\":%.8f}",dp->itimestamps[c],dp->ibids[c],dp->iasks[c]); }*/ if ( yprice != 0. ) sprintf(retbuf+strlen(retbuf),",\"yahoo\":{\"price\":%.8f}",yprice); if ( daily != 0. || revdaily != 0. ) sprintf(retbuf+strlen(retbuf),",\"ecb\":{\"date\":\"%s\",\"daily\":%.8f,\"reverse\":%.8f}",dp->edate,daily,revdaily); } if ( n > 0 ) price /= n; sprintf(retbuf+strlen(retbuf),",\"aveprice\":%.8f,\"n\":%d}",price,n); return(price); } /*double PAX_aveprice(struct supernet_info *myinfo,char *base) { struct peggy_info *PEGS; int32_t basenum; if ( (PEGS= myinfo->PEGS) != 0 && (basenum= PAX_basenum(base)) >= 0 ) { return(PEGS->data.RTmatrix[basenum][basenum]); } return(0.); }*/ cJSON *url_json(char *url) { char *jsonstr; cJSON *json = 0; if ( (jsonstr= issue_curl(url)) != 0 ) { //printf("(%s) -> (%s)\n",url,jsonstr); json = cJSON_Parse(jsonstr); free(jsonstr); } return(json); } cJSON *url_json2(char *url) { char *jsonstr; cJSON *json = 0; if ( (jsonstr= issue_curl(url)) != 0 ) { //printf("(%s) -> (%s)\n",url,jsonstr); json = cJSON_Parse(jsonstr); free(jsonstr); } return(json); } double PAX_yahoo(char *metal) { // http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json // http://finance.yahoo.com/webservice/v1/symbols/EUR=USD/quote?format=json // http://finance.yahoo.com/webservice/v1/symbols/XAU=X/quote?format=json // http://finance.yahoo.com/webservice/v1/symbols/XAG=X/quote?format=json // http://finance.yahoo.com/webservice/v1/symbols/XPT=X/quote?format=json // http://finance.yahoo.com/webservice/v1/symbols/XPD=X/quote?format=json char url[1024],*jsonstr; cJSON *json,*obj,*robj,*item,*field; double price = 0.; sprintf(url,"http://finance.yahoo.com/webservice/v1/symbols/%s=X/quote?&format=json",metal); if ( (jsonstr= issue_curl(url)) != 0 ) { //printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { if ( (obj= jobj(json,"list")) != 0 && (robj= jobj(obj,"resources")) != 0 && (item= jitem(robj,0)) != 0 ) { if ( (robj= jobj(item,"resource")) != 0 && (field= jobj(robj,"fields")) != 0 && (price= jdouble(field,"price")) != 0 ) price = 1. / price; } free_json(json); } free(jsonstr); } if ( Debuglevel > 2 ) printf("(%s %f) ",metal,price); dpow_price("yahoo",metal,price,price); return(price); } void PAX_btcprices(struct PAX_data *dp,int32_t enddatenum,int32_t numdates) { int32_t i,n,year,month,day,seconds,datenum; char url[1024],url2[1024],date[64],*dstr,*str; uint32_t timestamp,utc32[MAX_SPLINES]; struct tai t; cJSON *coindesk,*quandl,*kmdhist,*bpi,*array,*item; double kmddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; coindesk = url_json("http://api.coindesk.com/v1/bpi/historical/close.json"); sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); sprintf(url2,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); if ( (bpi= jobj(coindesk,"bpi")) != 0 ) { datenum = enddatenum; memset(utc32,0,sizeof(utc32)); memset(cdaily,0,sizeof(cdaily)); if ( datenum == 0 ) { datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); printf("got datenum.%d %d %d %d\n",datenum,seconds/3600,(seconds/60)%24,seconds%60); } for (i=0; isplines[MAX_CURRENCIES],MAX_CURRENCIES,"coindesk",utc32,cdaily,numdates,cdaily); } else printf("no bpi\n"); quandl = url_json("https://www.quandl.com/api/v1/datasets/BAVERAGE/USD.json?rows=64"); if ( 0 && (str= jstr(quandl,"updated_at")) != 0 && (datenum= conv_date(&seconds,str)) > 0 && (array= jarray(&n,quandl,"data")) != 0 ) { printf("datenum.%d data.%d %d\n",datenum,n,cJSON_GetArraySize(array)); memset(utc32,0,sizeof(utc32)), memset(qdaily,0,sizeof(qdaily)); for (i=0; i 2 ) printf("(%s) ",cJSON_Print(item)); if ( (dstr= jstr(jitem(item,0),0)) != 0 && (datenum= conv_date(&seconds,dstr)) > 0 ) { price = jdouble(jitem(item,1),0), ask = jdouble(jitem(item,2),0), bid = jdouble(jitem(item,3),0); close = jdouble(jitem(item,4),0), vol = jdouble(jitem(item,5),0); if ( Debuglevel > 2 ) fprintf(stderr,"%d.[%d %f %f %f %f %f].%d ",i,datenum,price,ask,bid,close,vol,n); utc32[numdates - 1 - i] = OS_conv_datenum(datenum,12,0,0), qdaily[numdates - 1 - i] = price * .001; if ( i == n-1 ) dpow_price("quandl","BTCUSD",bid,ask); } } PAX_genspline(&dp->splines[MAX_CURRENCIES+1],MAX_CURRENCIES+1,"quandl",utc32,qdaily,n 2 ) printf("[%u %d %f]",timestamp,OS_conv_unixtime(&t,&seconds,timestamp),price); utc32[i] = timestamp - 12*3600, kmddaily[i] = price * 100.; } if ( Debuglevel > 2 ) printf("poloniex.%d\n",n); PAX_genspline(&dp->splines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"kmdhist",utc32,kmddaily,n 2 ) printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { if ( jobj(json,"error") != 0 || jobj(json,"date") == 0 ) { printf("Got error from fixer.io (%s)\n",jsonstr); sleep(10); } else { copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64); if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 ) { while ( item != 0 ) { if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 ) { i = basenum*MAX_CURRENCIES + relnum; prices[i] = item->valuedouble; //if ( basenum == JPYNUM ) // prices[i] *= 100.; // else if ( relnum == JPYNUM ) // prices[i] /= 100.; count++; if ( Debuglevel > 2 ) printf("(%02d:%02d %f) ",basenum,relnum,prices[i]); sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]); } else printf("cant find.(%s)\n",relstr);//, getchar(); item = item->next; } } } free_json(json); } free(jsonstr); } return(count); } int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32_t day) { // http://api.fixer.io/latest?base=CNH // http://api.fixer.io/2000-01-03?base=USD // "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD" char baseurl[512],tmpdate[64],url[512],checkdate[16]; int32_t basenum,count,i,iter,nonz; checkdate[0] = 0; if ( year == 0 ) strcpy(baseurl,"http://api.fixer.io/latest?base="); else { sprintf(checkdate,"%d-%02d-%02d",year,month,day); sprintf(baseurl,"http://api.fixer.io/%s?base=",checkdate); } count = 0; for (iter=0; iter<2; iter++) { for (basenum=0; basenum= MAX_CURRENCIES ) break; if ( iter == 0 ) { sprintf(url,"%s%s",baseurl,CURRENCIES[basenum]); count += PAX_ecbparse(basenum == 0 ? date : tmpdate,prices,url,basenum); usleep(100000); if ( (basenum != 0 && strcmp(tmpdate,date) != 0) || (checkdate[0] != 0 && strcmp(checkdate,date) != 0) ) { //printf("date mismatch (%s) != (%s) or checkdate.(%s)\n",tmpdate,date,checkdate); return(-1); } } else { for (nonz=i=0; i= MAX_CURRENCIES ) break; if ( prices[MAX_CURRENCIES*basenum + i] != 0. ) nonz++; if ( Debuglevel > 2 ) printf("%8.5f ",prices[MAX_CURRENCIES*basenum + i]); } if ( Debuglevel > 2 ) printf("%s.%d %d\n",CURRENCIES[basenum],basenum,nonz); } } } return(count); } int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES][MAX_CURRENCIES],char *date) { FILE *fp=0; double price,bid,ask; int32_t n=0,datenum,relid,baseid,year=0,seconds,month=0,day=0,loaded = 0; char name[16],fname[64],_date[64]; if ( date == 0 ) date = _date, memset(_date,0,sizeof(_date)); //printf("ecb_matrix(%s)\n",date); sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname); if ( date[0] != 0 && (fp= fopen(fname,"rb")) != 0 ) { if ( fread(matrix,1,sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES,fp) == sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES ) loaded = 1; else printf("fread error\n"); fclose(fp); } else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp); datenum = conv_date(&seconds,date); year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100); if ( loaded == 0 ) { if ( (n= PAX_ecbprices(date,&matrix[0][0],year,month,day)) > 0 ) { sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { if ( fwrite(matrix,1,sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES,fp) == sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES ) loaded = 1; fclose(fp); } } //else printf("peggy_matrix error loading %d.%d.%d\n",year,month,day); } else { PAX_calcmatrix(matrix); for (baseid=0; baseid SMALLVAL ) price = 1. / price; if ( matrix[baseid][relid] > SMALLVAL && matrix[baseid][relid] < price ) bid = matrix[baseid][relid], ask = price; else bid = price, ask = matrix[baseid][relid]; if ( bid > SMALLVAL && ask > SMALLVAL ) { dpow_price("ecb",name,bid,ask); n++; } } for (baseid=0; baseid 0 && (array= jarray(&n,quandl,"data")) != 0 ) { //printf("datenum.%d data.%d %d\n",datenum,n,cJSON_GetArraySize(array)); for (i=0; i<1; i++) { // ["Date","24h Average","Ask","Bid","Last","Total Volume"] // ["2015-07-25",289.27,288.84,288.68,288.87,44978.61] item = jitem(array,i); if ( (dstr= jstr(jitem(item,0),0)) != 0 && (datenum= conv_date(&seconds,dstr)) > 0 ) { btcusd = price = jdouble(jitem(item,1),0), ask = jdouble(jitem(item,2),0), bid = jdouble(jitem(item,3),0); close = jdouble(jitem(item,4),0), vol = jdouble(jitem(item,5),0); //fprintf(stderr,"%d.[%d %f %f %f %f %f].%d ",i,datenum,price,ask,bid,close,vol,n); } } } if ( 1 ) { double USD_average,avebid,aveask,bidvol,askvol,highbid,lowask,CMC_average,changes[3]; //struct exchange_quote sortbuf[512]; struct supernet_info *myinfo = SuperNET_MYINFO(0); cJSON *argjson = cJSON_Parse("{}"); //aveask = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&askvol,"KMD","BTC",1,argjson); //avebid = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&bidvol,"KMD","BTC",-1,argjson); if ( 0 && avebid > SMALLVAL && aveask > SMALLVAL ) { price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol); *kmdbtcp = price; printf("set KMD price %f\n",price); dp->KMDBTC = price; } else if ( (dp->KMDBTC= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,"komodo","KMD","BTC",&USD_average)) > SMALLVAL ) *kmdbtcp = dp->KMDBTC; else { for (iter=1; iter<2; iter++) { kmdhist = url_json(iter == 0 ? url : url2); //{"date":1406160000,"high":0.01,"low":0.00125,"open":0.01,"close":0.001375,"volume":1.50179994,"quoteVolume":903.58818412,"weightedAverage":0.00166204}, if ( kmdhist != 0 && (array= jarray(&n,kmdhist,0)) != 0 ) { //printf("GOT.(%s)\n",cJSON_Print(array)); for (i=0; i<1; i++) { item = jitem(array,i); timestamp = juint(item,"date"), high = jdouble(item,"high"), low = jdouble(item,"low"), open = jdouble(item,"open"); close = jdouble(item,"close"), vol = jdouble(item,"volume"), quotevol = jdouble(item,"quoteVolume"), price = jdouble(item,"weightedAverage"); //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); //printf("[%u %d %f]",timestamp,OS_conv_unixtime(&seconds,timestamp),price); if ( price != 0 ) { if ( iter == 0 ) dp->KMDBTC = *kmdbtcp = kmddaily; else dp->BTCDBTC = price; } } //printf("poloniex.%d\n",n); } if ( kmdhist != 0 ) free_json(kmdhist); } } } if ( (*kmdbtcp= dp->KMDBTC) == 0. ) *kmdbtcp = dp->BTCDBTC / 50.22; if ( (rand() % 100) == 0 ) printf("KMD/BTC %.8f\n",*kmdbtcp); if ( btctrades != 0 && (array= jarray(&n,btctrades,0)) != 0 ) { //printf("GOT.(%s)\n",cJSON_Print(array)); for (i=0; i<1; i++) { item = jitem(array,i); timestamp = juint(item,"date"); //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); //printf("[%u %d %f]",timestamp,OS_conv_unixtime(&seconds,timestamp),price); *btcusdp = jdouble(item,"rate"); //printf("(%s) -> %f\n",jprint(item,0),btcusd); } free(btctrades); //printf("poloniex.%d\n",n); } if ( 0 && bitcoinave != 0 ) { if ( (price= jdouble(bitcoinave,"24h_avg")) > SMALLVAL ) { //printf("bitcoinave %f %f\n",btcusd,price); dpow_price("bitcoinave","BTCUSD",price,price); dxblend(&btcusd,price,0.5); } free_json(bitcoinave); } if ( quandl != 0 ) free_json(quandl); if ( coindesk != 0 ) free_json(coindesk); if ( blockchaininfo != 0 ) { if ( (item= jobj(blockchaininfo,"USD")) != 0 && item != 0 && (price= jdouble(item,"15m")) > SMALLVAL ) { dpow_price("blockchain.info","BTCUSD",price,price); printf("blockchaininfo %f %f\n",btcusd,price); dxblend(&btcusd,price,0.5); } free_json(blockchaininfo); } } double blend_price(double *volp,double wtA,cJSON *jsonA,double wtB,cJSON *jsonB) { //A.{"ticker":{"base":"BTS","target":"CNY","price":"0.02958291","volume":"3128008.39295500","change":"0.00019513","markets":[{"market":"BTC38","price":"0.02960000","volume":3051650.682955},{"market":"Bter","price":"0.02890000","volume":76357.71}]},"timestamp":1438490881,"success":true,"error":""} // B.{"id":"bts\/cny","price":"0.02940000","price_before_24h":"0.02990000","volume_first":"3048457.6857147217","volume_second":"90629.45859575272","volume_btc":"52.74","best_market":"btc38","latest_trade":"2015-08-02 03:57:38","coin1":"BitShares","coin2":"CNY","markets":[{"market":"btc38","price":"0.02940000","volume":"3048457.6857147217","volume_btc":"52.738317962865"},{"market":"bter","price":"0.04350000","volume":"0","volume_btc":"0"}]} double priceA,priceB,priceB24,price,volA,volB; cJSON *obj; priceA = priceB = priceB24= price = volA = volB = 0.; if ( jsonA != 0 && (obj= jobj(jsonA,"ticker")) != 0 ) { priceA = jdouble(obj,"price"); volA = jdouble(obj,"volume"); } if ( jsonB != 0 ) { priceB = jdouble(jsonB,"price"); priceB24 = jdouble(jsonB,"price_before_24h"); volB = jdouble(jsonB,"volume_first"); } //printf("priceA %f volA %f, priceB %f %f volB %f\n",priceA,volA,priceB,priceB24,volB); if ( priceB > SMALLVAL && priceB24 > SMALLVAL ) priceB = (priceB * .1) + (priceB24 * .9); else if ( priceB < SMALLVAL ) priceB = priceB24; if ( priceA*volA < SMALLVAL ) price = priceB; else if ( priceB*volB < SMALLVAL ) price = priceA; else price = (wtA * priceA) + (wtB * priceB); *volp = (volA + volB); return(price); } void _crypto_update(double cryptovols[2][9][2],struct PAX_data *dp,int32_t selector) { char *cryptonatorA = "https://www.cryptonator.com/api/full/%s-%s"; //unity-btc char *cryptocoinchartsB = "http://api.cryptocoincharts.info/tradingPair/%s_%s"; //bts_btc char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "kmd", "xmr", "bts", "xcp", "etc" }; int32_t iter,i,j; double btcusd,kmdbtc,cnyusd,prices[9][2],volumes[9][2]; char base[16],rel[16],url[512],name[16],*str; cJSON *jsonA,*jsonB; cnyusd = dp->CNYUSD; btcusd = dp->BTCUSD; if ( (kmdbtc= dp->KMDBTC) == 0. ) ;//kmdbtc = dp->BTCDBTC / 50.22; printf("DEPRECATED: update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd); return; if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { PAX_update(dp,&btcusd,&kmdbtc); //printf("PAX_update with btcusd %f kmd %f\n",btcusd,kmdbtc); } memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); for (j=0; j SMALLVAL ) break; i = 3; } else*/ i = j; for (iter=0; iter<1; iter++) { if ( i == 0 && iter == 0 ) strcpy(base,"kmd"), strcpy(rel,"btc"); else strcpy(base,str), strcpy(rel,iter==0?"btc":"cny"); sprintf(name,"%s%s",base,rel); //if ( selector == 0 ) { sprintf(url,cryptonatorA,base,rel); jsonA = url_json(url); } //else { sprintf(url,cryptocoinchartsB,base,rel); jsonB = url_json(url); } prices[i][iter] = blend_price(&volumes[i][iter],0.4,jsonA,0.6,jsonB); if ( iter == 1 ) { if ( btcusd > SMALLVAL ) { prices[i][iter] *= cnyusd / btcusd; volumes[i][iter] *= cnyusd / btcusd; } else prices[i][iter] = volumes[i][iter] = 0.; } cryptovols[0][i][iter] = _pairaved(cryptovols[0][i][iter],prices[i][iter]); //cryptovols[1][i][iter] = _pairaved(cryptovols[1][i][iter],volumes[i][iter]); dpow_price("cryptonator",name,prices[i][iter],prices[i][iter]); if ( Debuglevel > 2 ) printf("(%f %f).%d:%d ",cryptovols[0][i][iter],cryptovols[1][i][iter],i,iter); //if ( cnyusd < SMALLVAL || btcusd < SMALLVAL ) // break; } } } void PAX_RTupdate(double cryptovols[2][9][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) { char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "kmd", "xmr", "bts", "xcp" }; int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,kmdbtc,bid=0.,ask=0.,price,vol,prices[8][2],volumes[8][2]; char base[16],rel[16]; PAX_update(dp,&btcusd,&kmdbtc); memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); for (i=0; i SMALLVAL ) dxblend(&kmdbtc,prices[0][0],.9); dxblend(&dp->kmdbtc,kmdbtc,.995); if ( dp->KMDBTC < SMALLVAL ) dp->KMDBTC = dp->kmdbtc; if ( (cnyusd= dp->CNYUSD) > SMALLVAL ) { if ( prices[0][1] > SMALLVAL ) { //printf("cnyusd %f, btccny %f -> btcusd %f %f\n",cnyusd,prices[0][1],prices[0][1]*cnyusd,btcusd); btcusd = prices[0][1] * cnyusd; if ( dp->btcusd < SMALLVAL ) dp->btcusd = btcusd; else dxblend(&dp->btcusd,btcusd,.995); if ( dp->BTCUSD < SMALLVAL ) dp->BTCUSD = dp->btcusd; printf("cnyusd %f, btccny %f -> btcusd %f %f -> %f %f %f\n",cnyusd,prices[0][1],prices[0][1]*cnyusd,btcusd,dp->btcusd,dp->btcusd,dp->BTCUSD); } } for (i=1; i SMALLVAL ) { price = ((prices[i][0] * volumes[i][0]) + (prices[i][1] * volumes[i][1])) / vol; if ( Debuglevel > 2 ) printf("%s %f v%f + %f v%f -> %f %f\n",cryptostrs[i],prices[i][0],volumes[i][0],prices[i][1],volumes[i][1],price,dp->cryptos[i]); dxblend(&dp->cryptos[i],price,.995); } } btcusd = dp->BTCUSD; kmdbtc = dp->KMDBTC; if ( Debuglevel > 2 ) printf(" update with btcusd %f kmd %f\n",btcusd,kmdbtc); if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { PAX_update(dp,&btcusd,&kmdbtc); if ( Debuglevel > 2 ) printf(" price777_update with btcusd %f kmd %f\n",btcusd,kmdbtc); } else dp->BTCUSD = btcusd, dp->KMDBTC = kmdbtc; for (c=0; ctbids[c], ask = dp->tasks[c]; break; case 1: bid = dp->fbids[c], ask = dp->fasks[c]; break; case 2: bid = dp->ibids[c], ask = dp->iasks[c]; break; } if ( (price= _pairaved(bid,ask)) > SMALLVAL ) { if ( Debuglevel > 2 ) printf("%.6f ",price); dxblend(&RTprices[c],price,.995); if ( 0 && (baserel= PAX_ispair(base,rel,CONTRACTS[c])) >= 0 ) { basenum = (baserel >> 8) & 0xff, relnum = baserel & 0xff; if ( basenum < 32 && relnum < 32 ) { //printf("%s.%d %f <- %f\n",CONTRACTS[c],c,RTmatrix[basenum][relnum],RTprices[c]); //dxblend(&RTmatrix[basenum][relnum],RTprices[c],.999); } } if ( strcmp(CONTRACTS[c],"XAUUSD") == 0 ) dxblend(&RTmetals[0],price,.995); } } } for (i=0; imetals[i] != 0 ) dxblend(&RTmetals[i],dp->metals[i],.995); } void PAX_bidask(struct exchange_info *exchange,uint32_t *timestamps,double *bids,double *asks,int32_t baseid,int32_t relid) { int32_t contractnum; struct exchange_quote bidasks[2]; contractnum = Baserel_contractnum[baseid][relid]; (*exchange->issue.price)(exchange,CURRENCIES[baseid],CURRENCIES[relid],bidasks,1,0.,0,0); //bids[contractnum] = bidasks[0].price; //asks[contractnum] = bidasks[1].price; //timestamps[contractnum] = bidasks[0].timestamp; //printf("%s%s.(%s %.6f) %s\n",CURRENCIES[baseid],CURRENCIES[relid],CONTRACTS[contractnum],_pairaved(bids[contractnum],asks[contractnum]),exchange->name); } struct exchange_info *PAX_bidasks(char *exchangestr,uint32_t *timestamps,double *bids,double *asks) { int32_t baseid,relid; struct exchange_info *exchange; if ( (exchange= exchanges777_find(exchangestr)) != 0 ) { for (baseid=0; baseid<8; baseid++) { for (relid=0; relid<8; relid++) { if ( Currency_contractdirs[baseid][relid] > 0 ) PAX_bidask(exchange,timestamps,bids,asks,baseid,relid); } } } else printf("cant find (%s) exchange\n",exchangestr); return(exchange); } void dpow_price(char *exchange,char *name,double bid,double ask) { // adjust MAX_CURRENCIES, btcusd, btccny //printf("%-12s %16.8f %16.8f %s\n",name,bid,ask,exchange); } uint32_t PAX_val32(double val) { uint32_t val32 = 0; struct price_resolution price; if ( (price.Pval= val*1000000000) != 0 ) { if ( price.Pval > 0xffffffff ) printf("Pval overflow error %lld\n",(long long)price.Pval); else val32 = (uint32_t)price.Pval; } return(val32); } double PAX_val(uint32_t pval,int32_t baseid) { if ( baseid >= 0 && baseid < MAX_CURRENCIES ) return(((double)pval / 1000000000.) / MINDENOMS[baseid]); return(0.); } void PAX_genecbsplines(struct PAX_data *dp) { static portable_mutex_t mutex; static int32_t initflag; int32_t i,j,datenum,seconds,numsamples; double prices[128][MAX_SPLINES],splineval,diff; uint32_t pvals[MAX_CURRENCIES],utc32[MAX_SPLINES],timestamp; struct tai t; if ( initflag == 0 ) { portable_mutex_init(&mutex); initflag = 1; } portable_mutex_lock(&mutex); for (i=numsamples=0; i<28; i++) { datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(28-i+1)*24*3600); expand_datenum(dp->edate,datenum); timestamp = OS_conv_datenum(datenum,12,0,0); printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp); if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 ) { utc32[numsamples] = timestamp; for (j=0; jbasevals[j]); prices[j][numsamples] = dp->basevals[j]; } numsamples++; } } for (j=0; j<3; j++) utc32[numsamples + j] = utc32[numsamples + j - 1] + (24 * 3600); for (j=0; jsplines[j],j,CURRENCIES[j],utc32,prices[j],numsamples,prices[j]); splineval = PAX_splineval(&dp->splines[j],utc32[numsamples-1]- 8*3600,1); diff = (prices[j][numsamples-1] - splineval); prices[j][numsamples] = prices[j][numsamples-1] + diff; diff += prices[j][numsamples-1] - PAX_splineval(&dp->splines[j],utc32[numsamples-1] - 12*3600,1); prices[j][numsamples+1] = prices[j][numsamples-1] + diff; diff += prices[j][numsamples-1] - PAX_splineval(&dp->splines[j],utc32[numsamples-1] - 16*3600,1); prices[j][numsamples+2] = prices[j][numsamples-1] + diff; //printf("%s splineval %f vs %f %f %f\n",CURRENCIES[j],prices[j][numsamples-1],prices[j][numsamples],prices[j][numsamples+1],prices[j][numsamples+2]); PAX_genspline(&dp->splines[j],j,CURRENCIES[j],utc32,prices[j],numsamples+3,prices[j]); } portable_mutex_unlock(&mutex); } #define BTCFACTOR_TIMESTAMP 1503746319 #define BTCFACTOR_HEIGHT 466266 int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t idlegap) { static double lastupdate,lastdayupdate; static uint32_t didinit; static char *userhome; int32_t idlegap = 10; FILE *fp; long filesize; char fname[512]; double splineval; uint32_t pvals[128],timestamp; int32_t i,datenum,seconds,c; struct tai t; struct PAX_data *dp; uint8_t data[512]; if ( 1 || Currencymasks[0] == 0 ) // disable pax price gatherings return(0); if ( time(NULL) > didinit+12*3600 ) { if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 ) userhome = "root"; else { while ( (c= userhome[strlen(userhome)-1]) == '\r' || c == '\n' || c == ' ' || c == '\t' ) { userhome[strlen(userhome)-1] = 0; } } if ( myinfo->PAXDATA == 0 ) myinfo->PAXDATA = calloc(1,sizeof(*dp)); dp = myinfo->PAXDATA; PAX_genecbsplines(dp); printf("generated splines\n"); didinit = (uint32_t)time(NULL); datenum = OS_conv_unixtime(&t,&seconds,didinit); expand_datenum(dp->edate,datenum); } dp = myinfo->PAXDATA; /*if ( 0 && time(NULL) > dp->lastupdate+10 ) { _crypto_update(dp->cryptovols,dp,1); dp->lastupdate = (uint32_t)time(NULL); }*/ if ( OS_milliseconds() > lastupdate + (1000*idlegap) ) { lastupdate = OS_milliseconds(); if ( OS_milliseconds() > lastdayupdate + 60000*60 ) { lastdayupdate = OS_milliseconds(); datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); expand_datenum(dp->edate,datenum); if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 && datenum != dp->ecbdatenum ) { dp->ecbdatenum = datenum; dp->ecbyear = dp->ecbdatenum / 10000, dp->ecbmonth = (dp->ecbdatenum / 100) % 100, dp->ecbday = (dp->ecbdatenum % 100); expand_datenum(dp->edate,datenum); memcpy(dp->RTmatrix,dp->ecbmatrix,sizeof(dp->RTmatrix)); PAX_genecbsplines(dp); } } if ( 0 ) { for (i=0; imetals[i] = PAX_yahoo(Yahoo_metals[i]); PAX_bidasks("truefx",dp->ttimestamps,dp->tbids,dp->tasks); PAX_bidasks("fxcm",dp->ftimestamps,dp->fbids,dp->fasks); /*if ( (exchange= PAX_bidasks("instaforex",dp->itimestamps,dp->ibids,dp->iasks)) != 0 ) { if ( (contractnum= PAX_contractnum("XAU","USD")) >= 0 ) { (*exchange->issue.price)(exchange,"XAU","USD",bidasks,1,0.,0,0); dp->ibids[contractnum] = bidasks[0].price; dp->iasks[contractnum] = bidasks[1].price; dp->itimestamps[contractnum] = bidasks[0].timestamp; } }*/ //printf("BTCUSD %f %f %f\n",btcusd,dp->btcusd,dp->BTCUSD); if ( dp->ecbmatrix[USD][USD] > SMALLVAL && dp->ecbmatrix[CNY][CNY] > SMALLVAL ) dp->CNYUSD = (dp->ecbmatrix[CNY][CNY] / dp->ecbmatrix[USD][USD]); PAX_RTupdate(dp->cryptovols,dp->RTmetals,dp->RTprices,dp); PAX_emitprices(pvals,dp); } timestamp = (uint32_t)time(NULL); int32_t dispflag = ((rand() % 6) == 0); //printf("PAX_IDLE.%d %.8f %.8f\n",dispflag,dp->kmdbtc,dp->btcusd); if ( dp->kmdbtc == 0 || dp->btcusd == 0 || dispflag != 0 ) { PAX_update(dp,&dp->btcusd,&dp->kmdbtc); for (i=0; isplines[i],timestamp,0); pvals[6+i] = PAX_val32(splineval); if ( dispflag != 0 ) printf("%u ",pvals[6+i]); } if ( pvals[6+CNY] != 0 && pvals[6+USD] != 0 ) dp->CNYUSD = ((double)pvals[6 + CNY] / pvals[6 + USD]) * MINDENOMS[USD] / MINDENOMS[CNY]; pvals[1] = timestamp; pvals[2] = MAX_CURRENCIES + 3; pvals[3] = PAX_val32(dp->kmdbtc * 1000); double btcfactor; //if ( time(NULL) > BTCFACTOR_TIMESTAMP ) btcfactor = .00001; //else btcfactor = .001; pvals[4] = PAX_val32(dp->btcusd * btcfactor); pvals[5] = PAX_val32(dp->CNYUSD); sprintf(fname,"/%s/.komodo/komodofeed",userhome); if ( (fp= fopen(fname,"wb")) != 0 ) { for (i=1; ikmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD,pvals[4]); } } } return(0); } void PAX_init() { static int32_t didinit; //double commission = 0.; if ( didinit == 0 ) { init_Currencymasks(); //calc_smooth_code(127,7); //tradebot_monitorall(0,0,0,0,"fxcm",commission); //tradebot_monitorall(0,0,0,0,"truefx",commission); //tradebot_monitorall(0,0,0,0,"instaforex",commission); exchange_create("PAX",0); didinit = 1; } }