Menubar

lunes, 18 de febrero de 2019

Como tener el precio histórico de las criptomonedas usando PHP (últimos 6 meses)

Por J. Manuel Mar H. Editar
Compartir en Facebook
Compartir en Twitter
Compartir en MeWe
Enviar a Reddit
Guardar en Internet archive
Guardar en  archive.today
Enviar por email
Criptomonedas  Tiempo atrás publiqué una serie de scripts para graficar el precio de los últimos seis meses para diversas criptomonedas usando Excel. Sin embargo se quedó pendiente como poder generar estos mismos gráficos pero usando PHP; pues bien, he aquí entonces lo que quedó en deuda esperando les sea de utilidad Guiño.

Publicidad


  Si por alguna razón aún no le han dado un vistazo a los scripts para graficar los precios de las criptomonedas en los últimos seis meses pueden visitar los siguientes enlaces, pues este script está basado en los ya mencionados pero adaptando el código fuente a PHP.

Como tener el precio histórico de las criptomonedas en un archivo de Excel (últimos 6 meses) - I
Como tener el precio histórico de las criptomonedas en un archivo de Excel (últimos 6 meses) - II
Como tener el precio histórico de las criptomonedas en un archivo de Excel (últimos 6 meses) - III

Preparativos  


  El siguiente script puede funcionar tanto en un servidor PHP local como uno en Internet, pero es necesario hacer algunas configuraciones previamente para asegurarnos que todo va a marchar bien. Yo estoy usando XAMPP y haremos uso de la función "file_get_contents" para leer el contenido de un archivo externo a nuestro servidor web.

  Sin embargo es necesario habilitar dicha funcionalidad previamente en nuestro servidor web. Para ello (la siguiente información aplica para configurar nuestro servidor local, para el servidor en Internet necesitamos revisar que tipo de servidor tenemos y donde se almacena el archivo php.ini para poder editarlo) abriremos la carpeta donde está instalado XAMPP, en mi caso se encuentra en la carpeta "C:\trabajos\programas\xampplite".

  Uso Windows 7, en el explorador de archivos ya abierto en la ruta donde tenemos XAMPP sobre el área de búsqueda del mismo escribiremos *.ini y esperaremos a que se muestren todos los resultados.
Buscando archivos ini

  Ahora con un editor de texto plano (ejemplo Notepad) abriremos todos los archivos INI que comiencen con el nombre php, para ello iremos arrastrando de uno por uno a nuestro editor y buscaremos la cadena ;extension=php_openssl.dll, la reemplazaremos por extension=php_openssl.dll, guardaremos cambios y haremos lo mismo para todos los archivos. Concretamente deben quedar editados los archivos php.ini-recommended, php.ini-dist y php.ini (todos los que encontremos). Guardaremos cambios y reiniciaremos nuestro servidor web.

Es todo, ya la función file_get_contents debe trabajar sin problemas.

Código fuente


 El script se compone de tres archivos: emptyframe.html, graph.php e index.php, además de una carpeta llamada Cache y otra llamada pChart. El primer archivo emptyframe.html solo contiene la estructura básica de un archivo html por lo que no lo detallaré, solo sirve de trasfondo al iniciar el script principal.

 El archivo index.php es la estructura principal del script, mediante el elegiremos la critpmoneda de la cual queremos saber su comportamiento, luciendo de la siguiente manera una vez puesto en marcha:
Página de inicio

 Elegiremos una criptmoneda de la lista o bien podemos ingresar sus iniciales en el campo de texto y presionaremos el botón "Otra" para consultar otra criptomoneda que no se encuentre en la lista. Este es el código fuente del archivo index.php.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title>Precio hist&oacute;rico de criptomonedas</title>
<style type="text/css">
<!--

html 
{
  overflow: hidden;
}

-->
</style>
<script language="JavaScript">
<!--

function gethistory()
{

  var coin = document.coin.list.options[document.coin.list.selectedIndex].value;
  var title = document.coin.list.options[document.coin.list.selectedIndex].text;
  
  if(coin == "-")
    alert("Debe seleccionar una moneda de la lista.");
  else
  window.open("graph.php?coin=" + coin + "&name=" + title + "&time=" + Math.random(), "graph");
  
}

