You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1969 lines
87 KiB

8 years ago
/******************************************************************************
8 years ago
* Copyright © 2014-2017 The SuperNET Developers. *
8 years ago
* *
* 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. *
* *
******************************************************************************/
8 years ago
#include "../exchanges777.h"
8 years ago
#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];
8 years ago
double basevals[MAX_CURRENCIES],cryptovols[2][9][2],BTCDBTC,BTCUSD,KMDBTC,CNYUSD,btcusd,kmdbtc,cryptos[8];
8 years ago
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,
8 years ago
};
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.);
}
};
8 years ago
#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<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
{
if ( strncmp(CURRENCIES[i],contract,strlen(CURRENCIES[i])) == 0 )
{
for (j=0; j<sizeof(CURRENCIES)/sizeof(*CURRENCIES); j++)
if ( strcmp(CURRENCIES[j],contract+strlen(CURRENCIES[i])) == 0 )
{
strcpy(base,CURRENCIES[i]);
strcpy(rel,CURRENCIES[j]);
/*USDCNY 6.209700 -> 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<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
for (j=0; j<sizeof(CURRENCIES)/sizeof(*CURRENCIES); j++)
if ( i != j && strcmp(CURRENCIES[i],CURRENCIES[j]) == 0 )
printf("duplicate.(%s)\n",CURRENCIES[i]);//, getchar();
}
for (i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
if ( strcmp(CURRENCIES[i],base) == 0 )
return(i);
return(-1);
}
int32_t PAX_contractnum(char *base,char *rel)
{
int32_t i,j,c; char contractstr[16],*contract = 0;
if ( 0 )
{
for (i=0; i<sizeof(CONTRACTS)/sizeof(*CONTRACTS); i++)
for (j=0; j<sizeof(CONTRACTS)/sizeof(*CONTRACTS); j++)
if ( i != j && strcmp(CONTRACTS[i],CONTRACTS[j]) == 0 )
printf("duplicate.(%s)\n",CONTRACTS[i]);//, getchar();
}
if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 )
{
for (i=0; i<NUM_CURRENCIES; i++)
if ( strcmp(base,CURRENCIES[i]) == 0 )
{
for (j=0; j<NUM_CURRENCIES; j++)
if ( strcmp(rel,CURRENCIES[j]) == 0 )
return(Baserel_contractnum[i][j]);
break;
}
sprintf(contractstr,"%s%s",base,rel);
contract = contractstr;
} else contract = base;
if ( contract != 0 && contract[0] != 0 )
{
for (c=0; c<sizeof(CONTRACTS)/sizeof(*CONTRACTS); c++)
if ( strcmp(CONTRACTS[c],contract) == 0 )
return(c);
}
return(-1);
}
int32_t PAX_mindenomination(int32_t base)
{
return(MINDENOMS[base]);
}
struct price_resolution peggy_scaleprice(struct price_resolution price,int64_t peggymils)
{
price.Pval = (10000 * price.Pval) / peggymils;
return(price);
}
void norm_smooth_wts(int32_t j,double *smoothwts,int32_t n,int32_t numiters)
{
double wt; int32_t iter,i;
for (iter=0; iter<numiters; iter++)
{
wt = 0.;
for (i=0; i<n; i++)
wt += smoothwts[i];
//printf("wtsum.j%d %.40f ",j,wt);
for (i=0; i<n; i++)
smoothwts[i] /= wt;
}
//printf("\n");
}
void calc_smooth_code(int32_t smoothwidth,int32_t _maxprimes)
{
double _coeffs[5000],sum,coeffs[60][10000],smoothbuf[10000]; int32_t x,p,prime,numprimes; uint64_t val,isum = 0;
_maxprimes = MIN((int32_t)(sizeof(coeffs)/(sizeof(double)*10000))-1,_maxprimes);
smoothwidth = MIN((int32_t)(sizeof(_coeffs)/sizeof(*_coeffs)),smoothwidth);
x = 5000;
memset(smoothbuf,0,sizeof(smoothbuf));
coeffs[0][x-2] = coeffs[0][x] = coeffs[0][x+2] = 1./3.;
for (numprimes=_maxprimes; numprimes>=3; numprimes--)
{
for (p=1; p<numprimes; p++)
{
memcpy(coeffs[p],coeffs[p-1],sizeof(coeffs[p]));
prime = sprimes[p];
for (x=0; x<10000; x++)
{
coeffs[p][x] += (coeffs[p-1][x - prime] / 3.);
coeffs[p][x] += (coeffs[p-1][x] / 3.);
coeffs[p][x] += (coeffs[p-1][x + prime] / 3.);
}
}
memcpy(smoothbuf,coeffs[numprimes-1],sizeof(smoothbuf));
memset(coeffs,0,sizeof(coeffs));
sum = 0.;
for (x=0; x<10000; x++)
{
if ( smoothbuf[x] != 0. )
{
sum += smoothbuf[x];
//printf("(%d %f) ",x-5000,smoothbuf[x]);
}
}
//printf("maxprimes.%d\n",maxprimes);
for (x=0; x<10000; x++)
coeffs[0][x] = (smoothbuf[x] / sum);
}
sum = 0.;
for (x=0; x<10000; x++)
sum += smoothbuf[x];
memset(coeffs,0,sizeof(coeffs));
if ( sum != 0. )
{
printf("double Smooth_coeffs[%d] = // numprimes.%d\n{\n",smoothwidth,_maxprimes);
for (x=0; x<10000; x++)
{
if ( smoothbuf[x] != 0. )
{
smoothbuf[x] = (1000000. * 1000000. * smoothbuf[x]) / sum;
//printf("(%d %f) ",x-5000,smoothbuf[x]);
}
}
_coeffs[0] = smoothbuf[5000];
for (x=1; x<=smoothwidth; x++)
{
if ( fabs(smoothbuf[5000 - x] - smoothbuf[5000 + x]) > 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<smoothwidth; x++)
sum += _coeffs[x];
if ( sum != 0. )
{
for (x=0; x<smoothwidth; x++)
{
val = ((SATOSHIDEN * 1000. * _coeffs[x] + sum*.4825) / sum);
printf("%lld, ",(long long)val);
isum += val;
//printf("%.0f, ",SATOSHIDEN*1000*_coeffs[x]/sum);
if ( (x%9) == 8 )
printf("// x.%d\n",x);
}
printf("// isum %lld\n",(long long)isum);
}
}
printf("\n}; // %llu\n",(long long)isum);
//printf("_Constants size %d\n",(int)__constant_size);
}
uint32_t peggy_mils(int32_t i)
{
uint32_t minmils = 0;
if ( i == 0 )
return(1000000);
else if ( i <= MAX_CURRENCIES )
minmils = 10 * PAX_mindenomination(i-1);
else if ( i >= 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<num; contractnum++)
if ( strcmp(contracts[contractnum],"XAUUSD") == 0 )
{
xauusd = cprices[contractnum];
break;
}
if ( basevals[8] > 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<NUM_CURRENCIES; base++)
{
basemask = 0L;
for (j=0; j<7; j++)
{
if ( (c= Currency_contracts[base][j]) >= 0 )
{
basemask |= (1L << c);
//printf("(%s %lx) ",CONTRACTS[c],1L<<c);
}
}
Currencymasks[base] = basemask;
printf("0x%llx, ",(long long)basemask);
}
}
double calc_primary_currencies(double logmatrix[8][8],double *bids,double *asks)
{
uint64_t nonzmask; int32_t c,base,rel; double bid,ask;
memset(logmatrix,0,sizeof(double)*8*8);
nonzmask = 0;
for (c=0; c<28; c++)
{
bid = bids[c];
ask = asks[c];
if ( bid != 0 && ask != 0 )
{
base = Contract_base[c];
rel = Contract_rel[c];
nonzmask |= (1L << c);
logmatrix[base][rel] = log(bid);
logmatrix[rel][base] = -log(ask);
//printf("[%f %f] ",bid,ask);
}
}
//printf("%07lx\n",nonzmask);
if ( nonzmask != 0 )
{
bids[USDNUM] = (logmatrix[USD][EUR] + logmatrix[USD][JPY] + logmatrix[USD][GBP] + logmatrix[USD][AUD] + logmatrix[USD][CAD] + logmatrix[USD][CHF] + logmatrix[USD][NZD]) / 8.;
asks[USDNUM] = -(logmatrix[EUR][USD] + logmatrix[JPY][USD] + logmatrix[GBP][USD] + logmatrix[AUD][USD] + logmatrix[CAD][USD] + logmatrix[CHF][USD] + logmatrix[NZD][USD]) / 8.;
bids[EURNUM] = (logmatrix[EUR][USD] + logmatrix[EUR][JPY] + logmatrix[EUR][GBP] + logmatrix[EUR][AUD] + logmatrix[EUR][CAD] + logmatrix[EUR][CHF] + logmatrix[EUR][NZD]) / 8.;
asks[EURNUM] = -(logmatrix[USD][EUR] + logmatrix[JPY][EUR] + logmatrix[GBP][EUR] + logmatrix[AUD][EUR] + logmatrix[CAD][EUR] + logmatrix[CHF][EUR] + logmatrix[NZD][EUR]) / 8.;
bids[JPYNUM] = (logmatrix[JPY][USD] + logmatrix[JPY][EUR] + logmatrix[JPY][GBP] + logmatrix[JPY][AUD] + logmatrix[JPY][CAD] + logmatrix[JPY][CHF] + logmatrix[JPY][NZD]) / 8.;
asks[JPYNUM] = -(logmatrix[USD][JPY] + logmatrix[EUR][JPY] + logmatrix[GBP][JPY] + logmatrix[AUD][JPY] + logmatrix[CAD][JPY] + logmatrix[CHF][JPY] + logmatrix[NZD][JPY]) / 8.;
bids[GBPNUM] = (logmatrix[GBP][USD] + logmatrix[GBP][EUR] + logmatrix[GBP][JPY] + logmatrix[GBP][AUD] + logmatrix[GBP][CAD] + logmatrix[GBP][CHF] + logmatrix[GBP][NZD]) / 8.;
asks[GBPNUM] = -(logmatrix[USD][GBP] + logmatrix[EUR][GBP] + logmatrix[JPY][GBP] + logmatrix[AUD][GBP] + logmatrix[CAD][GBP] + logmatrix[CHF][GBP] + logmatrix[NZD][GBP]) / 8.;
bids[AUDNUM] = (logmatrix[AUD][USD] + logmatrix[AUD][EUR] + logmatrix[AUD][JPY] + logmatrix[AUD][GBP] + logmatrix[AUD][CAD] + logmatrix[AUD][CHF] + logmatrix[AUD][NZD]) / 8.;
asks[AUDNUM] = -(logmatrix[USD][AUD] + logmatrix[EUR][AUD] + logmatrix[JPY][AUD] + logmatrix[GBP][AUD] + logmatrix[CAD][AUD] + logmatrix[CHF][AUD] + logmatrix[NZD][AUD]) / 8.;
bids[CADNUM] = (logmatrix[CAD][USD] + logmatrix[CAD][EUR] + logmatrix[CAD][JPY] + logmatrix[CAD][GBP] + logmatrix[CAD][AUD] + logmatrix[CAD][CHF] + logmatrix[CAD][NZD]) / 8.;
asks[CADNUM] = -(logmatrix[USD][CAD] + logmatrix[EUR][CAD] + logmatrix[JPY][CAD] + logmatrix[GBP][CAD] + logmatrix[AUD][CAD] + logmatrix[CHF][CAD] + logmatrix[NZD][CAD]) / 8.;
bids[CHFNUM] = (logmatrix[CHF][USD] + logmatrix[CHF][EUR] + logmatrix[CHF][JPY] + logmatrix[CHF][GBP] + logmatrix[CHF][AUD] + logmatrix[CHF][CAD] + logmatrix[CHF][NZD]) / 8.;
asks[CHFNUM] = -(logmatrix[USD][CHF] + logmatrix[EUR][CHF] + logmatrix[JPY][CHF] + logmatrix[GBP][CHF] + logmatrix[AUD][CHF] + logmatrix[CAD][CHF] + logmatrix[NZD][CHF]) / 8.;
bids[NZDNUM] = (logmatrix[NZD][USD] + logmatrix[NZD][EUR] + logmatrix[NZD][JPY] + logmatrix[NZD][GBP] + logmatrix[NZD][AUD] + logmatrix[NZD][CAD] + logmatrix[NZD][CHF]) / 8.;
asks[NZDNUM] = -(logmatrix[USD][NZD] + logmatrix[EUR][NZD] + logmatrix[JPY][NZD] + logmatrix[GBP][NZD] + logmatrix[AUD][NZD] + logmatrix[CAD][NZD] + logmatrix[CHF][NZD]) / 8.;
if ( nonzmask != ((1<<28)-1) )
{
for (base=0; base<8; base++)
{
if ( (nonzmask & Currencymasks[base]) != Currencymasks[base] )
bids[base+28] = asks[base+28] = 0;
//else printf("%s %9.6f | ",CONTRACTS[base+28],_pairaved(bids[base+28],asks[base+28]));
}
//printf("keep.%07lx\n",nonzmask);
return(0);
}
if ( 0 && nonzmask != 0 )
{
for (base=0; base<8; base++)
printf("%9.6f | ",_pairaved(bids[base+28],asks[base+28]));
printf("%07llx\n",(long long)nonzmask);
}
}
return(0);
}
double PAX_splineval(struct PAX_spline *spline,uint32_t timestamp,int32_t lookahead)
{
int32_t i,gap,ind = (spline->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; i<spline->num-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<MAX_SPLINES&&i<num; i++)
{
if ( (f[n]= splinevals[i]) != 0. && utc32[i] != 0 )
{
//printf("i%d.(%u %f) ",i,utc32[i],splinevals[i]);
8 years ago
//printf("%f ",splinevals[i]);
8 years ago
if ( n > 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<n-3; i++)
dl[i] = du[i] = gaps[i+1];
for (i=0; i<n-2; i++)
{
dd[i] = 2.0 * (gaps[i] + gaps[i+1]);
c[i] = (3.0 / (double)gaps[i+1]) * (f[i+2] - f[i+1]) - (3.0 / (double)gaps[i]) * (f[i+1] - f[i]);
}
//for (i=0; i<n; i++)
// printf("%f ",f[i]);
//printf("F2[%d]\n",n);
dd[0] += (gaps[0] + (double)gaps[0]*gaps[0] / gaps[1]);
du[0] -= ((double)gaps[0]*gaps[0] / gaps[1]);
dd[n-3] += (gaps[n-2] + (double)gaps[n-2]*gaps[n-2] / gaps[n-3]);
dl[n-4] -= ((double)gaps[n-2]*gaps[n-2] / gaps[n-3]);
//tridiagonal(n-2, dl, dd, du, c);
for (i=0; i<n-1-2; i++)
{
du[i] /= dd[i];
dd[i+1] -= dl[i]*du[i];
}
c[0] /= dd[0];
for (i=1; i<n-2; i++)
c[i] = (c[i] - dl[i-1] * c[i-1]) / dd[i];
for (i=n-2-4; 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; i<n; i++)
{
vx = f[i];
vz = c[i];
if ( i < n-1 )
{
gap = gaps[i];
vy = ((f[i+1] - f[i]) / gap) - (gap * (c[i+1] + 2.*c[i]) / 3.);
vw = (c[i+1] - c[i]) / (3. * gap);
}
else
{
vy = 0;
vw = 0;
}
//printf("%3d: t%u [%14.11f %14.11f %14.11f %14.11f] gap %f | %d\n",i,spline->utc32[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; i<spline->num; i++)
{
if ( i < spline->num )
{
8 years ago
if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] )
8 years ago
printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i);
spline->pricevals[i] = output[i * 24];
}
}
8 years ago
//printf("spline.%s num.%d\n",name,spline->num);
8 years ago
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<numbase; basenum++)
{
for (vsum=sum=vnum=nonz=relnum=0; relnum<numbase; relnum++)
{
if ( basenum != relnum )
{
if ( (price= matrix[basenum][relnum]) != 0. )
{
price /= (MINDENOMS[relnum] * .001);
price *= (MINDENOMS[basenum] * .001);
if ( iter == 0 )
sum += (price), nonz++;//, printf("%.8f ",price);
else sum += fabs((price) - (basevals[basenum] / basevals[relnum])), nonz++;
}
if ( (price2= matrix[relnum][basenum]) != 0. )
{
price2 *= (MINDENOMS[relnum] * .001);
price2 /= (MINDENOMS[basenum] * .001);
if ( iter == 0 )
vsum += (price2), vnum++;
else vsum += fabs(price2 - (basevals[relnum] / basevals[basenum])), vnum++;
}
//if ( iter == 0 && 1/price2 > 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; relnum<numbase; relnum++)
sum += (basevals[relnum]);//, printf("%.8f ",(basevals[relnum]));
//printf("date.%d sums %.8f and vsums iter.%d\n",relnum,sum/7,iter);
sum /= (numbase - 1);
for (relnum=0; relnum<numbase; relnum++)
basevals[relnum] /= sum;//, printf("%.8f ",basevals[relnum]);
//printf("date.%d sums %.8f and vsums iter.%d\n",i,sum,iter);
}
else
{
for (basenum=0; basenum<numbase; basenum++)
matrix[basenum][basenum] = basevals[basenum];
}
}
if ( numerrs != 0 )
errsum /= numerrs;
return(errsum);
}
int32_t PAX_getmatrix(double *basevals,struct PAX_data *dp,double Hmatrix[32][32],double *RTprices,char *contracts[],int32_t num)
{
int32_t i,j,c; char name[16]; double btcusd,kmdbtc;
memcpy(Hmatrix,dp->ecbmatrix,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; i<num; i++)
{
if ( contracts[i] == 0 )
continue;
if ( i == num-1 && strcmp(contracts[i],"BTCUSD") == 0 )
{
RTprices[i] = dp->BTCUSD;
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; j<sizeof(Yahoo_metals)/sizeof(*Yahoo_metals); j++)
{
sprintf(name,"%sUSD",Yahoo_metals[j]);
if ( contracts[i] != 0 && strcmp(name,contracts[i]) == 0 )
{
RTprices[i] = dp->RTmetals[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<sizeof(PAX_bases)/sizeof(*PAX_bases); i++)
{
pvals[i] = 0;
if ( (prices[i].Pval= basevals[i]*1000000000) != 0 )
{
nonz++;
if ( prices[i].Pval > 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; i<sizeof(Yahoo_metals)/sizeof(*Yahoo_metals); i++)
if ( strncmp(Yahoo_metals[i],contract,3) == 0 && strcmp(contract+3,"USD") == 0 )
{
yprice = dp->metals[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
8 years ago
// http://finance.yahoo.com/webservice/v1/symbols/EUR=USD/quote?format=json
8 years ago
// 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)
{
8 years ago
int32_t i,n,year,month,day,seconds,datenum; char url[1024],url2[1024],date[64],*dstr,*str;
8 years ago
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&currencyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24));
8 years ago
sprintf(url2,"https://poloniex.com/public?command=returnChartData&currencyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24));
8 years ago
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; i<numdates; i++)
{
expand_datenum(date,datenum);
if ( (price= jdouble(bpi,date)) != 0 )
{
utc32[numdates - 1 - i] = OS_conv_datenum(datenum,12,0,0);
cdaily[numdates - 1 - i] = price * .001;
if ( i == 0 )
dpow_price("bpi","BTCUSD",price,price);
//printf("(%s %u %f) ",date,utc32[numdates - 1 - i],price);
}
datenum = ecb_decrdate(&year,&month,&day,date,datenum);
}
PAX_genspline(&dp->splines[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<n&&i<MAX_SPLINES; 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 ( Debuglevel > 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<MAX_SPLINES?n:MAX_SPLINES,qdaily);
}
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 ( (array= jarray(&n,kmdhist,0)) != 0 )
{
memset(utc32,0,sizeof(utc32)), memset(kmddaily,0,sizeof(kmddaily));
for (i=0; i<MAX_SPLINES; i++)
kmddaily[i] = 0.0001 * 100.;
//printf("GOT.(%s)\n",cJSON_Print(array));
for (i=0; i<n; 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);
if ( Debuglevel > 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<MAX_SPLINES?n:MAX_SPLINES,kmddaily);
}
// https://poloniex.com/public?command=returnChartData&currencyPair=BTC_KMD&start=1405699200&end=9999999999&period=86400
}
int32_t PAX_ecbparse(char *date,double *prices,char *url,int32_t basenum)
{
char *jsonstr,*relstr,*basestr,name[16]; int32_t count=0,i,relnum; cJSON *json,*ratesobj,*item; struct destbuf tmp;
if ( (jsonstr= issue_curl(url)) != 0 )
{
8 years ago
if ( Debuglevel > 2 )
8 years ago
printf("(%s)\n",jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
8 years ago
if ( jobj(json,"error") != 0 || jobj(json,"date") == 0 )
8 years ago
{
8 years ago
printf("Got error from fixer.io (%s)\n",jsonstr);
8 years ago
sleep(10);
8 years ago
}
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 )
8 years ago
{
8 years ago
while ( item != 0 )
8 years ago
{
8 years ago
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;
}
8 years ago
}
}
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<sizeof(CURRENCIES)/sizeof(*CURRENCIES); basenum++)
{
8 years ago
if ( strcmp(CURRENCIES[basenum],"XAU") == 0 || basenum >= MAX_CURRENCIES )
8 years ago
break;
if ( iter == 0 )
{
sprintf(url,"%s%s",baseurl,CURRENCIES[basenum]);
count += PAX_ecbparse(basenum == 0 ? date : tmpdate,prices,url,basenum);
8 years ago
usleep(100000);
8 years ago
if ( (basenum != 0 && strcmp(tmpdate,date) != 0) || (checkdate[0] != 0 && strcmp(checkdate,date) != 0) )
{
8 years ago
//printf("date mismatch (%s) != (%s) or checkdate.(%s)\n",tmpdate,date,checkdate);
8 years ago
return(-1);
}
}
else
{
for (nonz=i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
{
8 years ago
if ( strcmp(CURRENCIES[i],"XAU") == 0 || i >= MAX_CURRENCIES )
8 years ago
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));
8 years ago
//printf("ecb_matrix(%s)\n",date);
8 years ago
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);
8 years ago
} else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp);
8 years ago
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);
}
8 years ago
} //else printf("peggy_matrix error loading %d.%d.%d\n",year,month,day);
8 years ago
}
else
{
PAX_calcmatrix(matrix);
for (baseid=0; baseid<MAX_CURRENCIES-1; baseid++)
for (relid=baseid+1; relid<MAX_CURRENCIES; relid++)
{
bid = ask = 0.;
sprintf(name,"%s%s",CURRENCIES[baseid],CURRENCIES[relid]);
if ( (price= matrix[relid][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<MAX_CURRENCIES; baseid++)
basevals[baseid] = matrix[baseid][baseid];
}
if ( loaded == 0 && n == 0 )
{
printf("peggy_matrix couldnt process loaded.%d n.%d\n",loaded,n);
return(-1);
}
//"2000-01-03"
if ( (datenum= conv_date(&seconds,date)) < 0 )
return(-1);
8 years ago
//printf("loaded.(%s) nonz.%d (%d %d %d) datenum.%d\n",date,n,year,month,day,datenum);
8 years ago
return(datenum);
}
void PAX_update(struct PAX_data *dp,double *btcusdp,double *kmdbtcp)
{
8 years ago
int32_t i,n,iter,seconds,datenum; uint32_t timestamp; char url[1024],url2[1024],*dstr,*str;
8 years ago
double kmddaily=0.,btcusd=0.,ask,high,low,bid,close,vol,quotevol,open,price = 0.;
7 years ago
//cJSON *kmdtrades,*kmdtrades2,*,*bitcoincharts,;
8 years ago
cJSON *quandl,*kmdhist,*array,*item,*bitcoinave,*blockchaininfo,*btctrades,*coindesk=0;
sprintf(url,"https://poloniex.com/public?command=returnTradeHistory&currencyPair=USDT_BTC&start=%u&end=%u",(uint32_t)time(NULL)-60,(uint32_t)time(NULL));
7 years ago
btctrades = url_json(url);
8 years ago
//kmdtrades = url_json("https://poloniex.com/public?command=returnTradeHistory&currencyPair=USDT_BTC");
//kmdtrades2 = url_json("https://bittrex.com/api/v1.1/public/getmarkethistory?market=BTC-KMD&count=50");
8 years ago
*kmdbtcp = 0;
8 years ago
bitcoinave = 0;//url_json("https://api.bitcoinaverage.com/ticker/USD/");
//bitcoincharts = url_json("http://api.bitcoincharts.com/v1/weighted_prices.json");
7 years ago
blockchaininfo = url_json("https://blockchain.info/ticker");
8 years ago
coindesk = 0;//url_json("http://api.coindesk.com/v1/bpi/historical/close.json");
8 years ago
sprintf(url,"https://poloniex.com/public?command=returnChartData&currencyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-3600*24));
sprintf(url2,"https://poloniex.com/public?command=returnChartData&currencyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-3600*24));
8 years ago
quandl = 0;//url_json("https://www.quandl.com/api/v1/datasets/BAVERAGE/USD.json?rows=1");
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));
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);
}
}
}
8 years ago
if ( 1 )
8 years ago
{
7 years ago
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("{}");
8 years ago
//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 )
8 years ago
{
price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol);
*kmdbtcp = price;
printf("set KMD price %f\n",price);
dp->KMDBTC = price;
}
8 years ago
else if ( (dp->KMDBTC= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,"komodo","KMD","BTC",&USD_average)) > SMALLVAL )
8 years ago
*kmdbtcp = dp->KMDBTC;
8 years ago
else
{
8 years ago
for (iter=1; iter<2; iter++)
8 years ago
{
8 years ago
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 )
8 years ago
{
8 years ago
//printf("GOT.(%s)\n",cJSON_Print(array));
8 years ago
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");
8 years ago
//printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price);
8 years ago
//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;
}
}
8 years ago
//printf("poloniex.%d\n",n);
8 years ago
}
8 years ago
if ( kmdhist != 0 )
free_json(kmdhist);
8 years ago
}
}
}
8 years ago
if ( (*kmdbtcp= dp->KMDBTC) == 0. )
*kmdbtcp = dp->BTCDBTC / 50.22;
8 years ago
if ( (rand() % 100) == 0 )
printf("KMD/BTC %.8f\n",*kmdbtcp);
8 years ago
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);
7 years ago
printf("blockchaininfo %f %f\n",btcusd,price);
8 years ago
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. )
8 years ago
;//kmdbtc = dp->BTCDBTC / 50.22;
printf("DEPRECATED: update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd);
return;
8 years ago
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<sizeof(cryptostrs)/sizeof(*cryptostrs); j++)
{
str = cryptostrs[j];
/*if ( strcmp(str,"etc") == 0 )
{
if ( prices[3][0] > 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" };
8 years ago
int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,kmdbtc,bid=0.,ask=0.,price,vol,prices[8][2],volumes[8][2];
8 years ago
char base[16],rel[16];
PAX_update(dp,&btcusd,&kmdbtc);
memset(prices,0,sizeof(prices));
memset(volumes,0,sizeof(volumes));
for (i=0; i<sizeof(cryptostrs)/sizeof(*cryptostrs); i++)
for (iter=0; iter<2; iter++)
{
prices[i][iter] = cryptovols[0][i][iter];
volumes[i][iter] = cryptovols[1][i][iter];
}
if ( prices[0][0] > 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<sizeof(cryptostrs)/sizeof(*cryptostrs); i++)
{
vol = volumes[i][0];
vol += volumes[i][1];
if ( vol > 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; c<sizeof(CONTRACTS)/sizeof(*CONTRACTS); c++)
{
for (iter=0; iter<3; iter++)
{
switch ( iter )
{
case 0: bid = dp->tbids[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; i<sizeof(Yahoo_metals)/sizeof(*Yahoo_metals); i++)
if ( dp->metals[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);
}
8 years ago
double PAX_val(uint32_t pval,int32_t baseid)
{
if ( baseid >= 0 && baseid < MAX_CURRENCIES )
return(((double)pval / 1000000000.) / MINDENOMS[baseid]);
return(0.);
}
8 years ago
void PAX_genecbsplines(struct PAX_data *dp)
{
8 years ago
static portable_mutex_t mutex; static int32_t initflag;
8 years ago
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;
8 years ago
if ( initflag == 0 )
{
portable_mutex_init(&mutex);
initflag = 1;
}
portable_mutex_lock(&mutex);
8 years ago
for (i=numsamples=0; i<28; i++)
8 years ago
{
8 years ago
datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(28-i+1)*24*3600);
8 years ago
expand_datenum(dp->edate,datenum);
timestamp = OS_conv_datenum(datenum,12,0,0);
8 years ago
printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp);
8 years ago
if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 )
{
utc32[numsamples] = timestamp;
for (j=0; j<MAX_CURRENCIES; j++)
{
pvals[j] = PAX_val32(dp->basevals[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; j<MAX_CURRENCIES; j++)
{
PAX_genspline(&dp->splines[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;
8 years ago
//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]);
8 years ago
PAX_genspline(&dp->splines[j],j,CURRENCIES[j],utc32,prices[j],numsamples+3,prices[j]);
}
8 years ago
portable_mutex_unlock(&mutex);
8 years ago
}
7 years ago
#define BTCFACTOR_TIMESTAMP 1503746319
#define BTCFACTOR_HEIGHT 466266
8 years ago
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;
8 years ago
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];
8 years ago
if ( Currencymasks[0] == 0 )
return(0);
if ( didinit == 0 )
{
if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 )
userhome = "root";
8 years ago
else
{
8 years ago
while ( (c= userhome[strlen(userhome)-1]) == '\r' || c == '\n' || c == ' ' || c == '\t' )
8 years ago
{
userhome[strlen(userhome)-1] = 0;
}
}
8 years ago
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);
}
8 years ago
8 years ago
dp = myinfo->PAXDATA;
8 years ago
/*if ( 0 && time(NULL) > dp->lastupdate+10 )
8 years ago
{
_crypto_update(dp->cryptovols,dp,1);
dp->lastupdate = (uint32_t)time(NULL);
8 years ago
}*/
8 years ago
if ( OS_milliseconds() > lastupdate + (1000*idlegap) )
{
lastupdate = OS_milliseconds();
if ( OS_milliseconds() > lastdayupdate + 60000*60 )
{
lastdayupdate = OS_milliseconds();
8 years ago
datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL));
expand_datenum(dp->edate,datenum);
8 years ago
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; i<sizeof(Yahoo_metals)/sizeof(*Yahoo_metals); i++)
dp->metals[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);
7 years ago
int32_t dispflag = ((rand() % 6) == 0);
7 years ago
//printf("PAX_IDLE.%d %.8f %.8f\n",dispflag,dp->kmdbtc,dp->btcusd);
7 years ago
if ( dp->kmdbtc == 0 || dp->btcusd == 0 || dispflag != 0 )
8 years ago
{
8 years ago
PAX_update(dp,&dp->btcusd,&dp->kmdbtc);
for (i=0; i<MAX_CURRENCIES; i++)
{
splineval = PAX_splineval(&dp->splines[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);
7 years ago
double btcfactor;
7 years ago
//if ( time(NULL) > BTCFACTOR_TIMESTAMP )
7 years ago
btcfactor = .00001;
7 years ago
//else btcfactor = .001;
7 years ago
pvals[4] = PAX_val32(dp->btcusd * btcfactor);
8 years ago
pvals[5] = PAX_val32(dp->CNYUSD);
sprintf(fname,"/%s/.komodo/komodofeed",userhome);
if ( (fp= fopen(fname,"wb")) != 0 )
{
for (i=1; i<MAX_CURRENCIES+6; i++)
iguana_rwnum(1,&data[i*sizeof(uint32_t)],sizeof(*pvals),(void *)&pvals[i]);
pvals[0] = calc_crc32(0,(void *)&data[sizeof(uint32_t)],(MAX_CURRENCIES+5)*sizeof(*pvals));
iguana_rwnum(1,data,sizeof(*pvals),(void *)&pvals[0]);
if ( fwrite(data,sizeof(*pvals),MAX_CURRENCIES+6,fp) != MAX_CURRENCIES+6 )
printf("error writing pvals to (%s)\n",fname);
fclose(fp);
}
7 years ago
if ( dispflag != 0 )
8 years ago
{
for (i=0; i<6; i++)
printf("%u ",pvals[i]);
7 years ago
printf("KMD %.8f BTC %f CNY %f (%f) btcusd pval.%u\n",dp->kmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD,pvals[4]);
8 years ago
}
8 years ago
}
8 years ago
}
return(0);
}
void PAX_init()
{
8 years ago
static int32_t didinit; //double commission = 0.;
8 years ago
if ( didinit == 0 )
{
init_Currencymasks();
//calc_smooth_code(127,7);
8 years ago
//tradebot_monitorall(0,0,0,0,"fxcm",commission);
//tradebot_monitorall(0,0,0,0,"truefx",commission);
8 years ago
//tradebot_monitorall(0,0,0,0,"instaforex",commission);
exchange_create("PAX",0);
didinit = 1;
}
8 years ago
}