Страница 1 из 12
AdirConnector
Добавлено: 05 янв 2019, 23:29
ensh
Итак, сегодня мы напишем простейшее приложение-терминал с командной строкой, на основании базовых библиотек Alfa Direct Pro 4.0. Это не сложно.
Забудьте про индикаторы, стратегии роботы, api и прочий хлам! Все эти инструкции вам больше не нужны!
Теперь, только тонкая прослойка асинхронных сокетов и, сравнительно, полезное, ядро терминала (я вас научу как и его отключить;) ) отделяет вас от серверов Alfa Direct!
Теперь, только ВАШ КОД, КОТОРЫЙ ВЫ ПИШЕТЕ САМИ, получит непосредственный доступ к каждой циферке терминала и сможет максимально эффективно реализовывать любую торговую стратегию.
А если Вам станет скучно - дерзайте, ваяйте свою графику и померейтесь с разработчиками терминала своим крутейшим дизайном ))))
Re: AdirConnector
Добавлено: 05 янв 2019, 23:51
ensh
Итак приступаем, пристегните ремни.
1. Находим папку Alfa-Direct Pro инсталляции терминала в C:\Program Files (x86) и КОПИРУЕМ ее в отдельный каталог с вашими правами, например c:\temp, чтобы меньше проблем. Далее, подразумеваем, что все действия происходят с КОПИЕЙ папки.
2. В папке находим файл ADirect.exe, запускаем, все работает? Да! - Отлично продолжаем...
3. Можно переименовать папку например на Alfa-Direct Connector
4. Запускаем Visual Studio 2017, надеюсь
5. Создаем консольный проект (назовем его AdirConnector) с версией .Net Framework 4.5 (это для крайней версии терминала) предыдущие версии терминала работали под .Net Framework 4.0.
6. В свойствах проекта, сразу настроим папку для отладки и компиляции (свойство Выходной путь или Output path чтоле) обычно там bin\Debug.
7. Трррррррреемммм - приступаем к добавлению сборок от терминала в проект: открываем диалоговое окно добавления сборки -> выбираем режим обзор -> в диалоговом окне находим и добавляем (сразу или по очереди) Core.dll, ADUtils.dll, ADir.NetProtocol.dll, ADir.ClientStructures.dll, ADir.BaseStructures.dll (в ранних версиях NetProtocol.dll, ClientStructures.dll, BaseStructures.dll)
8. Сохраняем проект переводим дух, удалим из проекта ненужный app.config, если есть.
Re: AdirConnector
Добавлено: 05 янв 2019, 23:54
ensh
Теперь приступим к коду, файла Program.cs
вот собственно:
Код: Выделить всё
using System;
using AD.Common.Helpers;
using AD.Common.DataStructures;
namespace AdirConnector
{
class Program
{
static void Main(string[] args)
{
// настройка системы логирования
LogFileManager.Instance.FolderPath = @"C:\TEMP\AdirConnector\Logs\";
LogFileManager.Instance.LoggingLevel = EventsLoggingLevels.All;
LogFileManager.Instance.SizeLimit = 32u << 20;
RunProcessing(); // программа где-то здесь
Console.ReadLine(); // ожидаем нажатия Enter, что приведет к дисконнекту
Core.ADConnection.Instance.Disconnect();
Console.ReadLine(); // ожидаем нажатия Enter, что приведет к выходу из программы
LogFileManager.Instance.WriteAllStream(); // сбрасываем на диск все логи, из буферов
}
static void Instance_ConnectionChanging(Core.LogicConnectionStatus status)
{
Console.WriteLine(String.Format("Instance_ConnectionChanging({0})", status.ToString()));
}
static void Instance_OnConnectionStatusChanged(FrontEndType frontendType, ConnectionStatus status)
{
Console.WriteLine(String.Format("Instance_ConnectionChanged({0}, {1})", frontendType.ToString(), status.ToString()));
}
static void RunProcessing()
{
Core.ConnectionInfo.Instance.Load(ApplicationPaths.ConnectionInfoFilePath);
Core.ADConnection.Instance.ConnectionChanging += Instance_ConnectionChanging;
Core.ADConnection.Instance.OnFrontEndConnectionStatusChanged += Instance_OnConnectionStatusChanged;
Console.Write("Login=>");
var login = Console.ReadLine();
Console.Write("Password=>");
var password = Console.ReadLine();
Core.ADConnection.Instance.Login(login, password);
}
}
}
Re: AdirConnector
Добавлено: 06 янв 2019, 00:04
ensh
Компилируем, запускаем...
Вводим логин и пароль и вуаля... надеюсь, успешно, подключились к серверам Alfa Direct
Теперь у нас из коробки весь невизуальный движок (ядро) терминала Alfa Direct, при должной сноровке, можно переписать свой Core.dll,
Ядро само подключается, авторизуется, отвечает и передает запросы, логирует, пишет локальные базы.
Обращаем внимание на всевозможные менеджеры, типа OrdersManager, OperationManager, PositionManager, BalanceManager, ChatManager, и тд и тп.
Все что относится к графикам ChartHistoryManager, Chart..., а также всякие Robot... лучше не трогать они не нужны.... воооще не нужны и точка, лучше все писать самим.
Re: AdirConnector
Добавлено: 06 янв 2019, 00:08
ensh
Теперь научимся подписываться на данные
для этого изменим код метода:
Код: Выделить всё
static void Instance_ConnectionChanging(Core.LogicConnectionStatus status)
{
Console.WriteLine(String.Format("Instance_ConnectionChanging({0})", status.ToString()));
if (status == Core.LogicConnectionStatus.Conneceted)
{
// подпишемся на что-нибудь интересное
// чат
Core.SubscriptionManager.Instance.SubscribeChat();
// свои сделки
Core.SubscriptionManager.Instance.SubscribeOperations();
//стаканы AAPL
Core.SubscriptionManager.Instance.SubscribeQueue(218182);
// сделки биржи
Core.SubscriptionManager.Instance.SubscribeStream(Core.SubscribeFilterType.MarketTrades, 218182);
// инстумент инфо
Core.SubscriptionManager.Instance.SubscribeStream(Core.SubscribeFilterType.FinInfoExt, 218182);
// котировки
Core.SubscriptionManager.Instance.SubscribeStream(Core.SubscribeFilterType.Quotes, 218182);
// график
var rq = new ArchiveRequestEntity()
{
IdRequest = 1,
IdFi = 218182,
TimeFrame = BaseTimeFrame.Hour,
CandleType = CandleType.Standard,
DaysCount = -100,
MaximumDate = DateTime.MaxValue,
Created = Core.ConnectionManager.Instance.GetServerTime()
};
Core.ConnectionManager.Instance.SendPacket(rq, FrontEndType.BirzArchAndMediaServer);
}
}
существуют также групповые методы, которые принимают список idFi, но помним про ограничения на подписку и методы UnSubscribe
Re: AdirConnector
Добавлено: 06 янв 2019, 00:12
ensh
как работать с менеджерами... ну например...
создадим таймер на 1000 мсек, например, и в обработчике напишем
Код: Выделить всё
static void OnTimer(Object source, ElapsedEventArgs e)
{
if (Core.Notifications.Instance.TryGetMessagesUpdate(out var messages))
foreach (var line in messages.Select(mm => mm.TextDisplayMessage))
LogFileManager.AddInfo(line, "notification");
if (Core.PositionManager.Instance.TryGetChanges(out var positionUpdates, out var balanceUpdates))
{
lock (Core.PositionManager.Instance.Positions.Locker)
{
foreach (var pos in positionUpdates
.Select(pu => Core.PositionManager.Instance.Positions.Primary[pu])
.OfType<ClientTradePosition>())
{
LogFileManager.AddInfo(pos.ToString(), "positions");
}
}
lock (Core.PositionManager.Instance.Balances.Locker)
{
foreach (var bal in balanceUpdates
.Select(bu => Core.PositionManager.Instance.Balances.Primary[bu])
.OfType<ClientSubAccountBalance>())
{
LogFileManager.AddInfo(bal.ToString(), "balances");
}
}
}
if (Core.OperationsManager.Instance.TryGetChanges(out var operUpdates))
{
foreach (var oper in operUpdates)
LogFileManager.AddInfo(oper.Value.ToString(), "operations");
}
}
тут, для примера, все выводится в файл но можно что-то другое замутить
Re: AdirConnector
Добавлено: 06 янв 2019, 00:20
ensh
теперь можем переопределить стандартный обработчик, хотя можем навесить свой поверх имеющегося как-то так
Код: Выделить всё
static void Instance_OnConnectionStatusChanged(FrontEndType frontendType, AD.Common.DataStructures.ConnectionStatus status)
{
Console.WriteLine(String.Format("Instance_ConnectionChanged({0}, {1})", frontendType.ToString(), status.ToString()));
if (status == ConnectionStatus.Authorized)
{
// удаляем дефолтную обработку пакетов
var caller = typeof(Core.ConnectionManager).GetMethod("ConnectionManager_NewPacket", BindingFlags.NonPublic | BindingFlags.Instance);
if (caller != null)
{
var d = Delegate.CreateDelegate(typeof(Core.NewPacketEvent), Core.ConnectionManager.Instance, caller);
Core.ConnectionManager.Instance[frontendType].NewPacket -= (Core.NewPacketEvent)d;
Core.ConnectionManager.Instance[frontendType].NewPacket += NewPacket; // подставляем свою
}
}
}
static bool unpack(IADSerializable o, ICollection<IADSerializable> l)
{
l.Add(o);
return true;
}
static void NewPacket(FrontEndType frontendType, byte[] packet, DateTime packetTime, bool newPacket)
{
try
{
// разбор данных пакета
var list = new List<IADSerializable>();
Packer.UnpackEntityList<IADSerializable>(o => unpack(o, list), packet);
foreach (var e in list)
LogFileManager.AddInfo(e.ToString(), e.TypeID.ToString());
}
catch (Exception ex)
{
LogFileManager.AddError("NewPacket PackerException", ex);
}
}
для чего... там много всего тяжелого в стандартном обработчике, можно написать свой обработчик, а часть кода взять из стандартного, это нужно для своих роботов которые должны агрегировать сделки и получать графики, что сейчас сделано кривее некуда
Re: AdirConnector
Добавлено: 06 янв 2019, 00:22
ensh
на этом все, пока, надеюсь это поможет вам в написании эффективных стратегий и в прибыльной торговле
Re: AdirConnector
Добавлено: 12 янв 2019, 19:42
AP_Bor
Доброго времени суток,
enshensh писал(а):на этом все, пока, надеюсь это поможет вам в написании эффективных стратегий и в прибыльной торговле
Может возьметесь собрать объект для "Журнал трейдера" или еще чего интересного, вместе придумаем как его прикрутить, или времени швах? А у меня времени пока много, сам бы взялся, но компьютер и интернет подвели.
Это было-бы попыткой написать первый плагин для AD, да и повод пообщаться.
Может кто еще захочет присоединиться?Или, такого не было и вот опять?
Indigo-On » 03 дек 2018, 13:13 писал(а):В топку такие предложения!
► Показать
Народная мудрость программистов писал(а):Ходить по воде и разрабатывать ПО без "поддержки" легко. Просто нужно заморозить и то, и другое.
С наилучшими пожеланиями
Re: AdirConnector
Добавлено: 12 янв 2019, 20:50
ensh
А что такое журнал трейдера?