function getother()
{

  var coin = document.coin.other.value;
  
  if(coin == "" || coin == null || coin == "undefined")
    alert("Debe ingresar el simbolo de la criptomoneda");
  else
     window.open("graph.php?coin=" + coin + "&time=" + Math.random(), "graph");
  
}

-->
</script>
</head>
<body>

<form name="coin">
<table border="0" width="100%" height="100%">
<tr>
<td valign="middle" colspan="2" height="1%"><h2>Seleccione una criptomoneda</h2></td>
</tr>
<td valign="middle" width="30%" height="1%">

<select name="list" size="1" style="width: 100%; height: 30px; font-size: 14px;" onchange="javascript:gethistory();">
<option value="-">Criptomonedas disponibles</option>
<option value="bitcoin">Bitcoin</option>
<option value="bitcoin-cash">Bitcoin Cash</option>
<option value="dash">Dash</option>
<option value="dogecoin">Dogecoin</option>
<option value="ethereum">Ethereum</option>
<option value="litecoin">Litecoin</option>
<option value="monero">Monero</option>
<option value="ripple">Ripple</option>
<option value="golem">Golem</option>
<option value="curecoin">Curecoin</option>
<option value="nem">XEM</option>
<option value="zcash">Zcash</option>
<option value="factom">Factom</option>
<option value="bytecoin">Bytecoin</option>
<option value="steem">STEEM</option>
<option value="lisk">Lisk</option>
<option value="gridcoin-research">GridCoin</option>
<option value="ethereum-classic">Ethereum classic</option>
<option value="bitcore">Bitcore</option>
<option value="blackcoin">Blackcoin</option>
<option value="cardano">Cardano</option>
<option value="peercoin">Peercoin</option>
<option value="primecoin">Primecoin</option>
<option value="chaucha">Chaucha</option>
</select>

</td>
<td valign="top" width="70%">

<table border="0">
<tr>
<td valign="top">
<input type="text" name="other" value="" maxlenght="10" style="width: 150px; height: 30px; font-size: 14px;">
</td>
<td valign="top">
<input type="button" value="Otra" style="height: 30px; font-size: 14px;" onclick="javascript:getother();">
</td>
</tr>
</table>

</td>
</tr>
<tr>
<td valign="top" colspan="2" height="1%">
<hr>
</td>
</tr>
<tr>
<td valign="top" colspan="2" height="97%">
<iframe src="emptyframe.html" frameborder="0" scrolling="no" width="100%" height="100%" name="graph">Su navegador no soporta iframes.</iframe>
</td>
</tr>
</table><?

  //thanks to http://thisinterestsme.com/php-delete-all-files-from-a-folder/
  $folder = "Cache";
  $files = glob($folder."/*");
  
  foreach($files as $file)
    if(is_file($file))
      @unlink($file);

?>
    
</body>
</html>

  Básicamente lo que hacemos es mostrar una una lista de criptomonedas, cada elemento tiene asociada la cadena con que coingecko.com la conoce (es quien nos presta el servicio de consulta histórica de los precios de diversas criptomonedas). Una vez seleccionada una criptomoneda mandamos llamar la función "gethistory()" para recuperar los detalles de la criptomoneda y posteriormente cargamos el archivo "graph.php" en un iframe que hasta el momento teníamos oculto (es por ello la existencia del archivo emptyframe.html).

  Lo mismo aplica para el botón "Otra", aquí tomaremos las iniciales de la criptomoneda a analizar (es importante saber como se llama previamente en coingecko.com) y nuevamente haremos uso del iframe con el archivo graph.php y los parámetros adecuados tomados de la criptomoneda a analizar.

if(coin == "-")
    alert("Debe seleccionar una moneda de la lista.");
else
  window.open("graph.php?coin=" + coin + "&name=" + title + "&time=" + Math.random(), "graph");

Si miramos al final de nuestro archivo index.php veremos el siguiente código fuente:

<?

  //thanks to http://thisinterestsme.com/php-delete-all-files-from-a-folder/
  $folder = "Cache";
  $files = glob($folder."/*");
  
  foreach($files as $file)
  if(is_file($file))
      @unlink($file);

