如何从Amibroker持续导出数据

需要测试用于日间交易的algotrading工具。 为了从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 = 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; 

看起来你不断向服务器询问有关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)。

构建事件代码

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