Необходимо протестировать инструмент 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;
Кажется, что вы постоянно запрашиваете у сервера данные о 100.000 баров, хотя ему требуется только последнее.
Я бы создал этот обзор один раз, установил флажок в коде, если это было сделано, и когда это будет сделано, обновляйте только данные, повторяя их в обратном порядке, пока полученное время barOpen не сравняется с барами, уже находящимися в обзоре.
Избавься от петель. 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 находятся на одном компьютере, вы можете использовать события сборки, в противном случае вы можете создать командный файл. При первом запуске, сначала запустите часть регистрации (закомментируйте незарегистрированный код). Каждый раз, когда я перекомпилирую свою 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