]>
Commit | Line | Data |
---|---|---|
1e81ccb7 | 1 | |
2 | ||
3 | int32_t NUM_PRICES; uint32_t *PVALS; | |
4 | ||
41a4a4db | 5 | #define USD 0 |
6 | ||
1e81ccb7 | 7 | #define MAX_CURRENCIES 32 |
8 | char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies | |
9 | "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", | |
10 | "KMD" }; | |
11 | ||
a4ebaad7 | 12 | uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies |
13 | 45434000000000, 16827000000, 3473357229000, 306435000000, 27139000000000, 2150641000000, 347724099000, 1469583000000, 749543000000, 1826110000000, 2400434000000, 1123925000000, 3125276000000, 13975000000000, 317657000000, 759706000000000, 354902000000, 2797061000000, 162189000000, 163745000000, 1712000000000, 39093000000, 1135490000000000, 80317000000, | |
14 | 100000000 }; | |
15 | ||
16 | #define MIND 1000 | |
17 | uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies | |
18 | 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 | |
19 | 10*MIND, | |
1e81ccb7 | 20 | }; |
21 | ||
ab6984e9 | 22 | uint64_t komodo_paxvol(uint64_t volume,uint64_t price) |
23 | { | |
24 | if ( volume < 10000000000 ) | |
25 | return((volume * price) / 1000000000); | |
26 | else if ( volume < (uint64_t)10 * 10000000000 ) | |
27 | return((volume * (price / 10)) / 100000000); | |
28 | else if ( volume < (uint64_t)100 * 10000000000 ) | |
29 | return(((volume / 10) * (price / 10)) / 10000000); | |
30 | else if ( volume < (uint64_t)1000 * 10000000000 ) | |
31 | return(((volume / 10) * (price / 100)) / 1000000); | |
32 | else if ( volume < (uint64_t)10000 * 10000000000 ) | |
33 | return(((volume / 100) * (price / 100)) / 100000); | |
34 | else if ( volume < (uint64_t)100000 * 10000000000 ) | |
35 | return(((volume / 100) * (price / 1000)) / 10000); | |
36 | else if ( volume < (uint64_t)1000000 * 10000000000 ) | |
37 | return(((volume / 1000) * (price / 1000)) / 1000); | |
38 | else if ( volume < (uint64_t)10000000 * 10000000000 ) | |
39 | return(((volume / 1000) * (price / 10000)) / 100); | |
40 | else return(((volume / 10000) * (price / 10000)) / 10); | |
41 | } | |
42 | ||
a4ebaad7 | 43 | void pax_rank(uint64_t *ranked,uint32_t *pvals) |
44 | { | |
45 | int32_t i; uint64_t vals[32],sum = 0; | |
46 | for (i=0; i<32; i++) | |
47 | { | |
48 | vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); | |
49 | sum += vals[i]; | |
50 | } | |
51 | for (i=0; i<32; i++) | |
52 | { | |
53 | ranked[i] = (vals[i] * 1000000000) / sum; | |
54 | printf("%.6f ",(double)ranked[i]/1000000000.); | |
55 | } | |
08ef004d | 56 | printf("sum %llu\n",(long long)sum); |
a4ebaad7 | 57 | }; |
58 | ||
1e81ccb7 | 59 | int32_t dpow_readprices(uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals) |
60 | { | |
61 | uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,len = 0; | |
62 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp); | |
63 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n); | |
64 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000 | |
65 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000 | |
66 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd); | |
67 | *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.)); | |
68 | *BTCUSDp = ((double)btcusd / (1000000000. / 1000.)); | |
69 | *CNYUSDp = ((double)cnyusd / 1000000000.); | |
70 | for (i=0; i<n-3; i++) | |
71 | { | |
72 | len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&pvals[i]); | |
73 | //printf("%u ",pvals[i]); | |
74 | } | |
75 | pvals[i++] = kmdbtc; | |
76 | pvals[i++] = btcusd; | |
77 | pvals[i++] = cnyusd; | |
78 | //printf("OP_RETURN prices\n"); | |
79 | return(n); | |
80 | } | |
81 | ||
82 | /*uint32_t PAX_val32(double val) | |
83 | { | |
84 | uint32_t val32 = 0; struct price_resolution price; | |
85 | if ( (price.Pval= val*1000000000) != 0 ) | |
86 | { | |
87 | if ( price.Pval > 0xffffffff ) | |
88 | printf("Pval overflow error %lld\n",(long long)price.Pval); | |
89 | else val32 = (uint32_t)price.Pval; | |
90 | } | |
91 | return(val32); | |
92 | }*/ | |
93 | ||
94 | double PAX_val(uint32_t pval,int32_t baseid) | |
95 | { | |
96 | //printf("PAX_val baseid.%d pval.%u\n",baseid,pval); | |
97 | if ( baseid >= 0 && baseid < MAX_CURRENCIES ) | |
98 | return(((double)pval / 1000000000.) / MINDENOMS[baseid]); | |
99 | return(0.); | |
100 | } | |
101 | ||
102 | void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) | |
103 | { | |
104 | int32_t i,nonz; double KMDBTC,BTCUSD,CNYUSD; uint32_t kmdbtc,btcusd,cnyusd; | |
105 | if ( numpvals >= 35 ) | |
106 | { | |
107 | for (nonz=i=0; i<32; i++) | |
108 | { | |
109 | if ( pvals[i] != 0 ) | |
110 | nonz++; | |
111 | //printf("%u ",pvals[i]); | |
112 | } | |
113 | if ( nonz == 32 ) | |
114 | { | |
115 | kmdbtc = pvals[i++]; | |
116 | btcusd = pvals[i++]; | |
117 | cnyusd = pvals[i++]; | |
118 | KMDBTC = ((double)kmdbtc / (1000000000. * 1000.)); | |
119 | BTCUSD = ((double)btcusd / (1000000000. / 1000.)); | |
120 | CNYUSD = ((double)cnyusd / 1000000000.); | |
121 | PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36); | |
122 | PVALS[36 * NUM_PRICES] = height; | |
123 | memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35); | |
124 | NUM_PRICES++; | |
125 | //printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES); | |
126 | } | |
127 | } | |
128 | } | |
129 | ||
130 | int32_t komodo_baseid(char *origbase) | |
131 | { | |
132 | int32_t i; char base[64]; | |
133 | for (i=0; origbase[i]!=0&&i<sizeof(base); i++) | |
134 | base[i] = toupper((int32_t)(origbase[i] & 0xff)); | |
135 | base[i] = 0; | |
136 | for (i=0; i<=MAX_CURRENCIES; i++) | |
137 | if ( strcmp(CURRENCIES[i],base) == 0 ) | |
138 | return(i); | |
139 | printf("illegal base.(%s) %s\n",origbase,base); | |
140 | return(-1); | |
141 | } | |
142 | ||
a4ebaad7 | 143 | uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t volume) |
144 | { | |
13d410de | 145 | uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t baseusd,kmdusd,baserel,sum,ranked[32]; int32_t i; |
a4ebaad7 | 146 | if ( (pvalb= pvals[baseid]) != 0 ) |
147 | { | |
148 | if ( relid == MAX_CURRENCIES ) | |
149 | { | |
150 | kmdbtc = pvals[MAX_CURRENCIES]; | |
151 | btcusd = pvals[MAX_CURRENCIES + 1]; | |
152 | if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 ) | |
153 | { | |
154 | baseusd = ((uint64_t)pvalb * 1000000000) / pvals[USD]; | |
155 | kmdusd = ((uint64_t)kmdbtc * 1000000000) / btcusd; | |
156 | //printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd); | |
157 | return(volume * ((baseusd * 1000000000) / kmdusd)); | |
158 | } | |
159 | } | |
160 | else if ( baseid == relid ) | |
161 | { | |
162 | pax_rank(ranked,pvals); | |
08ef004d | 163 | return(ranked[baseid]); |
a4ebaad7 | 164 | } |
165 | else if ( (pvalr= pvals[relid]) != 0 ) | |
166 | { | |
167 | baserel = ((uint64_t)pvalb * 1000000000) / pvalr; | |
168 | return(komodo_paxvol(volume,baserel)); | |
169 | } | |
170 | } | |
08ef004d | 171 | return(0); |
a4ebaad7 | 172 | } |
173 | ||
1e81ccb7 | 174 | uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t volume) |
175 | { | |
aa5a494c | 176 | int32_t baseid=-1,relid=-1,i,ht; uint32_t *ptr; |
1e81ccb7 | 177 | if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) |
178 | { | |
179 | for (i=NUM_PRICES-1; i>=0; i--) | |
180 | { | |
181 | ptr = &PVALS[36 * i]; | |
182 | if ( *ptr < height ) | |
a4ebaad7 | 183 | return(komodo_paxcalc(&ptr[1],baseid,relid,volume)); |
1e81ccb7 | 184 | } |
185 | } else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid); | |
186 | return(0); | |
187 | } | |
188 | ||
a4ebaad7 | 189 | int32_t komodo_paxprices(uint32_t *timestamps,uint64_t *prices,int32_t max,int32_t width,char *base,char *rel) |
190 | { | |
aa5a494c | 191 | int32_t baseid=-1,relid=-1,i,ht; uint32_t *ptr; |
a4ebaad7 | 192 | if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) |
193 | { | |
194 | for (i=NUM_PRICES-1; i>=0; i--) | |
195 | { | |
196 | ptr = &PVALS[36 * i]; | |
197 | } | |
198 | } | |
199 | } | |
200 | ||
1e81ccb7 | 201 | int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize) |
202 | { | |
203 | static uint32_t lastcrc; | |
204 | FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n,retval,fsize,len=0; uint8_t data[8192]; | |
205 | #ifdef WIN32 | |
206 | sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed"); | |
207 | #else | |
208 | sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed"); | |
209 | #endif | |
210 | if ( (fp= fopen(fname,"rb")) != 0 ) | |
211 | { | |
212 | fseek(fp,0,SEEK_END); | |
213 | fsize = (int32_t)ftell(fp); | |
214 | rewind(fp); | |
215 | if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) ) | |
216 | { | |
217 | if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize ) | |
218 | { | |
219 | len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32); | |
220 | check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); | |
221 | if ( check == crc32 ) | |
222 | { | |
223 | double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128]; | |
224 | dpow_readprices(&data[len],×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals); | |
225 | if ( 0 && lastcrc != crc32 ) | |
226 | { | |
227 | for (i=0; i<32; i++) | |
228 | printf("%u ",pvals[i]); | |
229 | printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0); | |
230 | } | |
231 | if ( timestamp > time(NULL)-600 ) | |
232 | { | |
233 | n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); | |
234 | if ( 0 && lastcrc != crc32 ) | |
235 | { | |
236 | for (i=0; i<n; i++) | |
237 | printf("%02x",opret[i]); | |
238 | printf(" coinbase opret[%d] crc32.%u:%u\n",n,crc32,check); | |
239 | } | |
240 | } else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL)); | |
241 | lastcrc = crc32; | |
242 | } else printf("crc32 %u mismatch %u\n",crc32,check); | |
243 | } else printf("fread.%d error != fsize.%d\n",retval,fsize); | |
244 | } else printf("fsize.%d > maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data)); | |
245 | fclose(fp); | |
246 | } | |
247 | return(n); | |
248 | } |