Как постоянно экспортировать данные из Amibroker

Необходимо протестировать инструмент algotrading, который будет использоваться для дневной торговли. Чтобы получить данные в реальном времени от NSE, некоторые поставщики продают плагины данных для Amibroker. Чтобы получить данные из Amibroker, я собираюсь использовать AFL Амиброкер Формула Язык. Следующий код в AFL создает .csv файлы для каждого символа один раз. Но чтобы использовать живые данные, мне нужно добавить входящие данные в .csv файл непрерывно в течение дня. Как это можно сделать без сбоев / перегрузок Amibroker?

// created a directory on your C drive named AmiBroker data backup
dayhours = paramtoggle("Day hours only", "No|Yes");
fmkdir("c:\\AmiBackup\\");
setbarsrequired(100000,100000);
lname = Name(); // gets the name of the symbol
// note: if you have names with invalid characters like / you must rename the
file before you try to create a name 
// add an IF line for each symbol you need to rename
if (lname == "ER2U8-GLOBEX-FUT") lname = "ER2U8";

fh = fopen( "c:\\AmiBackup\\" + lname + ".csv", "w"); 
if( fh ) 
{ 
    if(interval() == inDaily OR interval() == inMonthly OR interval() == inweekly)
    {
        fputs( "Ticker,Date,Open,High,Low,Close,Volume \n", fh ); 
        for( i = 0; i < BarCount; i++ ) 
        { 
            y = Year(); 
            m = Month(); 
            d = Day(); 
            fputs( Name() + "," , fh );
            ds = StrFormat("%02.0f-%02.0f-%02.0f,", m[ i ], d[ i ], y[ i ] ); 
            fputs( ds, fh ); 
            qs = StrFormat("%.4f,%.4f,%.4f,%.4f,%.0f\n", O[ i ],H[ i ],L[ i ],C[ i
],V[ i ] ); 
            fputs( qs, fh ); 
            if(i == 65500 or i == 130000 or i == 196500 or i == 262000)
            {
                fclose( fh ); 
                if(i == 65500  ) fh = fopen( "c:\\AmiBackup\\" + lname + " A.csv", "w"); 
                if(i == 130000 ) fh = fopen( "c:\\AmiBackup\\" + lname + " B.csv", "w"); 
                if(i == 196500 ) fh = fopen( "c:\\AmiBackup\\" + lname + " C.csv", "w"); 
                if(i == 262000 ) fh = fopen( "c:\\AmiBackup\\" + lname + " D.csv", "w"); 
            }
        }
    }
    else // intraday so add time field
    {
        fputs( "Ticker,Date,Time,Open,High,Low,Close,Volume \n", fh ); 
        y = Year(); 
        m = Month(); 
        d = Day(); 
        r = Hour();
        e = Minute();
        n = Second();

        for( i = 1; i < BarCount; i++ ) 
        { 
            if (dayhours and lastvalue(timenum()) >= 92900 and lastvalue(timenum()) <=
161500)
            { 
                fputs( Name() + "," , fh );
                ds = StrFormat("%02.0f-%02.0f-%02.0f,", m[ i ], d[ i ], y[ i ] ); 
                fputs( ds, fh ); 

                ts = StrFormat("%02.0f:%02.0f:%02.0f,", r[ i ],e[ i ],n[ i ] ); 
                fputs( ts, fh ); 

                qs = StrFormat("%.4f,%.4f,%.4f,%.4f,%.0f\n", O[ i ],H[ i ],L[ i ],C[ i
],V[ i ] ); 
                fputs( qs, fh ); 
            }
            else
            { 
                fputs( Name() + "," , fh );
                ds = StrFormat("%02.0f-%02.0f-%02.0f,", m[ i ], d[ i ], y[ i ] ); 
                fputs( ds, fh ); 

                ts = StrFormat("%02.0f:%02.0f:%02.0f,", r[ i ],e[ i ],n[ i ] ); 
                fputs( ts, fh ); 

                qs = StrFormat("%.4f,%.4f,%.4f,%.4f,%.0f\n", O[ i ],H[ i ],L[ i ],C[ i
],V[ i ] ); 
                fputs( qs, fh ); 
            }
            if(i == 65500 or i == 130000 or i == 196500 or i == 262000)
            {
                fclose( fh ); 
                if(i == 65500  ) fh = fopen( "c:\\AmiBackup\\" + lname + " A.csv", "w"); 
                if(i == 130000 ) fh = fopen( "c:\\AmiBackup\\" + lname + " B.csv", "w"); 
                if(i == 196500 ) fh = fopen( "c:\\AmiBackup\\" + lname + " C.csv", "w"); 
                if(i == 262000 ) fh = fopen( "c:\\AmiBackup\\" + lname + " D.csv", "w"); 
            }
        } 
    }
    fclose( fh ); 
} 