?>

  Cuando el gráfico es generado se almacena en la carpeta "Cache" que se encuentra en la ruta raíz de nuestro script (a la altura del archivo index.php). Esto tiene la ventaja de no generar el mismo gráfico por segunda vez para si por ejemplo volvemos a consultar una misma moneda, pero si hay cambios en la moneda en largo tiempo, el gráfico no se actualizaría hasta que no borráramos el contenido de esa carpeta. Pues bien, esa es la funcionalidad de éste código fuente. Cada vez que ingresemos por primera vez al script entonces automáticamente se vaciará la carpeta "Cache" para asegurarnos que por lo menos en esa sesión los datos estén frescos.

Ahora veamos el contenido del archivo graph.php.

<?php

  include("pChart/pChart/pData.class"); 
  include("pChart/pChart/pChart.class"); 
  include("pChart/pChart/pCache.class"); 

  if(isset($_GET["coin"]))
    $coin = trim($_GET["coin"]);
  else
    $coin = "";
    
  if(isset($_GET["name"]))
    $name = trim($_GET["name"]);
  else
    $name = "Criptomoneda desconocida";
    
  $price = array();
  $time = array();

  if(trim($coin) == "")
    echo "No ingres&oacute; el simbolo de ninguna criptomoneda.";
  else
  {
  
    ini_set('memory_limit', '1024M' );
    set_time_limit(0);
  
    //thanks to http://php.net/manual/fr/function.file-get-contents.php
    //thanks to https://www.coingecko.com
    //thanks to https://www.softqubes.com/blog/how-csv-data-can-be-read-in-php-array/
  $csv = @file_get_contents("https://www.coingecko.com/price_charts/export/".trim($coin)."/usd.csv");
  $lines = explode("\n", $csv);
  
  if((int)count($lines) <= 1)
    echo "Simbolo inv&aacute;lido.";
  else
  { 
  
    $i = 0;
    $j = 0;
    $pos = 0;
    $max = 0;
    
    if(count($lines) <= 180)
    {

  $pos = 0;
  $max = count($lines);
  
}
    else
    {

  $max = count($lines);
  $pos = ($max - 180) - 1;
  
}

for($j=$pos; $j < $max; $j++)
{

  if(trim($lines[$j]) != "")
  {

  if(strpos(".".strtolower(trim($lines[$j])), "snapped_at") <= 0)
    {

  $myarray = explode(",", trim($lines[$j]));
  
  $time[$i] = date("d/m/Y", strtotime(substr(trim($myarray[0]), 0, 10)));
$history[$i] = trim($myarray[1]);

  $i++;
  
}
    
}

}

$DataSet = new pData();   
  $DataSet->AddPoint($history, "Serie1"); 
  $DataSet->AddAllSeries();  
  $DataSet->SetAbsciseLabelSerie("X");
$DataSet->SetSerieName("USD", "Serie1"); 
 
  $Cache = new pCache();  
$Cache->GetFromCache("Graph1", $DataSet->GetData());  
          
$Test = new pChart(1038, 486);  //full area to work
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 8);  
$Test->setGraphArea(50, 60, 981, 458); //graph area 

//gray body rectangle
$Test->drawFilledRoundedRectangle(7, 7, 993, 482, 5, 240, 240, 240);  
$Test->drawRoundedRectangle(5, 5, 995, 484, 5, 230, 230, 230);

$Test->drawGraphArea(255, 255, 255, TRUE); //graph background color  
  $Test->drawScale($DataSet->GetData(), $DataSet->GetDataDescription(), SCALE_NORMAL, 0, 0, 0, TRUE, 0,2); //usd metter colors 
 
//configure bar color, thanks to http://wiki.pchart.net/doc.settings.setpalette.html
$Test->setColorPalette(0, 63, 153, 178);  
$Test->setLineStyle(2); //heigth line border thanks to http://pchart.sourceforge.net/documentation.php?topic=pChart#

// Draw the cubic curve graph
$Test->drawCubicCurve($DataSet->GetData(), $DataSet->GetDataDescription());  

// series titles
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 13);  
$Test->drawLegend(872, 32, $DataSet->GetDataDescription(), 255, 255, 255);  

