Блог им. karat39

По следам .Net Core 1.0

Для начала, хотел бы сказать спасибо пользователю crazyFakir для отслеживания темы c# в Линукс. Последняя его заметка рассказала нам об официальном релизе шарпа в Линукс.

  Для чего?

      Ну наверное для того, чтобы расширить возможности c++. Это не говорит о том, что с++ не все силен, просто нам теперь дают возможность более быстро решать задачи в виде большого количества оберток с заглавной вывеской .Net. Я честно пытался решить массу задач на c++, но бросил эти затеи, оставшись на c# под Windows. Игра в данном случае не стоит свеч.

  Когда использую C#

     Шарп использую для обслуживания трейдинга. Я очень много выкачиваю данных для анализа. А именно:
  • Выкачивание cme отчетов и парсинг pdf. Складирование все БД;
  • Парсинг yohoo, nymex для ведения истории ОИ опционов американских акций;
  • Парсинг micex на предмет все возможных данных, складирование все в БД;
  • Выкачивание и парсинг с ftp micex, складирование все в БД;
  • Парсинг всевозможных банковских курсов валют;
  • … другой разбор рыночных данных.

  Почему Linux

     Ну во-первых, думаю, кто «подсел» на идеологию, с пути уже не свернет. Во-вторых, вся работа на линуксе. В третьих, мне очень удобно арендовать, либо возможно использовать на работе, сервер, к которому я не буду привязан и на котором ведется автоматический сбор данных без моего участия. Когда, ты привязан, к личной рабочей машине, тебе постоянно нужно следить, чтобы обязательно она была включена утром, для запуска софта, днем, для мониторинга и поздно вечером для финального выкачивания Америки.

  .Net Core 1.0

Майкрософт анонсировал выход движка .Net Core — аналог .Net Framework под Windows. Так же, выходит Entity Framework 1.0 — фреймворк для работы с базами данных, на основе классов и коллекций, что тоже не может не радовать. Забегая вперед, скажу, что .Net Core очень схож с Framework, правда не такой еще полный, но все равно, переносимость кода оказалось очень и очень высокой.

  Для начала

     Стартовать очень просто. Для начала тут смотрим, как и что поставить. Там же написано, как инициализировать c# проект.
Далее вот тут смотрим описание всех оберток и классов в фреймворке. Ссылка очень выручила.

  Пример

Ну для начала про переносимость. Много что попробовал: потоки, регулярные выражения, лямбда функции — все держит и переносится без проблем. Для теста, мне было интересно, я запустил свои две функции для парсинга тагов и аттрибутов html.
        public static string GetBetweenTagData(string tag, string line) {
            string Result = "";
            string pattern = string.Format(@"\<{0}.*?\>(?<tagData>.+?)\<\/{0}\>", tag.Trim());
            // \<{0}.*?\> - открывающий тег
            // \<\/{0}\> - закрывающий тег
            // (?<tegData>.+?) - содержимое тега, записываем в группу tegData
            Regex regex = new Regex(pattern, RegexOptions.ExplicitCapture);
            MatchCollection matches = regex.Matches(line);
            if (matches.Count > 0)
                Result = (matches[0].Groups["tagData"].Value);
            return Result;
        }

        public static string GetTagValue(string param_name, string line) {
            string Result = "";
            //string pattern = string.Format(@".*?{0}=(?<paramData>.+?) ", param_name.Trim());
            string pattern = string.Format(@".*?{0}=[\',\''](?<paramData>.+?)('>|'\s)", param_name.Trim());
                        // \<{0}.*?\> - открывающий тег
            // \<\/{0}\> - закрывающий тег
            // (?<tegData>.+?) - содержимое тега, записываем в группу tegData
            Regex regex = new Regex(pattern, RegexOptions.ExplicitCapture);
            MatchCollection matches = regex.Matches(line);
                        if (matches.Count > 0)
                                Result = matches[0].Groups["paramData"].Value;
            return Result;
        }       
     С чем столкнулся. Столкнулся либо с пока еще нереализованными возможностями самого .Net Framework'а и кое что пришлось переписывать, так же обратил внимание, что много методов в .Net Core 1.0 реализовано для асинхронного запуска. Что тоже пришлось переделывать под Task, async, await.
    Ну например, выкачивать html теперь пришлось вот так путем Task, так как все методы для http реализованы в стиле «Async»
               static async Task<string> DownloadPageAsync()     {
                        using (HttpClient                       httpClient              = new HttpClient()) 
                        using (HttpResponseMessage      httpResponse    = await httpClient.GetAsync("http://www.dohod.ru/ik/analytics/dividend"))
                        using (HttpContent                      content                 = httpResponse.Content) {
                                string result = await content.ReadAsStringAsync();
                                return result;
                        }
                }       