Buy = 1;

3 ответа

Нет проблем.

У меня появилась идея сделать это из

https://adamprescott.net/2012/04/05/net-vb6-interop-tutorial/

Что вы собираетесь сделать, это создать библиотеку классов. Создайте интерфейс и класс, который реализует интерфейс. В вашем случае это будет примерно так:

namespace AmiCOMLib
{
    [ComVisible(true)]
    public interface IMyInterop
    {
        [DispId(1)]
        void SendQuotes(string quoteString);
    }//end interface  

    [ComVisible(true)]
    public class AmiCOM
    {
        public void SendQuotes(string quoteString)
        { 
            //process string here and save as CSV
        }
    }
  }

Вы можете отправить строку кавычки в виде строки, разделенной запятыми (как я обычно это делаю для длинных строк), и разделить ее в вашей DLL или отправить со многими параметрами.

Далее вы подготовитесь к регистрации вашей DLL. Если DLL и Amibroker находятся на одном компьютере, вы можете использовать события сборки, в противном случае вы можете создать командный файл. При первом запуске, сначала запустите часть регистрации (закомментируйте незарегистрированный код). Каждый раз, когда я перекомпилирую свою DLL, я запускаю разрегистрацию, а затем регистрирую код. Я не уверен, если это необходимо, но я все равно делаю это. Целевой путь может быть любой папкой, которую вы хотите, например, я использую папку на моем диске C:\. Проверьте, в какой папке находится regasm, поскольку он отличается для разных версий.NET (это для 4.5).

Построить код событий

"%WinDir%\Microsoft.NET\Framework\v4.0.30319\regasm" /tlb /unregister "$(TargetPath)"

echo UNREGISTERED

"%WinDir%\Microsoft.NET\Framework\v4.0.30319\regasm" /tlb /codebase "$(TargetPath)"

echo REGISTERED

xcopy "$(TargetPath)" "<folder where you want DLL to be copied to>" /D /Y

Пакетный файл

ECHO OFF

ECHO We're first going to unregister, then register AmiCOMLib

ECHO UnRegistering AmiCOMLib

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm" "C:\ATS\AmiCOMLib.dll" /unregister 

ECHO UNREGISTERED

PAUSE

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm" "C:\ATS\AmiCOMLib.dll" /tlb /codebase

ECHO REGISTERED

PAUSE

Наконец, я не помню почему, но я все равно делаю это, я подписываю сборку. Под Свойства> Подписание> Отметьте "Подписать сборку". Я просто выбираю вариант по умолчанию, он выглядит как assemblyName.dll.snk.

Чтобы использовать его, в вашем AFL сначала вы создадите статический объект (компилятор будет жаловаться на него, но использование статического объекта означает, что он создается один раз и используется совместно, в отличие от того, что он создавался много раз и потреблял вашу память - так что вы могу проигнорировать это, у меня никогда не было проблем с памятью при использовании):

AmiComObj = CreateStaticObject("AmiCOMLib.AmiCOM"); //note format is namespace.class
quoteString = Name() + "," + close; //or, for example, what you have in your fputs
AmiComObj.SendQuotes(quoteString);

Я лично использую этот метод для проверки определенных условий каждый тик, поэтому я знаю, что он работает для приложений реального времени.

Надеюсь, что это дает вам некоторые идеи.

Удачи.

Sethmo

Кажется, вы постоянно запрашиваете у сервера данные о 100 000 баров, хотя ему требуется только последнее.

Я бы создал этот обзор один раз, установил флаг в коде, если это было сделано, и когда это будет сделано, обновляйте только данные, повторяя их в обратном порядке, пока полученное время barOpen не сравняется с барами, уже находящимися в обзоре.

Избавься от петель. Amibroker запускает AFL каждый раз, когда ваш график обновляется, поэтому с помощью циклов for вы просматриваете каждый бар в базе данных каждый раз, когда график обновляется (когда появляется новая котировка), поэтому, чем больше у вас баров, тем выше использование памяти. Вы можете просто установить i = 0 для ссылки на текущий бар. Я просто схожу с макушки головы. Если вы не правы и не против написать C# dll, дайте мне знать, я выложу код.

Другие вопросы по тегам