Объектно-ориентированный дизайн для инвестиционного /фондового и опционного портфеля в Python

Я начинающий /средний программист Python, но я не написал приложение, только сценарии. В настоящее время я не использую много объектно-ориентированного дизайна, поэтому мне бы хотелось, чтобы этот проект помог мне развить навыки OOD. Проблема в том, что я не знаю, с чего начать с точки зрения дизайна (я знаю, как создавать объекты и все такое). Что бы это ни стоило, я тоже самоучка, без формального образования по CS.

Я хотел бы попробовать написать программу для отслеживания позиций портфеля акций /опционов.

У меня есть приблизительное представление о том, что может быть хорошим кандидатом на объект (портфолио, акции, опцион и т. д.) и методах (покупка, продажа, обновление и т. д.).

Длинная позиция будет покупать-открывать и продавать-закрываться, в то время как короткая позиция будет продавать-открывать и покупать-закрывать.

portfolio.PlaceOrder(type="BUY", symbol="ABC", date="01/02/2009", price=50.00, qty=100)
portfolio.PlaceOrder(type="SELL", symbol="ABC", date="12/31/2009", price=100.00, qty=25)
portfolio.PlaceOrder(type="SELLSHORT", symbol="XYZ", date="1/2/2009", price=30.00, qty=50)
portfolio.PlaceOrder(type="BUY", symbol="XYZ", date="2/1/2009", price=10.00, qty=50)

Затем, когда этот метод вызывается, как мне хранить информацию? Сначала я думал, что у меня будет объект Position с такими атрибутами, как Symbol, OpenDate, OpenPrice и т. Д., Но задуматься об обновлении позиции для учета продаж становится непросто, поскольку покупки и продажи происходят в разное время и в разном количестве.

  • Купить 100 акций, чтобы открыть, 1 раз, 1 цена. Продаю 4 разных раза, 4 разных цены.
  • Купите 100 акций. Продайте 1 акцию в день на 100 дней.
  • Купите 4 разных раза, 4 разных цены. Продать всю позицию за 1 раз по 1 цене.

Возможное решение - создать объект для каждой акции, таким образом, каждая акция будет иметь разные даты и цены. Это было бы слишком много накладных расходов? В портфолио могут быть тысячи или миллионы маленьких объектов Share. Если вы хотите узнать общую рыночную стоимость позиции, вам понадобится что-то вроде:

sum([trade.last_price for trade in portfolio.positions if trade.symbol == "ABC"])

Если бы у вас был объект позиции, вычисление было бы простым:

position.last * position.qty

Заранее спасибо за помощь. Глядя на другие посты, очевидно, что ТАК для «помощи», а не для «написания вашей программы для вас». Я чувствую, что мне просто нужно какое-то направление, указывающее правильный путь.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ОТРАЖЕНИИ Цель Программа будет отслеживать все позиции, как открытые, так и закрытые; с возможностью видеть подробную прибыль и убыток.

Когда я думаю о подробном P & L, я хочу увидеть ...  - все открытые даты (и закрытые даты)  - время проведено  - цена открытия (дата закрытия)  - P & L, так как открыт  - P & L в день

@Senderle

  

Я думаю, что, возможно, вы воспринимаете метафору «объект» слишком буквально, и поэтому пытаетесь превратить объект, который в некотором смысле кажется очень похожим на объект, в объект в смысле программирования этого слова. Если это так, то это ошибка, которую я принимаю за точку соприкосновения.

Это моя ошибка. Думая об «объектах», объект share кажется естественным кандидатом. Только до тех пор, пока не появятся миллионы, идея кажется безумной. У меня будет свободное время для кодирования в эти выходные, и я постараюсь создать объект с количеством.

7 голосов | спросил Jason Wirth 23 MaramWed, 23 Mar 2011 04:26:21 +03002011-03-23T04:26:21+03:0004 2011, 04:26:21

4 ответа


0

При проектировании такой системы следует учитывать два основных принципа:

  1. Устраните избыточность ваших данных. Никакая избыточность не гарантирует целостность.
  2. Храните все данные, необходимые для ответа на любой запрос, с минимальным уровнем детализации.

Исходя из этих правил, я предлагаю сохранить файл журнала транзакций. Каждая транзакция представляет собой какое-то изменение состояния и все относящиеся к нему факты: когда, что, покупка /продажа, сколько, сколько и т. Д. Каждая транзакция будет представлена ​​записью (именованный кортеж полезен здесь) в плоском файле. Годы транзакций (или даже 5 или 10 лет) должны легко помещаться в списке резидентов памяти. Затем вы можете создавать функции для выбора, сортировки и суммирования любой необходимой вам информации из этого списка, и, будучи резидентом памяти, она будет удивительно быстрой, намного быстрее, чем база данных SQL.

Когда и если журнал транзакций становится слишком большим или слишком медленным, вы можете вычислить состояние всех ваших позиций на определенную дату (например, на конец года), использовать его для начального состояния на следующий период и архивировать ваш старый файл журнала на диск.

Вам может потребоваться некоторая вспомогательная информация о ваших активах, такая как стоимость /цена на конкретную дату, чтобы вы могли построить график зависимости стоимости от времени для любого или всех холдингов (существуют онлайновые источники для этого типа информации, Yahoo Finance для одного.) Также будет полезна основная база данных, содержащая статическую информацию о каждом из ваших владений.

