Commit 2e1d2a32 authored by Gampe Sebastian's avatar Gampe Sebastian
Browse files

update price ticker

parent 1afb622c
/**
* Default styles for the dygraphs charting library.
*/
.dygraph-legend {
position: absolute;
font-size: 14px;
z-index: 10;
width: 250px; /* labelsDivWidth */
/*
dygraphs determines these based on the presence of chart labels.
It might make more sense to create a wrapper div around the chart proper.
top: 0px;
right: 2px;
*/
background: white;
line-height: normal;
text-align: left;
overflow: hidden;
}
/* styles for a solid line in the legend */
.dygraph-legend-line {
display: inline-block;
position: relative;
bottom: .5ex;
padding-left: 1em;
height: 1px;
border-bottom-width: 2px;
border-bottom-style: solid;
/* border-bottom-color is set based on the series color */
}
/* styles for a dashed line in the legend, e.g. when strokePattern is set */
.dygraph-legend-dash {
display: inline-block;
position: relative;
bottom: .5ex;
height: 1px;
border-bottom-width: 2px;
border-bottom-style: solid;
/* border-bottom-color is set based on the series color */
/* margin-right is set based on the stroke pattern */
/* padding-left is set based on the stroke pattern */
}
.dygraph-roller {
position: absolute;
z-index: 10;
}
/* This class is shared by all annotations, including those with icons */
.dygraph-annotation {
position: absolute;
z-index: 10;
overflow: hidden;
}
/* This class only applies to annotations without icons */
/* Old class name: .dygraphDefaultAnnotation */
.dygraph-default-annotation {
border: 1px solid black;
background-color: white;
text-align: center;
}
.dygraph-axis-label {
/* position: absolute; */
/* font-size: 14px; */
z-index: 10;
line-height: normal;
overflow: hidden;
color: black; /* replaces old axisLabelColor option */
}
.dygraph-axis-label-x {
}
.dygraph-axis-label-y {
}
.dygraph-axis-label-y2 {
}
.dygraph-title {
font-weight: bold;
z-index: 10;
text-align: center;
/* font-size: based on titleHeight option */
}
.dygraph-xlabel {
text-align: center;
/* font-size: based on xLabelHeight option */
}
/* For y-axis label */
.dygraph-label-rotate-left {
text-align: center;
/* See http://caniuse.com/#feat=transforms2d */
transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
}
/* For y2-axis label */
.dygraph-label-rotate-right {
text-align: center;
/* See http://caniuse.com/#feat=transforms2d */
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
}
.input-group-prepend, .input-group-prepend > span {
width:12em;
}
.input-group-append, .input-group-append > select {
width:6em;
}
.curr { font-size:0.8em; }
.prices { text-align: right; }
#pricegraph { width:100%; }
#pricegraph_btn { padding-bottom: 1em; }
#resetZoom { float:right; }
#legend {
float:right;
width:10rem;
position: relative;
top:-1em;
text-align: right;
}
.finfo_config {
text-align:right;
background:lavender;
border:0.5rem solid white;
padding:1em;
}
.finfo_chart {
font-size:0.7em;
padding:1rem;
background:lavender;
border:0.5rem solid white;
height:39em;
}
.ticker {
border:0.5rem solid white;
padding:1.5rem;
background:lightblue;
}
.api {
font-size: 0.8em;
line-height: 0.1em;
}
#history > .row:first-child > * {
font-weight:bold;
}
#history > .row > .col:nth-child(2),
#history > .row > .col:nth-child(5) {
color:blue;
}
.finfo_history {
font-size:0.8em;
padding:1rem;
background:lavender;
margin:0.5rem;
}
This diff is collapsed.
function json_load( url ){
function json_load( url, datatype ){
var json = null;
if( datatype == undefined ){
datatype=url.match(/\..*$/g)[0].slice(1);
}
$.ajax({
'async': false,
'global': false,
'cache': false,
'url': url,
'dataType': "json",
'dataType': ((datatype == 'csv') ? 'text' : datatype),
'success': function (data) {
json = data;
result = data;
}
});
return json;
if(datatype == 'csv'){
result=result.split(/\n/g);
var AA=[];
result.forEach(
function(v,i){
var A=v.split(/,/g);
if( A.length > 1 && A[0] != '' ){
AA.push(A);
}
}
);
result=AA;
}
return result;
}
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
//https://www.coinexchange.io/api/v1/getmarketsummary?market_id=200
//https://www.coinexchange.io/api/v1/getorderbook?market_id=200
var DATA;
var PAIR;
var DEFAULT_CURRENCY='eur';
var GRAPH;
$( document ).ready(
function() {
get_data();
$( '#curr' ).change(function() {
get_data( $(this).val() );
});
get_data( (( getQueryVariable('c') == false ) ? DEFAULT_CURRENCY : getQueryVariable('c') ) );
$('#resetZoom').click(function(){ unzoomGraph(); });
}
);
var lastlegend='..loading..';
function legendFormatter(data) {
if (data.x == null) {
// This happens when there's no selection and {legend: 'always'} is set.
//return '<br>' + data.series.map(function(series) { return series.dashHTML + ' ' + series.labelHTML }).join('<br>');
return lastlegend;
}
var html = this.getLabels()[0] + ': ' + data.xHTML;
data.series.forEach(function(series) {
if (!series.isVisible) return;
var labeledData = series.labelHTML + ': ' + series.yHTML;
if (series.isHighlighted) {
labeledData = '<b>' + labeledData + '</b>';
}
html += '<br>' + series.dashHTML + ' ' + labeledData;
});
lastlegend=html;
return html;
}
function unzoomGraph() {
GRAPH.updateOptions({
dateWindow: null,
valueRange: null
});
}
function create_graph(){
var D=[];
var L=['time','fv_price','fm_price'];
DATA.history.slice(1).forEach(
function(v,i){
var A=v.split(/,/g);
if( A.length > 1 ){
var LMH_fv=[parseFloat(A[1]),parseFloat(A[1]),parseFloat(A[2])];
var LMH_fm=[parseFloat(A[3]),(parseFloat(A[3])+parseFloat(A[4]))/2,parseFloat(A[4])];
D.push([new Date(A[0]*1000),LMH_fv,LMH_fm]);
}
}
);
console.log(D);
GRAPH = new Dygraph(
document.getElementById("pricegraph"),
D, // path to CSV file
{
customBars:true,
labels:L,
labelsSeparateLines: true,
labelsKMB: true,
legendFormatter: legendFormatter,
labelsDiv: document.getElementById('legend'),
legend:'always',
hideOverlayOnMouseOut:false,
series: {
'fv_price': { axis: 'y' },
'fm_price': { axis: 'y' }
},
axes : {
y : {
valueFormatter: function(v) {
return v.toFixed(4) + ' ' + DATA.config.FACTOR_PREPOSITION + DATA.config.CURRENCY.toUpperCase();
},
axisLabelFormatter: function(v) {
return v.toFixed(3);
}
}
}
} // options
);
var linear = document.getElementById("linear");
var log = document.getElementById("log");
var setLog = function(val) {
GRAPH.updateOptions({ logscale: val });
linear.disabled = !val;
log.disabled = val;
};
linear.onclick = function() { setLog(false); };
log.onclick = function() { setLog(true); };
GRAPH.setSelection(GRAPH.file_.length-1);
}
function get_data(){
var DATA=json_load('functions/get_data.php');
console.log(DATA);
$('#fv_bid').html( DATA.fv_bid );
$('#fm_bid').html( DATA.fm_bid.toString().slice(0,-1) + '<sub>' + DATA.fm_bid.toString().slice(-1) + '</sub>' );
$('#fm_ask').html( DATA.fm_ask.toString().slice(0,-1) + '<sub>' + DATA.fm_ask.toString().slice(-1) + '</sub>' );
$('#fv_ask').html( DATA.fv_ask );
function get_data(curr){
DATA=json_load('functions/get_data.php?c=' + curr,'json' );
PAIR=json_load('data/coingecko_currencies.json');
$('#curr').html('');
var tmp='';
PAIR.sort().forEach(
function(v,i){
tmp+='<option value="'+v+'" '+((v==DATA.config.CURRENCY) ? 'selected' : '' )+'>'+v.toUpperCase()+'</option>';
}
);
$('#curr').html(tmp);
$('#fv_bid').html( DATA.fv_bid.toString().slice(0,-2) + '<sub>' + DATA.fv_bid.toString().slice(-2) + '</sub>' );
$('#fm_bid').html( DATA.fm_bid.toString().slice(0,-2) + '<sub>' + DATA.fm_bid.toString().slice(-2) + '</sub>' );
$('#fm_ask').html( DATA.fm_ask.toString().slice(0,-2) + '<sub>' + DATA.fm_ask.toString().slice(-2) + '</sub>' );
$('#fv_ask').html( DATA.fv_ask.toString().slice(0,-2) + '<sub>' + DATA.fv_ask.toString().slice(-2) + '</sub>' );
$('.curr').html(DATA.config.FACTOR_PREPOSITION + DATA.config.CURRENCY.toUpperCase() + ' / FAIR' );
$('#conf').html( JSON.stringify( DATA.config).replace(/\,/g,'<br>').replace(/\"|\{|\}/g,'').replace(/\:/g,' = ') );
$('#formulas').html( JSON.stringify( DATA.formulas).replace(/\,/g,'<br>').replace(/\"|\{|\}/g,'').replace(/\:/g,' = ') );
console.log(curr);
$('.api.share > a').attr('href',window.location.origin + window.location.pathname+'?c='+curr);
$('.api.data > a').attr('href','data/freevision_'+DATA.config.CURRENCY+'.json');
$('.api.history > a').attr('href','data/freevisionHistory_'+DATA.config.CURRENCY+'.csv');
var tmp='';
DATA.history.slice(0,1).concat(DATA.history.slice(1).reverse()).forEach(
function(v,i){
......@@ -23,6 +134,7 @@ function get_data(){
}
);
$('#history').html(tmp);
create_graph();
}
function history_out(v,i){
......@@ -30,13 +142,13 @@ function history_out(v,i){
var tmp='';
if( V.length > 1 ){
tmp+='<div class="row">'
tmp+='<div class="col-sm-2">'+(( i == 0 ) ? V[0] : new Date(V[0]*1000).toJSON().slice(0,16).replace(/T/g,' '))+'</div>';
tmp+='<div class="col-sm-2">'+(( i == 0 ) ? V[0] : new Date(V[0]*1000 - new Date().getTimezoneOffset()*60*1000).toJSON().slice(0,16).replace(/T/g,' '))+'</div>';
tmp+='<div class="col">'+V[1]+'</div>';
tmp+='<div class="col">'+V[2]+'</div>';
tmp+='<div class="col">'+V[3]+'</div>';
tmp+='<div class="col">'+V[4]+'</div>';
tmp+='<div class="col">'+V[2]+'</div>';
tmp+='<div class="col">'+V[5]+'</div>';
tmp+='<div class="col">'+V[6]+'</div>';
//tmp+='<div class="col">'+V[6]+'</div>';
tmp+='</div>';
}
return tmp;
......
......@@ -5,20 +5,100 @@ ini_set('display_errors',1);
define('COINEXCHANGE','../data/coinexchange.json');
define('COINEXCHANGE_URL','https://www.coinexchange.io/api/v1/getorderbook?market_id=200');
//https://www.coinexchange.io/api/v1/getorderbook?market_id=200
define('BITCOINAVERAGE','../data/bitcoinaverage.json');
define('BITCOINAVERAGE_URL','https://apiv2.bitcoinaverage.com/indices/global/ticker/BTCEUR');
//define('BITCOINAVERAGE','../data/bitcoinaverage.json');
//define('BITCOINAVERAGE_URL','https://apiv2.bitcoinaverage.com/indices/global/ticker/BTCEUR');
define('FREEVISION', '../data/freevision.json');
define('FREEVISION_HISTORY', '../data/freevision_history.csv');
define('FREEVISION', '../data/freevision_');
define('FREEVISION_HISTORY', '../data/freevisionHistory_');
define('COINGECKO_CURRENCIES', '../data/coingecko_currencies.json');
define('COINGECKO_CURRENCIES_URL','https://api.coingecko.com/api/v3/simple/supported_vs_currencies');
define('COINGECKO_FAIR_PAIRS', '../data/coingecko_fair_pairs.json');
define('COINGECKO_FAIR_PAIRS_URL','https://api.coingecko.com/api/v3/simple/price?ids=faircoin&vs_currencies=');
define('DEFAULT_CURRENCY','eur');
define('ASK_DEPTH_EUR',1000);
define('BID_DEPTH_EUR',1000);
define('ASK_OFFSET_EUR',0.01);
define('BID_OFFSET_EUR',0.01);
define('BID_MIN_EUR',0.05);
define('ASK_OFFSET_PERC',1.05);
define('BID_OFFSET_PERC',0.95);
define('REFRESH_TIME_SECONDS',3600);
define('FACTOR_PREPOSITION',Array(
1 => '',
0.001=> 'm',
0.000001=>'µ'
)
);
define('LOG_NORMALIZED_25',
Array(
1,
1.25,
1.5,
1.75,
2,
2.5,
3,
3.5,
4,
5,
6,
7,
8
)
);
define('LOG_NORMALIZED_5',
Array(
1,
1.05,
1.1,
1.15,
1.2,
1.25,
1.3,
1.35,
1.4,
1.5,
1.6,
1.7,
1.8,
1.9,
2,
2.1,
2.2,
2.3,
2.4,
2.5,
2.6,
2.7,
2.8,
3,
3.25,
3.5,
3.75,
4,
4.25,
4.5,
4.75,
5,
5.25,
5.5,
6,
6.5,
7,
7.5,
8,
8.5,
9,
9.5
)
);
function curl($url){
$ch = curl_init();
......@@ -35,13 +115,12 @@ function curl($url){
function update_data(){
$ARR=[COINEXCHANGE,BITCOINAVERAGE];
$ARR_URL=[COINEXCHANGE_URL,BITCOINAVERAGE_URL];
$ff=false;
$ARR=[COINEXCHANGE,COINGECKO_CURRENCIES];
$ARR_URL=[COINEXCHANGE_URL,COINGECKO_CURRENCIES_URL];
$f=false;
foreach( $ARR as $key => $value ){
if( file_exists($value) ){
if( filemtime($value) + REFRESH_TIME_SECONDS > time() ){
$f=false;
} else {
$f=true;
}
......@@ -54,18 +133,30 @@ function update_data(){
$fp=fopen($value,'w+');
fwrite($fp,$json);
fclose($fp);
$ff=true;
if($value == COINGECKO_CURRENCIES ){
$CURR=json_decode($json,true);
$urlparam='';
foreach($CURR as $currency){
$urlparam.=$currency.'%2C';
}
$json=curl(COINGECKO_FAIR_PAIRS_URL.$urlparam);
$fp=fopen(COINGECKO_FAIR_PAIRS,'w+');
fwrite($fp,$json);
fclose($fp);
}
}
}
return get_data($ff);
$curr=empty($_GET['c']) ? DEFAULT_CURRENCY : $_GET['c'];
return get_data($f,$curr);
}
function get_data($upd){
function get_data($upd,$curr){
if( !$upd ){
// load data from folder
$ARR=[FREEVISION,FREEVISION_HISTORY];
$ARR=[FREEVISION.$curr.'.json',FREEVISION_HISTORY.$curr.'.csv'];
$ARR_ID=['FREEVISION','HISTORY'];
$JS=[];
foreach( $ARR as $key => $value ){
......@@ -86,8 +177,8 @@ function get_data($upd){
}
// recalculate data
$ARR=[COINEXCHANGE,BITCOINAVERAGE,FREEVISION];
$ARR_ID=['BTCFAIR','BTCEUR','FREEVISION'];
$ARR=[COINEXCHANGE,COINGECKO_FAIR_PAIRS];
$ARR_ID=['BTCFAIR','COINGECKO_FAIR_PAIRS'];
$JS=[];
foreach( $ARR as $key => $value ){
$fp=fopen($value,'r');
......@@ -97,80 +188,194 @@ function get_data($upd){
}
// calculate prices
$BTCEUR=$JS['BTCEUR'];
$PAIR=$JS['COINGECKO_FAIR_PAIRS']['faircoin'];
$btc_eur=$PAIR['eur']/$PAIR['btc'];
$BTCFAIR=$JS['BTCFAIR']['result'];
$ask_depth_btc=ASK_DEPTH_EUR/$BTCEUR['last'];
$bid_depth_btc=BID_DEPTH_EUR/$BTCEUR['last'];
$btceur=$BTCEUR['last'];
$ask_depth_btc=ASK_DEPTH_EUR/$btc_eur;
$bid_depth_btc=BID_DEPTH_EUR/$btc_eur;
$c=0;
foreach($BTCFAIR['SellOrders'] as $order ){
if( $c < $ask_depth_btc ){
// get bid price by market depth ( at https://www.coinexchange.io/market/FAIR/BTC )
$c=0; $lp=0;
foreach($BTCFAIR['BuyOrders'] as $order ){
if( $c < $bid_depth_btc ){
$c+=$order['Price'] * $order['Quantity'];
$lp=$order['Price'];
} else { break; }
}
$ask_price=$lp*$btceur;
$bid_price_btc=$lp;
$c=0;
foreach($BTCFAIR['BuyOrders'] as $order ){
if( $c < $bid_depth_btc ){
// get ask price by market depth ( at https://www.coinexchange.io/market/FAIR/BTC )
$c=0; $lp=0;
foreach($BTCFAIR['SellOrders'] as $order ){
if( $c < $ask_depth_btc ){
$c+=$order['Price'] * $order['Quantity'];
$lp=$order['Price'];
} else { break; }
}
$bid_price=$lp*$btceur;
$fv_bid_bid = max( BID_MIN_EUR, intVal(($bid_price - BID_OFFSET_EUR)*10)/10 );
$fv_bid_ask = max( BID_MIN_EUR, intVal(($ask_price - BID_OFFSET_EUR)*10)/10 );
$fv_ask = $ask_price+ASK_OFFSET_EUR;