//title
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 16);  
$Test->drawTitle(50, 32,"Historial ".trim($name)." (6 meses)", 50, 50, 50, 585);  
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 13);  
$Test->drawTitle(50, 52,"Fuente: Coingecko.com", 50, 50, 50, 585);  

$diff1 = 798 / 3;
$pos1 = 0;
$pos4 = count($time) - 1;
$diff2 = ceil(($pos4 - $pos1) / 3);
$pos2 = (($pos1 + $diff2)) - 1;
$pos3 = ($pos2 + $diff2);
$pos1txt = $time[$pos1];
$pos4txt = $time[$pos4];
$pos2txt = $time[$pos2];
$pos3txt = $time[$pos3];

//x axis labels
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 10);  
$Test->drawTitle(46, 477, $pos1txt, 50, 50, 50);  
$Test->drawTitle(909, 477, $pos4txt, 50, 50, 50);
$Test->drawTitle(111 + $diff1 - 70, 477, $pos2txt, 50, 50, 50);
$Test->drawTitle(111 + ($diff1 * 2) + 5, 477, $pos3txt, 50, 50, 50);

// Render the graph  
$Cache->WriteToCache("Graph1",$DataSet->GetData(),$Test);  
$Test->Stroke();
  
}

}

?>

Las partes interesantes son las siguientes:

@file_get_contents("https://www.coingecko.com/price_charts/export/".trim($coin)."/usd.csv");
$lines = explode("\n", $csv);

  Mediante este par de líneas recuperaremos el precio histórico de una criptomoneda desde coingecko.com en formato CSV, una vez recuperado el archivo lo separaremos línea por línea para poderlo analizar.

  Si hubo resultados (caso contrario mostraremos un aviso de error) iremos dividiendo cada línea en columnas y cargaremos las que nos interesan.

  Como nos interesa solo tener los datos de los últimos seis meses aplicaremos dicho filtro (coingecko.com retorna todo el historial existente) recuperando únicamente los últimos 180 registros (es uno por día):

$i = 0;
$j = 0;
$pos = 0;
$max = 0;
    
if(count($lines) <= 180)
{

    $pos = 0;
    $max = count($lines);
  
}
else
{

    $max = count($lines);
    $pos = ($max - 180) - 1;
  
}

for($j=$pos; $j < $max; $j++)
{

    if(trim($lines[$j]) != "")
    {

         if(strpos(".".strtolower(trim($lines[$j])), "snapped_at") <= 0)
 {

$myarray = explode(",", trim($lines[$j]));
  
$time[$i] = date("d/m/Y", strtotime(substr(trim($myarray[0]), 0, 10)));
$history[$i] = trim($myarray[1]);

$i++;
  
  }
    
}

  }

Una vez recuperados vamos a empezar a generar nuestro gráfico:

$DataSet = new pData();   
$DataSet->AddPoint($history, "Serie1"); 
$DataSet->AddAllSeries();  
$DataSet->SetAbsciseLabelSerie("X");
$DataSet->SetSerieName("USD", "Serie1"); 
 
$Cache = new pCache();  
$Cache->GetFromCache("Graph1", $DataSet->GetData());  
          
$Test = new pChart(1038, 486);  //full area to work
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 8);  
$Test->setGraphArea(50, 60, 981, 458); //graph area 

//gray body rectangle
$Test->drawFilledRoundedRectangle(7, 7, 993, 482, 5, 240, 240, 240);  
$Test->drawRoundedRectangle(5, 5, 995, 484, 5, 230, 230, 230);

$Test->drawGraphArea(255, 255, 255, TRUE); //graph background color  
$Test->drawScale($DataSet->GetData(), $DataSet->GetDataDescription(), SCALE_NORMAL, 0, 0, 0, TRUE, 0,2); //usd metter colors 
 
//configure bar color, thanks to http://wiki.pchart.net/doc.settings.setpalette.html
$Test->setColorPalette(0, 63, 153, 178);  
$Test->setLineStyle(2); //heigth line border thanks to http://pchart.sourceforge.net/documentation.php?topic=pChart#