Кому интересен так же main, привожу. Кстати код парсит заглавную страницу с дивидендными бумагами для дальнейшего анализа и обработки.
               public static void Main(string[] args)
        {
                        string                          htmlCode                = DownloadPageAsync().Result;                                   //Загрузка страницы N компании
                        string                          htmlTableData   = htmlCode.Substring(htmlCode.IndexOf("<tbody>") + 7, 
                                                                                                                                         htmlCode.IndexOf("</tbody>") - htmlCode.IndexOf("<tbody>") - 7)
                                                                                                                                         .Trim()
                                                                                                                                         .Replace((char)10, ' ')
                                                                                                                                         .Replace('\"', '\'');  //Получение таблицы в html
                        string                          tableRow                = "";
                        string                                  result                  = "";
                        int                                     nColumn         = 0;
                        
                        while ((tableRow = GetBetweenTagData("tr", htmlTableData).Trim()) != "" ) {                                       //Проход всех строк таблицы
                                string  tableCol        = "";
                                                result          = "";
                                                nColumn         = 0;
                                while (tableRow.IndexOf("td") > 0) {                                                                                   //Проход столбцов строки
                                        nColumn++;
                                        tableCol = GetBetweenTagData("td", tableRow).Trim();
                                        switch (nColumn) {
                                                case 1: {
                                                        if (tableCol.Contains("href"))
                                                                tableCol = GetTagValue("href", tableCol) + "\t" + GetBetweenTagData("a", tableCol);     
                                                        else
                                                                tableCol = "\t" + tableCol;
                                                } break;
                                                case 5: {
                                                        tableCol = GetTagValue("title", tableCol);
                                                } break;
                                                case 10: {
                                                        tableCol = GetTagValue("title", tableCol);
                                                } break;
                                        }
                                        tableRow = tableRow.Remove(0, tableRow.IndexOf("</td>") + 5); 
                                        result = result + "\t" + tableCol;
                                }
                                if (result.Length > 0)
                                        Console.WriteLine(result);
                                htmlTableData = htmlTableData.Remove(0, htmlTableData.IndexOf("</tr>") + 5);
                        }
                }
    }
     Вообщем пока можно сказать, что пришли одни вкусняшки, по мере усложнения задач, будем посмотреть, как оно пойдет. За код сильно не критикуйте. Не кодил c# около 4-5 месяцев. С с++ сразу не перейти на все плюшки.
★17
26 комментариев
avatar
crazyFakir, посмотрел дорожную карту. Интересно, замахнулись даже на низко уровневые api линукса.
avatar
смотрел одну из презентаций Майкрософта как раз на эту тему. Ответ на вопрос «Зачем» проще — они хотят чтобы код на шарпе мог работать везде, практически на любом устройстве, на любой ОС.

Показывали даже что-то скомпиленное под Распберри Пи.
avatar
Stan Sokolov, ну по сути, он уже действительно может работать на любой ОС. В принципе, это очень удобно, если это будет без сильных накладных расходах.
avatar
Андрей К, я уже не помню деталей, но само направление мне нравится, они разворачиваются в сторону опенсорса.

Идея в том что кроссплатформенность + опенсорс даёт хороший буст к развитию всего вместе. В том плане что начинают больше всего писать, больше полезных\прикольных\уникальных\интересных решений, больше народа привлекают и т.д.