Я знаю, что это звучит не очень "объектно-ориентировано", но ОО-дизайн может быть полезен, чтобы скрыть подробную работу системы в TransLog объект с методами для сохранения /восстановления данных на /с диска (методы сохранения /открытия), ввода /изменения /удаления транзакции; и дополнительные методы для обработки данных в значимые информационные дисплеи.

Сначала напишите API с интерфейсом командной строки. Когда это работает к вашему удовлетворению, вы можете перейти к созданию интерфейса GUI, если хотите.

Удачи и веселья!

ответил Don O'Donnell 25 MaramFri, 25 Mar 2011 10:22:20 +03002011-03-25T10:22:20+03:0010 2011, 10:22:20
0

Избегайте предметов. Объектно-ориентированный дизайн несовершенен. Думайте о своей программе как о совокупности поведений, которые работают с данными (списки и словари). Затем сгруппируйте ваши связанные поведения как функции в модуле. Каждая функция должна иметь четкие входы и выходы. Храните ваши данные глобально в каждом модуле. Почему это без предметов? Потому что это карты ближе к проблемному пространству. Объектно-ориентированное программирование создает слишком много косвенных факторов, чтобы решить проблему. Ненужная косвенность приводит к раздутию программного обеспечения и ошибкам.

Возможное решение - создать объект для каждой акции, таким образом, каждая акция будет иметь разные даты и цены. Это было бы слишком много накладных расходов? В портфолио могут быть тысячи или миллионы маленьких объектов Share. Если вы хотите узнать общую рыночную стоимость позиции, вам понадобится что-то вроде:

Да, это было бы слишком много накладных расходов. Решение здесь заключается в том, что вы будете хранить данные в базе данных. Поиск общей рыночной стоимости позиции будет выполняться в SQL, если вы не используете схему NOSQL.

Не пытайтесь придумывать все возможные будущие результаты. Просто заставьте вашу программу работать так, как нужно сейчас.

ответил eat_a_lemon 23 MaramWed, 23 Mar 2011 05:36:37 +03002011-03-23T05:36:37+03:0005 2011, 05:36:37
0

Думаю, я бы разделил его на

  • авуары (то, что вы в настоящее время владеете или должны каждому символу)
  • заказы (простые требования купить или продать один символ за один раз)
  • сделки (коллекции заказов)

Это позволяет легко получать текущее значение, размещать заказы в очереди, создавать более сложные заказы и легко отображать их в объекты данных с базой данных за ними.

ответил Hugh Bothwell 23 MaramWed, 23 Mar 2011 06:01:27 +03002011-03-23T06:01:27+03:0006 2011, 06:01:27
0

Чтобы ответить на ваш вопрос . Похоже, у вас уже есть достаточно четкое представление о вашей модели данных. Но мне кажется, что вам нужно больше думать о том, что вы хотите, чтобы эта программа делала. Будет ли он отслеживать изменения цен на акции? Размещать заказы или предлагать размещать заказы? Или он будет просто отслеживать заказы, которые вы разместили? Каждое из этих применений может потребовать различных стратегий.

Тем не менее, я не понимаю, зачем вам нужен объект для каждой акции ; Я не понимаю причины этой стратегии. Даже если вы хотите иметь возможность отслеживать историю ваших заказов в мельчайших деталях, вы можете просто хранить сводные данные, как в «x в y долларов за акцию на дату z ».

Было бы более разумно иметь объект position (или holding (в терминологии Хью) - по одному на акцию, возможно, с атрибутом .order_history, если вы действительно нужна подробная история ваших владений на этом складе. И да, база данных определенно будет полезна для такого рода вещей.

Вкратце расскажу о философских взглядах : я думаю, что вы, возможно, слишком буквально воспринимаете метафору «объект» и пытаетесь сделать акцию, которая в некоторых отношениях кажется очень объектной. в объект в программном смысле этого слова. Если это так, то это ошибка, которую я принимаю за точку соприкосновения.

Я не согласен с ним, что объектно-ориентированный дизайн имеет недостатки - это довольно смелое заявление! - но его ответ правильный, поскольку «объект» (например, экземпляр класса) почти идентичен модулю **. Это коллекция связанных функций, связанных с некоторым общим состоянием. В экземпляре класса состояние совместно используется через self или this, пока он находится в модуле, он используется в глобальном пространстве имен.

Для большинства целей единственным существенным отличием между экземпляром класса и модулем является то, что может быть много экземпляров класса, каждый со своим независимым состоянием, в то время как может быть только один экземпляр модуля. (Конечно, есть и другие отличия, но в большинстве случаев они связаны с техническими вопросами, которые не очень важны для изучения OOD.) Это означает, что вы можете думать об объектах так же, как вы думаете о модулях, и это полезный подход здесь.

** Во многих скомпилированных языках файл, который получается при компиляции модуля, называется «объектным» файлом. Я думаю, это , откуда на самом деле происходит метафора «объект». (У меня нет никаких реальных доказательств этого! Так что любой, кто знает лучше, не стесняйтесь поправлять меня.) Повсеместные игрушечные примеры OOD, которые можно увидеть - car.drive(mph=50); car.stop(); car.refuel(unleaded, regular) - я верю, что это бэк-формации, которые могут немного запутать концепцию.

ответил senderle 24 MaramThu, 24 Mar 2011 03:16:26 +03002011-03-24T03:16:26+03:0003 2011, 03:16:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132