From 493ef27e94f75e4936245278bd5499a07652f565 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 23 Oct 2016 10:46:04 -0300 Subject: [PATCH] pricefeed --- iguana/dpow/dpow_fsm.c | 2 +- iguana/dpow/dpow_prices.c | 1859 +++++++++++++++++++++++++++++++++ iguana/exchanges/fxcm.c | 5 + iguana/exchanges/instaforex.c | 2 +- iguana/exchanges/truefx.c | 17 +- iguana/exchanges777.h | 1 + iguana/iguana777.h | 3 +- iguana/iguana_exchanges.c | 22 +- iguana/iguana_notary.c | 5 +- iguana/peggy.c | 10 +- iguana/peggy.h | 10 +- iguana/peggy_price.c | 54 +- iguana/peggy_update.c | 116 +- iguana/ramchain_api.c | 6 + includes/iguana_apideclares.h | 2 - 15 files changed, 1991 insertions(+), 123 deletions(-) create mode 100755 iguana/dpow/dpow_prices.c diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index 096b1517d..e44e8f316 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -111,7 +111,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t if ( (bp= dpow_heightfind(myinfo,height)) == 0 ) { if ( (rand() % 100) == 0 ) - printf("couldnt find height.%d\n",height); + printf("couldnt find height.%d | if you just started notary dapp this is normal\n",height); return(-1); } dpow_notaryfind(myinfo,bp,&myind,myinfo->DPOW.minerkey33); diff --git a/iguana/dpow/dpow_prices.c b/iguana/dpow/dpow_prices.c new file mode 100755 index 000000000..a22293305 --- /dev/null +++ b/iguana/dpow/dpow_prices.c @@ -0,0 +1,1859 @@ +/****************************************************************************** + * Copyright © 2014-2016 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],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 +}; + +int32_t MINDENOMS[] = { 1000, 1000, 100000, 1000, 1000, 1000, 1000, 1000, // major currencies + 10000, 100000, 10000, 1000, 100000, 10000, 1000, 10000, 1000, 10000, 10000, 10000, 10000, 100000, 1000, 1000000, 1000, 10000, 1000, 1000, 10000, 1000, 10000000, 10000, // end of currencies + 1, 100, 1, 1, // metals, gold must be first + 100, 1, 10000, 100, 100, 1000, 100000, 1000, 1000, 1000 +}; +#define YAHOO_METALS "XAU", "XAG", "XPT", "XPD" +static char *Yahoo_metals[] = { YAHOO_METALS }; + +char CURRENCIES[][8] = { "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[64]; + 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 ( 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/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],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)); + 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 ) + { + copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64); + printf("tmpdate.(%s)\n",date); + 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 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)); + 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 ( 0 ) + { + double avebid,aveask,bidvol,askvol; 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 ( avebid > SMALLVAL && aveask > SMALLVAL ) + { + price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol); + *kmdbtcp = price; + printf("set KMD price %f\n",price); + dp->KMDBTC = price; + } + else + { + kmdhist = url_json(url); + //{"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); + kmddaily = price; + if ( kmddaily != 0 ) + dp->KMDBTC = *kmdbtcp = kmddaily; + } + //printf("poloniex.%d\n",n); + } + if ( kmdhist != 0 ) + free_json(kmdhist); + } + } + 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 = 0.0001; + //printf("update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd); + 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,ask,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); +} + +void PAX_genecbsplines(struct PAX_data *dp) +{ + 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; + for (i=numsamples=0; i<30; i++) + { + datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(30-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]); + } +} + +int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t idlegap) +{ + static double lastupdate,lastdayupdate; static int32_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; struct tai t; struct PAX_data *dp; uint8_t data[512]; + if ( Currencymasks[0] == 0 ) + return(0); + if ( didinit == 0 ) + { + if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 ) + userhome = "root"; + myinfo->PAXDATA = calloc(1,sizeof(*dp)); + didinit = 1; + dp = myinfo->PAXDATA; + PAX_genecbsplines(dp); + printf("generated splines\n"); + datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); + expand_datenum(dp->edate,datenum); + } + dp = myinfo->PAXDATA; + if ( 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(); + 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); + } + PAX_update(dp,&dp->btcusd,&dp->kmdbtc); + timestamp = (uint32_t)time(NULL); + for (i=0; isplines[i],timestamp,0); + pvals[6+i] = PAX_val32(splineval); + printf("%d ",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); + pvals[4] = PAX_val32(dp->btcusd * .001); + pvals[5] = PAX_val32(dp->CNYUSD); + printf("KMD %f BTC %f CNY %f (%f)\n",dp->kmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD); + sprintf(fname,"/%s/.komodo/komodofeed",userhome); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + for (i=1; i %s\n",fname); + } + return(0); +} + +void PAX_init() +{ + double commission = 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); +} diff --git a/iguana/exchanges/fxcm.c b/iguana/exchanges/fxcm.c index 02e98fea1..42807a46f 100755 --- a/iguana/exchanges/fxcm.c +++ b/iguana/exchanges/fxcm.c @@ -131,6 +131,7 @@ int32_t fxcm_setcontracts() if ( strcmp(name,"USDCNH") == 0 ) strcpy(name,"USDCNY"); FXCM_contracts[num++] = clonestr(name); + printf("FXCM[%d] = %s\n",num-1,name); } } } @@ -235,6 +236,7 @@ void prices777_fxcm(double bids[64],double asks[64],double highs[64],double lows { bids[c] = bid, asks[c] = ask, highs[c] = high, lows[c] = low; //printf("c.%d (%s) %f %f\n",c,name,bid,ask); + dpow_price("fxcm",name,bid,ask); flag = 1; } else printf("cant find.%s\n",name);//, getchar(); } @@ -261,7 +263,10 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bids[c],1,commission,0,(uint32_t)time(NULL),0); ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,asks[c],1,commission,0,(uint32_t)time(NULL),0); if ( bid > SMALLVAL && ask > SMALLVAL ) + { + //printf("%d.{%.6f %.6f}.%s ",c,bid,ask,name); return((bid + ask) * .5); + } } } return(0); diff --git a/iguana/exchanges/instaforex.c b/iguana/exchanges/instaforex.c index 4a5ba5c0f..3efa2a0e4 100755 --- a/iguana/exchanges/instaforex.c +++ b/iguana/exchanges/instaforex.c @@ -44,7 +44,7 @@ void prices777_instaforex(uint32_t timestamps[NUM_INSTAFOREX],double bids[NUM_IN jsonstr = issue_curl("https://quotes.instaforex.com/get_quotes.php?q=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,XAUUSD&m=json"); if ( jsonstr != 0 ) { - // printf("(%s)\n",jsonstr); + printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { for (i=0; i (%s)\n",url,str); + maxlen = (int32_t)strlen(str); + count = 0; /*EUR/USD,1454354222037,1.08,997,1.09,000,1.08142,1.09130,1.08333 USD/JPY,1454354221120,121.,049,121.,053,120.676,121.496,121.289 GBP/USD,1454354221048,1.44,242,1.44,254,1.42280,1.44305,1.42483 @@ -91,7 +95,7 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl GBP/JPY,1454354221581,174.,602,174.,621,172.408,174.730,172.805 */ - while ( str[n + 0] != 0 && str[n] != '\n' && str[n] != '\r' ) + while ( str[n + 0] != 0 && str[n] != '\n' && str[n] != '\r' && count++ < 10 ) { for (i=jpyflag=0; str[n + i]!=' '&&str[n + i]!='\n'&&str[n + i]!='\r'&&str[n + i]!=0; i++) { @@ -108,7 +112,7 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl memcpy(rel,str+n+4,3), rel[3] = 0; str[n + i] = 0; sprintf(buf,"[%s]",str+n+7+1); - //printf("str.(%s) (%s/%s) %d n.%d i.%d |%s|\n",str+n,base,rel,str[n],n,i,buf); + //printf("%d: str.(%s) (%s/%s) %d n.%d i.%d |%s|\n",count,str+n,base,rel,str[n],n,i,buf); n += i + 1; if ( (array= cJSON_Parse(buf)) != 0 ) { @@ -130,7 +134,9 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl *bidp = bid, *askp = ask, *openp = openval, *highp = high, *lowp = low; *closep = 0; *millistampp = millistamp; - //printf("(%f %f)\n ",bid,ask); + sprintf(name,"%s%s",reqbase,reqrel); + dpow_price("truefx",name,bid,ask); + //printf("[%s%s %f %f] buf.(%s) (%ld)\n ",base,rel,bid,ask,buf,strlen(&str[n])); break; } } @@ -154,6 +160,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang numbids = numasks = 0; bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bid,volume,commission,0,(uint32_t)(millistamp/1000),0); ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,ask,volume,commission,0,(uint32_t)(millistamp/1000),0); + //printf("[%s/%s %.6f %.6f] ",base,rel,bid,ask); if ( bid > SMALLVAL && ask > SMALLVAL ) return((bid + ask) * .5); else return(0); diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index 3475c72a6..b1b632660 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -195,5 +195,6 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n); struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A,struct bitcoin_swapinfo *swap,struct iguana_info *coin); void instantdex_statemachine_iter(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap); void instantdex_historyadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap); +void dpow_price(char *exchange,char *name,double bid,double ask); #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 72f50734a..7872f6bbc 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -99,7 +99,8 @@ struct supernet_info struct dpow_info DPOW; struct delayedPoW_info dPoW; struct basilisk_spend *spends; int32_t numspends; - struct peggy_info *PEGS; + //struct peggy_info *PEGS; + void *PAXDATA; struct liquidity_info linfos[64]; struct komodo_notaries NOTARY; // compatibility diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 8ff60232a..a053cc627 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -736,7 +736,7 @@ void exchanges777_loop(void *ptr) int32_t flag,retval,i; struct exchange_request *req; char *retstr; myinfo = SuperNET_MYINFO(0); #ifdef INCLUDE_PAX - struct peggy_info *PEGS=0; int32_t peggyflag = 0; + /*struct peggy_info *PEGS=0; int32_t peggyflag = 0; if ( strcmp(exchange->name,"PAX") == 0 ) { if ( (PEGS= myinfo->PEGS) != 0 ) @@ -746,23 +746,12 @@ void exchanges777_loop(void *ptr) _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); PEGS->lastupdate = (uint32_t)time(NULL); } - } + }*/ #endif printf("exchanges loop.(%s)\n",exchange->name); while ( 1 ) { -#ifdef INCLUDE_PAX - if ( peggyflag != 0 && PEGS != 0 ) - { - //printf("nonz peggy\n"); - PAX_idle(PEGS,peggyflag,3); - if ( time(NULL) > PEGS->lastupdate+100 ) - { - _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); - PEGS->lastupdate = (uint32_t)time(NULL); - } - } -#endif + PAX_idle(myinfo); flag = retval = 0; retstr = 0; if ( (req= queue_dequeue(&exchange->requestQ,0)) != 0 ) @@ -1133,8 +1122,11 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle for (i=0; iname)) == 0 ) { - if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) + if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforex") == 0 ) + { + exchange->pollgap = 10; continue; + } if ( ((exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 && (exchange= exchange_create(Exchange_funcs[i]->name,0)) != 0) || (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; } diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index 2a09c7ea4..c0e395583 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -15,10 +15,6 @@ // Todo list: -// ht specific notarized ht - -// a) award 5% APR for utxo older than a week when they are spent - // q) investigate if rebroadcast reorged local chain notary tx and scanning mempool is needed #define CHECKSIG 0xac @@ -32,6 +28,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t #include "dpow/dpow_rpc.c" #include "dpow/dpow_tx.c" #include "dpow/dpow_fsm.c" +#include "dpow/dpow_prices.c" void dpow_fifoupdate(struct supernet_info *myinfo,struct dpow_checkpoint *fifo,struct dpow_checkpoint tip) { diff --git a/iguana/peggy.c b/iguana/peggy.c index 4d5b34d06..d2a6dbcca 100755 --- a/iguana/peggy.c +++ b/iguana/peggy.c @@ -280,7 +280,7 @@ struct peggy *peggy_createpair(struct peggy_info *PEGS,int64_t quorum,int64_t de return(PEG); } -struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0) +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t KMD_price0) { //struct peggy_limits limits = { { PERCENTAGE(10), PERCENTAGE(25), PERCENTAGE(33), PERCENTAGE(50) }, SATOSHIDEN * 10000, SATOSHIDEN * 1000, { 0, 30, 90, 180 }, 4 }; struct peggy_lock default_lockparms = { 7, 365, 7, 0, 180, 0, -1 }; @@ -297,8 +297,8 @@ struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincu PEGS->interesttenths = interesttenths, PEGS->posboost = posboost, PEGS->negpenalty = negpenalty, PEGS->feediv = feediv, PEGS->feemult = feemult; mindenom.Pval = PRICE_RESOLUTION; PEGS->genesistime = firsttimestamp; - price.Pval = PEGS->BTCD_price0 = BTCD_price0; - printf("set genesistime.%u BTCD0.%u\n",firsttimestamp,BTCD_price0); + price.Pval = PEGS->KMD_price0 = KMD_price0; + printf("set genesistime.%u BTCD0.%u\n",firsttimestamp,KMD_price0); peggy_createpair(PEGS,0,0,"BTCD","BTCD",0,SATOSHIDEN*1000000,SATOSHIDEN*100000,0,SATOSHIDEN,PEGGY_RATE_777,firsttimestamp,&price,1,spread,0,mindenom,0,1,peggy_mils(0)); //PEGS->accts = accts777_init(path,0); return(PEGS); @@ -414,7 +414,7 @@ struct peggy_info *peggy_genesis(int32_t lookbacks[OPRETURNS_CONTEXTS],struct pe if ( PEGS == 0 ) { spread.Pval = PERCENTAGE(1); - PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,Ptx.timestamp,Ptx.details.price.feed[0]); + PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"KMD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,Ptx.timestamp,Ptx.details.price.feed[0]); //PEGS->accts = accts777_init(path,0); PEGS->genesis = opreturnstr, opreturnstr = 0; } @@ -688,7 +688,7 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t RTblocknum PEGS = peggy_init(path,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); globals[0] = PEGS; sprintf(buf,"%s_PERM",path); - globals[1] = PEGS2 = peggy_init(buf,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,PEGS->genesistime,PEGS->BTCD_price0); + globals[1] = PEGS2 = peggy_init(buf,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,PEGS->genesistime,PEGS->KMD_price0); startmilli = OS_milliseconds(); peggy_clone(buf,PEGS2,PEGS); printf("cloned %d in %.3f millis per opreturn\n",PEGS->numopreturns,(OS_milliseconds() - startmilli)/PEGS->numopreturns); sleep(3);*/ diff --git a/iguana/peggy.h b/iguana/peggy.h index 8487269b4..62cbc0577 100755 --- a/iguana/peggy.h +++ b/iguana/peggy.h @@ -222,7 +222,7 @@ struct PAX_data uint32_t itimestamps[128]; double ibids[128],iasks[128]; char edate[128]; double ecbmatrix[32][32],dailyprices[MAX_CURRENCIES * MAX_CURRENCIES],metals[4]; int32_t ecbdatenum,ecbyear,ecbmonth,ecbday; double RTmatrix[32][32],RTprices[128],RTmetals[4]; - double btcusd,btcdbtc,cryptos[8]; + double btcusd,kmdbtc,cryptos[8]; }; 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; }; @@ -235,8 +235,8 @@ struct peggy_info int32_t default_dailyrate,interesttenths,posboost,negpenalty,feediv,feemult; int32_t numpegs,numpairedpegs,numpricedpegs,numopreturns,numvoters; struct accts777_info *accts; - struct PAX_data data,tmp; double cryptovols[2][9][2],btcusd,btcdbtc,cnyusd; - char path[512],*genesis; uint32_t genesistime,BTCD_price0,lastupdate; + struct PAX_data data,tmp; double cryptovols[2][9][2],btcusd,kmdbtc,cnyusd; + char path[512],*genesis; uint32_t genesistime,KMD_price0,lastupdate; struct PAX_spline splines[128]; struct peggy_vote votes[PEGGY_MAXPRICEDPEGS][PEGGY_MAXVOTERS]; struct peggy *contracts[PEGGY_MAXPEGS]; @@ -308,7 +308,7 @@ extern int32_t MINDENOMS[],Peggy_inds[],dailyrates[]; struct price_resolution peggy_scaleprice(struct price_resolution price,int64_t peggymils); char *peggy_tx(char *jsonstr); void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PAX_data *dp,int32_t selector,int32_t peggyflag); -int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap); +int32_t PAX_idle(struct supernet_info *myinfo);//struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap); 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 PAX_contractnum(char *base,char *rel); int32_t PAX_basenum(char *base); @@ -368,7 +368,7 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t blocknum,u uint32_t peggy_clone(char *path,void *dest,void *src); void *peggy_replay(char *path,struct txinds777_info *opreturns,void *_PEGS,uint32_t blocknum,char *opreturnstr,uint8_t *data,int32_t datalen); uint32_t peggy_currentblock(void *globals); -struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0); +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t KMD_price0); struct peggy_unit *peggy_match(struct accts777_info *accts,int32_t peg,uint64_t nxt64bits,bits256 lockhash,uint16_t lockdays); int32_t peggy_addunit(struct accts777_info *accts,struct peggy_unit *U,bits256 lockhash); diff --git a/iguana/peggy_price.c b/iguana/peggy_price.c index 3f0bc77d1..96e9333d5 100755 --- a/iguana/peggy_price.c +++ b/iguana/peggy_price.c @@ -201,17 +201,17 @@ uint32_t peggy_mils(int32_t i) minmils = 10000; else if ( strncmp(peggy_bases[i],"NXT",3) == 0 || strncmp(peggy_bases[i],"BTS",3) == 0 ) minmils = 1000000; - else if ( strncmp(peggy_bases[i],"STEEM",5) == 0 ) + else if ( strncmp(peggy_bases[i],"KMD",5) == 0 ) minmils = 1000; else minmils = 10000; } return(minmils); } -int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double btcdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) +int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double kmdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) { - double btcdusd,price_in_btcd,dprice,usdcny,usdrub,btccny,btcrub,xauusd,usdprice=0.,usdval,btcprice=0.; int32_t contractnum,base,nonz = 0; - if ( btcusd > SMALLVAL && btcdbtc > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) + 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 && kmdbtc > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) { xauusd = usdcny = usdrub = btccny = btcrub = 0.; for (contractnum=0; contractnumdata.ecbmatrix,sizeof(PEGS->data.ecbmatrix)); PAX_calcmatrix(Hmatrix); /*for (i=0; i<32; i++) @@ -638,11 +638,11 @@ int32_t PAX_getmatrix(double *basevals,struct peggy_info *PEGS,double Hmatrix[32 printf("%s\n",CURRENCIES[i]); }*/ btcusd = PEGS->data.btcusd; - btcdbtc = PEGS->data.btcdbtc; + kmdbtc = PEGS->data.kmdbtc; if ( btcusd > SMALLVAL ) dxblend(&PEGS->btcusd,btcusd,.9); - if ( btcdbtc > SMALLVAL ) - dxblend(&PEGS->btcdbtc,btcdbtc,.9); + if ( kmdbtc > SMALLVAL ) + dxblend(&PEGS->kmdbtc,kmdbtc,.9); // char *cryptostrs[8] = { "btc", "nxt", "unity", "eth", "ltc", "xmr", "bts", "xcp" }; // "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "LTCBTC", "XMRBTC", "BTSBTC", "XCPBTC", // BTC priced for (i=0; i 2 ) - printf("(%f %f) i.%d num.%d %s %f\n",PEGS->btcusd,PEGS->btcdbtc,i,num,contracts[i],RTprices[i]); + printf("(%f %f) i.%d num.%d %s %f\n",PEGS->btcusd,PEGS->kmdbtc,i,num,contracts[i],RTprices[i]); //printf("RT.(%s %f) ",contracts[i],RTprices[i]); } return(PEGS->data.ecbdatenum); @@ -719,7 +719,7 @@ char *peggy_emitprices(int32_t *nonzp,struct peggy_info *PEGS,uint32_t blocktime printf("peggy_emitprices\n"); if ( PAX_getmatrix(basevals,PEGS,matrix,cprices+1,peggy_bases+1,sizeof(peggy_bases)/sizeof(*peggy_bases)-1,blocktimestamp) > 0 ) { - cprices[0] = PEGS->btcdbtc; + cprices[0] = PEGS->kmdbtc; for (i=0; i<32; i++) PEGS->data.RTmatrix[i][i] = basevals[i]; /*for (i=0; i<32; i++) @@ -732,7 +732,7 @@ char *peggy_emitprices(int32_t *nonzp,struct peggy_info *PEGS,uint32_t blocktime memset(prices,0,sizeof(prices)); memset(matrix,0,sizeof(matrix)); memset(RTmatrix,0,sizeof(RTmatrix)); - peggy_prices(prices,PEGS->btcusd,PEGS->btcdbtc,peggy_bases,sizeof(peggy_bases)/sizeof(*peggy_bases),cprices,basevals); + peggy_prices(prices,PEGS->btcusd,PEGS->kmdbtc,peggy_bases,sizeof(peggy_bases)/sizeof(*peggy_bases),cprices,basevals); for (i=0; isplines[MAX_CURRENCIES+0],timestamp,0),PAX_splineval(&PEGS->splines[MAX_CURRENCIES+1],timestamp,0)); - btcd = .01 * PAX_splineval(&PEGS->splines[MAX_CURRENCIES+2],timestamp,0); - if ( btc != 0. && btcd != 0. ) + kmd = .01 * PAX_splineval(&PEGS->splines[MAX_CURRENCIES+2],timestamp,0); + if ( btc != 0. && kmd != 0. ) { - btcdusd = (btc * btcd); + kmdusd = (btc * kmd); usdval = PAX_splineval(&PEGS->splines[USD],timestamp,0); if ( basenum == USD ) - return(1. / btcdusd); - else return(PAX_splineval(&PEGS->splines[basenum],timestamp,0) / (btcdusd * usdval)); + return(1. / kmdusd); + else return(PAX_splineval(&PEGS->splines[basenum],timestamp,0) / (kmdusd * usdval)); } return(0.); } @@ -848,7 +848,7 @@ struct peggy_info *PAX_init() tradebot_monitorall(0,0,0,0,"truefx",commission); tradebot_monitorall(0,0,0,0,"instaforex",commission); spread.Pval = PERCENTAGE(1); - PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); + PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"KMD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); exchange_create("PAX",0); //peggy_priceinits(PEGS,(uint32_t)time(NULL),allprices); return(PEGS); diff --git a/iguana/peggy_update.c b/iguana/peggy_update.c index d23b190f6..1ebee32da 100755 --- a/iguana/peggy_update.c +++ b/iguana/peggy_update.c @@ -47,7 +47,7 @@ static char *Yahoo_metals[] = { YAHOO_METALS }; char CURRENCIES[][8] = { "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", "STEEM", "BTS", "MAID", "XCP", "XMR" // cryptos + "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 @@ -197,10 +197,10 @@ void PAX_btcprices(struct peggy_info *PEGS,int32_t enddatenum,int32_t numdates) { int32_t i,n,year,month,day,seconds,datenum; char url[1024],date[64],*dstr,*str; uint32_t timestamp,utc32[MAX_SPLINES]; struct tai t; - cJSON *coindesk,*quandl,*btcdhist,*bpi,*array,*item; - double btcddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; + 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_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); + sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); if ( (bpi= jobj(coindesk,"bpi")) != 0 ) { datenum = enddatenum; @@ -248,11 +248,13 @@ void PAX_btcprices(struct peggy_info *PEGS,int32_t enddatenum,int32_t numdates) } PAX_genspline(&PEGS->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, btcddaily[i] = price * 100.; + utc32[i] = timestamp - 12*3600, kmddaily[i] = price * 100.; } if ( Debuglevel > 2 ) printf("poloniex.%d\n",n); - PAX_genspline(&PEGS->splines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"btcdhist",utc32,btcddaily,nsplines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"kmdhist",utc32,kmddaily,n 0 && (array= jarray(&n,quandl,"data")) != 0 ) { @@ -430,20 +432,20 @@ void PAX_update(struct peggy_info *PEGS,double *btcusdp,double *btcdbtcp) { double avebid,aveask,bidvol,askvol; 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,"BTCD","BTC",1,argjson); - avebid = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&bidvol,"BTCD","BTC",-1,argjson); + 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 ( avebid > SMALLVAL && aveask > SMALLVAL ) { price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol); - *btcdbtcp = price; - printf("set BTCD price %f\n",price); - PEGS->btcdbtc = price; + *kmdbtcp = price; + printf("set KMD price %f\n",price); + PEGS->kmdbtc = price; } else { - btcdhist = url_json(url); + kmdhist = url_json(url); //{"date":1406160000,"high":0.01,"low":0.00125,"open":0.01,"close":0.001375,"volume":1.50179994,"quoteVolume":903.58818412,"weightedAverage":0.00166204}, - if ( btcdhist != 0 && (array= jarray(&n,btcdhist,0)) != 0 ) + if ( kmdhist != 0 && (array= jarray(&n,kmdhist,0)) != 0 ) { //printf("GOT.(%s)\n",cJSON_Print(array)); for (i=0; i<1; i++) @@ -453,14 +455,14 @@ void PAX_update(struct peggy_info *PEGS,double *btcusdp,double *btcdbtcp) 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); - btcddaily = price; - if ( btcddaily != 0 ) - PEGS->btcdbtc = *btcdbtcp = btcddaily; + kmddaily = price; + if ( kmddaily != 0 ) + PEGS->kmdbtc = *kmdbtcp = kmddaily; } //printf("poloniex.%d\n",n); } - if ( btcdhist != 0 ) - free_json(btcdhist); + if ( kmdhist != 0 ) + free_json(kmdhist); } } if ( bitcoinave != 0 ) @@ -524,19 +526,19 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA { 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", "steem", "xmr", "bts", "xcp", "etc" }; - int32_t iter,i,j; double btcusd,btcdbtc,cnyusd,prices[9][2],volumes[9][2]; + 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],*str; cJSON *jsonA,*jsonB; if ( peggyflag != 0 ) { cnyusd = PEGS->cnyusd; btcusd = PEGS->btcusd; - btcdbtc = PEGS->btcdbtc; - //printf("update with btcusd %f btcd %f cnyusd %f cnybtc %f\n",btcusd,btcdbtc,cnyusd,cnyusd/btcusd); - if ( btcusd < SMALLVAL || btcdbtc < SMALLVAL ) + kmdbtc = PEGS->kmdbtc; + //printf("update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd); + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { - PAX_update(PEGS,&btcusd,&btcdbtc); - printf("PAX_update with btcusd %f btcd %f\n",btcusd,btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); + printf("PAX_update with btcusd %f kmd %f\n",btcusd,kmdbtc); } memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); @@ -553,7 +555,7 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA for (iter=0; iter<1; iter++) { if ( i == 0 && iter == 0 ) - strcpy(base,"btcd"), strcpy(rel,"btc"); + strcpy(base,"kmd"), strcpy(rel,"btc"); else strcpy(base,str), strcpy(rel,iter==0?"btc":"cny"); //if ( selector == 0 ) { @@ -587,10 +589,10 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][9][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) { - char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "steem", "xmr", "bts", "xcp" }; - int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,btcdbtc,bid,ask,price,vol,prices[8][2],volumes[8][2]; + 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,ask,price,vol,prices[8][2],volumes[8][2]; char base[16],rel[16]; - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); for (i=0; i SMALLVAL ) - dxblend(&btcdbtc,prices[0][0],.9); - dxblend(&dp->btcdbtc,btcdbtc,.995); - if ( PEGS->btcdbtc < SMALLVAL ) - PEGS->btcdbtc = dp->btcdbtc; + dxblend(&kmdbtc,prices[0][0],.9); + dxblend(&dp->kmdbtc,kmdbtc,.995); + if ( PEGS->kmdbtc < SMALLVAL ) + PEGS->kmdbtc = dp->kmdbtc; if ( (cnyusd= PEGS->cnyusd) > SMALLVAL ) { if ( prices[0][1] > SMALLVAL ) @@ -633,15 +635,15 @@ void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][9][2],double RTme } } btcusd = PEGS->btcusd; - btcdbtc = PEGS->btcdbtc; + kmdbtc = PEGS->kmdbtc; if ( Debuglevel > 2 ) - printf(" update with btcusd %f btcd %f\n",btcusd,btcdbtc); - if ( btcusd < SMALLVAL || btcdbtc < SMALLVAL ) + printf(" update with btcusd %f kmd %f\n",btcusd,kmdbtc); + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); if ( Debuglevel > 2 ) - printf(" price777_update with btcusd %f btcd %f\n",btcusd,btcdbtc); - } else PEGS->btcusd = btcusd, PEGS->btcdbtc = btcdbtc; + printf(" price777_update with btcusd %f kmd %f\n",btcusd,kmdbtc); + } else PEGS->btcusd = btcusd, PEGS->kmdbtc = kmdbtc; for (c=0; ctmp; *dp = PEGS->data; if ( didinit == 0 ) @@ -717,7 +719,7 @@ int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap) //prices777_init(BUNDLE.jsonstr,peggyflag); didinit = 1; datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); - expand_datenum(PEGS->data.edate,datenum); + expand_datenum(dp->edate,datenum); if ( peggyflag != 0 ) { //int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); @@ -752,15 +754,15 @@ int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap) dp->itimestamps[contractnum] = bidasks[0].timestamp; } } - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); if ( btcusd > SMALLVAL ) dxblend(&dp->btcusd,btcusd,0.99); - if ( btcdbtc > SMALLVAL ) - dxblend(&dp->btcdbtc,btcdbtc,0.99); + if ( kmdbtc > SMALLVAL ) + dxblend(&dp->kmdbtc,kmdbtc,0.99); if ( dp->btcusd == 0 ) dp->btcusd = dp->btcusd; - if ( dp->btcdbtc == 0 ) - dp->btcdbtc = dp->btcdbtc; + if ( dp->kmdbtc == 0 ) + dp->kmdbtc = dp->kmdbtc; if ( dp->ecbmatrix[USD][USD] > SMALLVAL && dp->ecbmatrix[CNY][CNY] > SMALLVAL ) PEGS->cnyusd = (dp->ecbmatrix[CNY][CNY] / dp->ecbmatrix[USD][USD]); portable_mutex_lock(&mutex); diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 0e9283b55..59fe53824 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -308,6 +308,12 @@ SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) return(jprint(retjson,1)); } +ZERO_ARGS(pax,start) +{ + void PAX_init(); + PAX_init(); + return(clonestr("{\"result\":\"PAX_init called\"}")); +} #undef IGUANA_ARGS #include "../includes/iguana_apiundefs.h" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 7cfcfc747..e33255cea 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -21,9 +21,7 @@ ZERO_ARGS(dpow,cancelratify); TWO_STRINGS(zcash,passthru,function,hex); TWO_STRINGS(komodo,passthru,function,hex); -#ifdef INCLUDE_PAX ZERO_ARGS(pax,start); -#endif HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); ZERO_ARGS(tradebot,amlp); ZERO_ARGS(tradebot,notlp);