domingo, 18 de julio de 2021

Quitar duplicados en un fichero con Amibroker

El algoritmo Amibroker que se incluye más abajo permite localizar filas duplicadas de un fichero pero por parejas. Está diseñado específicamente para quitar los duplicados en un fichero que contenga pares de cointegración pero también se puede aplicar a muchos otros usos que requieran localizar elementos duplicados de varias filas y eliminarlos automáticamente. Utiliza bucles anidados para conseguir la tarea de la forma más eficiente. Más detalles en el vídeo: 


CÓDIGO QUE QUITA DUPLICADOS

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// ESTE CÓDIGO QUITA LOS PARES DUPLICADOS DE UN FICHERO
// MIRA EN EL ORDEN DIRECTO E INVERSO Y BORRA LAS SIGUIENTES
// APARICIONES DE UNA MISMA PAREJA.
// OSCAR G. CAGIGAS
// 1 JULIO 2021
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Buy = Sell = Short = Cover = 0;
//para que no avise por el script
SetOption("warninglevel",1);

//ABRIMOS EL FICHERO
file = "C:\\TEMP\\pairs.txt"; 
fh = fopen( file, "r" );

//CONVERTIMOS LOS TICKERS EN PAREJAS SEPARADAS POR COMA
fila = 0;
while( ! feof( fh ) )
{
ticker1 = fgets( fh );
ticker2 = fgets( fh );
VarSetText("par"+ fila, ticker1 + "," + ticker2);
VarSetText("inv"+ fila, ticker2 + "," + ticker1);
fila++;

 
fclose( fh );

//COMPROBAR DUPLICADOS DE PAREJAS (ORDEN DIRECTO E INVERSO) 
//Y BORRARLOS MANTENIENDO LA PRIMERA APARICIÓN DE LA PAREJA
for( i = 0; i < fila ; i++)
{
for( j = 0; j < fila ; j++)
{
if( i != j ) 
{
match = VarGetText("par" + i) == VarGetText("par" + j);
inv_match = VarGetText("par" + i) == VarGetText("inv" + j);

//Si hay match borramos el par y su inverso
if( match OR inv_match )
{
VarSetText("par" + j, "");
VarSetText("inv" + j, "");
}
}
}
}

//ESCRIBIMOS LOS PARES AL FICHERO PERO UN TICKER POR LÍNEA
if ( Status("stocknum") == 0 ) //para que solo lo haga una vez por backtest
{

fh = fopen(file, "w" );
 
for( i = 0; i < fila; i++ )
{
ticker1 = StrExtract( VarGetText("par" +i ), 0);
ticker2 = StrExtract( VarGetText("par" +i ), 1);

if(ticker1 != "") fputs( ticker1, fh );
if(ticker2 != "") fputs( ticker2, fh );
}
fclose( fh );
}

4 comentarios:

  1. Otro código alternativo:

    // io file
    file = "C:\\TEMP\\pairs.txt";

    // Read and remove duplicates
    pairs = "";
    unique_pairs = "";
    fh = fopen( file, "r" );

    while( ! feof( fh ) )
    {
    ticker1 = fgets( fh );
    ticker2 = fgets( fh );
    pair = ticker1 + ticker2 ;
    invpair = ticker2 + ticker1;

    if( NOT StrFind( unique_pairs, pair ) AND NOT StrFind( unique_pairs, invpair ) )
    unique_pairs += pair;
    }

    fclose( fh );

    // Write uniques
    fh = fopen( file, "w" );
    fputs( unique_pairs, fh );
    fclose( fh );

    ResponderEliminar
    Respuestas
    1. Muchas gracias por este código. Me quito el sombrero :) Esta es una programación muy eficiente. Nunca se me hubiera ocurrido hacerlo así. Simplemente almacenando todo en un string y usando la función STRFIND() sale un código mucho más simple y elegante. Mi error fue pensar que tenía que utilizar la coma "," para separar los pares (cada uno tiene su longitud) y ahora me doy cuenta de que al venir por filas en un fichero ya vienen separados con el retorno de carro ("\n") y se puede simplificar todo. Genial!

      Eliminar
  2. Óscar, cómo haces para dar formato al código y no perder tabulaciones?

    ResponderEliminar
    Respuestas
    1. Seguramente es cosa del Blogger, que en términos de formato no es lo mismo publicar una entrada que un comentario. Simplemente lo he pegado desde Amibroker y sale con tabulaciones.

      Eliminar

ENTRADAS POPULARES