Как пример — написание приложений, которые работают как на мобильной Win10, так и на десктопной. А .Net Core это шаг ещё дальше, т.е. они хотят быть везде, на любом рынке.
avatar
Какие задачи решали на С++ и почему не справились?
avatar
Cristopher Robin, все вышеописанные. 
Не то, чтобы не справился. Я взялся переписывать их с действующего кода шарпа. Задачи типовые: http, запросы get/post, бд, pdf и тд. И бросил это дело. Я пока не располагаю стольким временем, чтобы еще и в свободное время столько кодить.
С появлением .Net Core естественно я теперь очень рад. Месяца за 3 потихоньку перенесу код.
avatar
Андрей К, а с какой целью переписывали, чего хотели добится?
avatar
Cristopher Robin, перетащить все на линукс. Создать полноценный автономный надежный сервер для автоматического складирования своих данных, с доступом к ним по основным протоколам, например банальный http.
avatar
Андрей К, имхо, ваши задачи можно было бы успешно решать под windows.
avatar
Cristopher Robin, под Windows не спорю. Но я в посте все описал:
— я подсел на linux и полюбил его
— я хочу иметь полностью автономный сервер. Это пожалуй самое главное. Тут и Linux бесплатный, и возможностей расширить все бесплатно всякие плюшки, эффективно тут будет на мой взгляд побольше. А я пришел уже к тому, что нужно сокращать косты. Уже даже и биржа ввела плату за свои данные. Там заплатишь, сям заплатишь, в мес уже может выходить не мало.
avatar
Андрей К, почему не получалось сделать автономный сервер под Виндовс? Чисто потому, что платный?
avatar
MyProfit, на вскидку:
  — платный
  — аренды на win дороже
  — затратный по ресурсам (это очень важно для меня), хочу простую консоль
  — у меня вся работа на linux. пересаживаться на win, делать что то серьезное глобальное, для меня уже затратно по времени (вникать в нюансы и тд).
avatar
Столько много делаешь.
А сколько у тебя прибыль при этом?
Всё равно в чем: в енотах североамериканских, в процентах, в деревяшках...?
avatar
Shoker, не знаю что вам сказать. Активная ручная торговля прекратилась. Ручная торговля перешла в стадию «подзаработать», «подхалтурить». Статистика заработков поэтому нарушена. Будем считать, что нисколько, что это все для ресерча, но в любом случае могу сказать, что работает делается далеко не зря.
И я бы не сказал, что это много. Весь анализ автоматический формируется минут за 10 в конце дня. 
avatar
Андрей К, всё равно круто )) нарабатываешь опыт.

а в части трейдинга и IT надо повышать эффективность.

а ты в ученики в программировании не берёшь ?)))
avatar
Shoker, да, опыт нарабатывается сильно. Все это пришло за 3 года активной торговли (именно активной ежедневной торговли), постоянного изучения и читания. Сейчас это является некой визитной карточкой в любом личном разговоре, например с потенциальными работодателями. + я не один все это развивал. Есть еще коллега, он обороты не снижает, его еквити растет не плохо. + с каждой новой разработкой только выравнивается. А я просто перешел в режим 5-10 сделок в месяц, в идеале через год перейти 1-5 в год, которые будут делать весь личный финансовый план года.

Что насчет учеников. Еще бы год назад, взял бы не задумываясь. Мне это и нравится делать и в плане иметь вторую подпитку. Но сейчас просто нехватка времени. Поэтому извините, даже если и соглашусь, подведу потом либо в сроках, либо в отдаче.
avatar
 не понятно, чем это лучше Mono?
avatar
vlad1024, тут мне сложно поддержать разговор, опыта нет. Я изначально воспринимал mono как некую прокладку, частично официально признаной. В связи с этим, считаю, что могут быть последствия, если задачи усложнить. Поэтому до последнего в шарпе писал под windows, так более надежно, а надежность в нашем деле самое главное =)
avatar
крутые ребята, тоже думал об этом
avatar
Борис Литвинов, вы про шарп под линукс? А чего думать, все очень просто на деле =)
avatar
Кстати собрали кодом все дивидендные выплаты по компаниям за весь период
avatar
Кстати собрали кодом все дивидендные выплаты по компаниям за весь период
В силах здесь выложить алгоритм «на пальцах» для особо одаренных (без кода): какая сумма была изначально, за сколько дней входили в бумаги, как делили сумму если на отсечку попадало более одного эмитента, когда выходили из акций?   
avatar
ИзЛеса, вы наверное меня не правильно поняли. Этим комментарием я имел ввиду, что с помощью этого кода собрали статистику по всем дивидендным выплатам всех компаний  за всю их историю.
avatar
А некисло там у Вас статистики правильной собралось…
avatar
facevalue, есть немножко =)
avatar

теги блога Андрей К

....все тэги



UPDONW
Новый дизайн