// Draw the cubic curve graph
$Test->drawCubicCurve($DataSet->GetData(), $DataSet->GetDataDescription());  

// series titles
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 13);  
$Test->drawLegend(872, 32, $DataSet->GetDataDescription(), 255, 255, 255);  

//title
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 16);  
$Test->drawTitle(50, 32,"Historial ".trim($name)." (6 meses)", 50, 50, 50, 585);  
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 13);  
$Test->drawTitle(50, 52,"Fuente: Coingecko.com", 50, 50, 50, 585);  

$diff1 = 798 / 3;
$pos1 = 0;
$pos4 = count($time) - 1;
$diff2 = ceil(($pos4 - $pos1) / 3);
$pos2 = (($pos1 + $diff2)) - 1;
$pos3 = ($pos2 + $diff2);
$pos1txt = $time[$pos1];
$pos4txt = $time[$pos4];
$pos2txt = $time[$pos2];
$pos3txt = $time[$pos3];

//x axis labels
$Test->setFontProperties("pChart/Fonts/tahoma.ttf", 10);  
$Test->drawTitle(46, 477, $pos1txt, 50, 50, 50);  
$Test->drawTitle(909, 477, $pos4txt, 50, 50, 50);
$Test->drawTitle(111 + $diff1 - 70, 477, $pos2txt, 50, 50, 50);
$Test->drawTitle(111 + ($diff1 * 2) + 5, 477, $pos3txt, 50, 50, 50);

// Render the graph  
$Cache->WriteToCache("Graph1",$DataSet->GetData(),$Test);  
$Test->Stroke();

  Este script hace uso de la librería pChart la cual se encarga de generarnos diversos tipos de gráficos a partir de un archivo CSV o un array de datos. La pueden descargar desde http://pchart.sourceforge.net/ y se encuentra liberada bajo licencia GPL.

  Si todo está listo, ya tenemos la estructura de nuestro script teniendo en la carpeta raíz los archivos index.php, graph.php, emptyframe.html, la carpeta Cache y la pChart (misma que contiene la librería) entonces ya solo resta ir a nuestro navegador web (previamente iniciado nuestro servidor web) y teclear http://127.0.0.1/historico (o el nombre que le hallamos dado a nuestro proyecto) y una vez mostrada la página de inicio podemos seleccionar la criptomoneda que gustemos para ver su comportamiento.

He aquí algunos ejemplos:

Bitcoin:
Historico Bitcoin

Ethereum:
Historico Ethereum

Monero:
Historico Monero

   El script completo lo pueden bajar en formato zip desde el siguiente link que a continuación se mostrará. Una vez descargado el archivo zip descomprimirlo y dentro encontraremos una carpeta llamada "historico", esa carpeta la copiaremos a donde se encuentre la carpeta "htdocs" de nuestra instalación de XAMPP, iniciaremos el servidor web y teclearemos en la barra del navegador web http://127.0.0.1/historico para empezar a usarlo.


Conclusiones:


  Concluimos con este artículo donde se muestra como poder empezar a analizar el comportamiento de las criptomonedas a lo largo del tiempo. Sin embargo estas no solo sirven para almacenarse como dinero, sino para todo comercio electrónico (siempre y cuando la otra persona las acepte), pero también se están desarrollando proyectos para por ejemplo almacenar archivos, documentos muy importantes y muchísimas aplicaciones basadas en el blockchain. Si aún no han leido los diversos artículos dedicados a las criptomonedas en este blog, les pido por favor lo hagan haciendo clic en este enlace. Gracias por leernos.

Procedencia de las imágenes:
File: Criptomonedas
URLhttp://shadowmyst.net/tag/criptomonedas/
Licencia: Creative Commons

¿Te gustó este post?, entonces si lo deseas puedes apoyarnos para continuar con nuestra labor, gracias.



Licencia de Creative Commons Esta obra está bajo una licencia de Creative Commons Reconocimiento 4.0 Internacional, haga clic aquí para conocer más detalles.


Compartir:



Directorio de blogs, ¡agrega el tuyo!
Programas para el mantenimiento de Windows
Blog de seguridad informatica