如何从Amibroker连续导出数据

本文关键字:数据 连续 Amibroker | 更新日期: 2023-09-27 18:13:32

需要测试一个用于日内交易的算法交易工具。为了从NSE获取每日实时数据,一些供应商正在销售Amibroker的数据插件。为了从Amibroker中获取数据,我打算使用 AFL (Amibroker Formula Language)。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;

如何从Amibroker连续导出数据

似乎您一直在向服务器询问有关100,000条的数据,而它只需要最后一个。

我只创建一次概览,在代码中设置是否已经完成的标志,完成后只通过向后迭代更新数据,直到接收到的barOpen时间等于概览中已经存在的条形图。

去掉for循环。Amibroker每次更新图表时都会运行AFL,因此使用这些for循环,每次图表更新时(当出现新报价时),您都要浏览数据库中的每个条形图,因此条形图越多,内存使用量就越高。您可以将i = 0设置为引用当前条。我只是一时想不起来。如果你做得不好,不介意写一个c# dll,告诉我,我会把代码贴出来。

没问题。

我是从

得到这个想法的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位于同一台机器上,则可以使用Build Events,否则,可以创建批处理文件。第一次运行这个程序时,首先运行寄存器部分(注释掉注销代码)。每次我重新编译我的DLL,我运行注销然后注册代码。我不确定是否有必要,但我还是做了。目标路径可以是你想要的任何文件夹,例如,我使用我的C:'驱动器上的一个文件夹。检查regasm在哪个文件夹中,因为它在不同的。net版本中是不同的(这是针对4.5)。

Build Events Code

"%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