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

Я начинающий / средний программист 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 раз, по одной цене.

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

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

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

position.last * position.qty

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

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

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

@ Senderle

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

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

Ответы [ 4 ]

2 голосов
/ 25 марта 2011

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

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

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

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

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

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

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

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

1 голос
/ 23 марта 2011

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

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

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

1 голос
/ 24 марта 2011

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

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

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

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

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

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

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

1 голос
/ 23 марта 2011

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

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

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

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

...