Моя проблема: Я пытаюсь разработать веб-приложение для валютных трейдеров.Приложение позволяет трейдерам вводить или загружать информацию о своих сделках, и я хочу рассчитать широкий спектр статистики на основе того, что пользователь ввел.
Теперь обычно я бы использовал для этого реляционную базу данных, но у меня есть два требования, которые не очень хорошо подходят для реляционной базы данных, поэтому я пытаюсь использовать couchdb.Эти две проблемы: 1) Прежде всего, у меня есть настольное приложение-компаньон, с которым пользователи смогут работать и реплицироваться на сайт, используя удивительную функцию репликации couchdb, и 2) Я хотел бы позволить пользователям иметь возможность определять свои собственные пользовательские настройки.вещи, чтобы отслеживать о сделках и генерировать результаты, основанные на том, что они вводят.Схема без природы дивана кажется здесь идеальной, но может оказаться сложнее, чем кажется.(Я уже знаю, что couch требует, чтобы вы определили представления заранее, и поэтому я просто планировал вставить все пользовательские атрибуты в массив, а затем выдать массив в виде и продолжить оттуда обработку.)
Что я делаю: Прямо сейчас я просто отправляю каждую сделку на кушетке с ключом системы каждого пользователя и запрашиваю ключ системы, чтобы получить массив сделок для каждой системы.Просто.В настоящее время я не использую функцию уменьшения для вычисления какой-либо статистики, потому что я не мог понять, как получить все, что мне нужно, без ошибки уменьшения переполнения.
Вот пример строк, которые выводятся из кушетки:
{"total_rows":134,"offset":0,"rows":[
{"id":"5b1dcd47221e160d8721feee4ccc64be",
"key":["80e40ba2fa43589d57ec3f1d19db41e6","2010/05/14 04:32:37 +0000"], null,
"doc":{
"_id":"5b1dcd47221e160d8721feee4ccc64be",
"_rev":"1-bc9fe763e2637694df47d6f5efb58e5b",
"couchrest-type":"Trade",
"system":"80e40ba2fa43589d57ec3f1d19db41e6",
"pair":"EUR/USD",
"direction":"Buy",
"entry":12600,
"exit":12700,
"stop_loss":12500,
"profit_target":12700,
"status":"Closed",
"slug":"101332132375",
"custom_tracking": [{"name":"signal", "value":"Pin Bar"}]
"updated_at":"2010/05/14 04:32:37 +0000",
"created_at":"2010/05/14 04:32:37 +0000",
"result":100}}
]}
В моем контроллере rails 3 я просто заполняю массив сделок, такой как приведенный выше, и затем извлекаю соответствующие данные в меньшие массивы, по которым я могу вычислить мою статистику.
Вот мое действие показа для страницы, на которой я хочу отобразить статистику и все сделки:
def show
@trades = Trade.by_system(:startkey => [@system.id], :endkey => [@system.id, Time.now ])
@trades.each do |trade|
if trade.result > 0
@winning_trades << trade.result
elsif trade.result < 0
@losing_trades << trade.result
else
@breakeven_trades << trade.result
end
if trade.direction == "Buy"
@long_trades << trade.result
else
@short_trades << trade.result
end
if trade["custom_tracking"] != nil
@custom_tracking << {"result" => trade.result, "variables" => trade["custom_tracking"]}
end
end
end
Я опускаю некоторые другие происходящие вещи, но этосуть того, что я делаю.Затем я вычисляю материал в слое вида, чтобы получить некоторые результаты:
<% winning_long_trades = @long_trades.reject {|trade| trade <= 0 } %>
<% winning_short_trades = @short_trades.reject {|trade| trade <= 0 } %>
<ul>
<li>Total Trades: <%= @trades.count %></li>
<li>Winners: <%= @winning_trades.size %></li>
<li>Biggest Winner (Pips): <%= @winning_trades.max %></li>
<li>Average Win(Pips): <%= @winning_trades.sum/@winning_trades.size %></li>
<li>Losers: <%= @losing_trades.size %></li>
<li>Biggest Loser (Pips): <%= @losing_trades.min %></li>
<li>Average Loss(Pips): <%= @losing_trades.sum/@losing_trades.size %></li>
<li>Breakeven Trades: <%= @breakeven_trades.size %></li>
<li>Long Trades: <%= @long_trades.size %></li>
<li>Winning Long Trades: <%= winning_long_trades.size %></li>
<li>Short Trades: <%= @short_trades.size %></li>
<li>Winning Short Trades: <%= winning_short_trades.size %></li>
<li>Total Pips: <%= @winning_trades.sum + @losing_trades.sum %></li>
<li>Win Rate (%): <%= @winning_trades.size/@trades.count.to_f * 100 %></li>
</ul>
Это дает следующие результаты, которые, кроме нескольких вещей, именно то, что я хочу:
- Всего сделок: 134
- Победители: 70
- Крупнейший победитель (в пипсах): 1488
- Средний выигрыш (в пипсах): 440
- Проигравшие: 58
- Самый большой проигрыш (в пипсах): -516
- Средний убыток (в пипсах): -225
- Безубыточные сделки: 6
- Длинные сделки: 125
- Выигрышные длинные сделки: 67
- Короткие сделки: 9
- Выигрышные короткие сделки: 3
- Всего пипсов: 17819
- Процент выигрыша (%):52.23880597014925
Что я задаюсь вопросом - наконец-то актуальные вопросы: Я начинаю очень скептически относиться к тому, насколько хорошо этот метод будет работать, когда у пользователя 5000 сделок вместо всего лишь 134как в этом примере.Я предполагаю, что большинство пользователей будут иметь где-то менее 200 в год, но некоторые пользователи могут иметь пару тысяч сделок в год.Вероятно, не более 5000 в год.Кажется, сейчас работает нормально, но время загрузки страницы уже немного выше, на мой вкус.(Около 800 мс для генерации страницы в соответствии с журналами рельсов с примерно 250 мс, потраченными в слое представления.) Я уверен, что я буду кэшировать эту страницу, но я все еще буду нуждаться в регенерации страницы каждый раз, когда сделка обновляется иЯ не могу позволить, чтобы это было слишком медленным.Ооочень .....
- Возможно ли сделать что-то подобное здесь с помощью функции прямого преобразования couchdb?Я предполагаю, что передача этого на диван могла бы помочь с большими наборами данных.Я не мог понять, как, но я предполагаю, что это не значит, что это невозможно.Если возможно, любые подсказки будут полезны.
- Могу ли я использовать функцию списка, если сокращение не было доступно из-за ограничений ограничения? Подходят ли функции списка couchdb для расчетов такого типа? Кто-нибудь имеет представление о том, хорошо ли работают функции списка? Любые намеки на то, как бы выглядел тип вычислений, которые я пытаюсь достичь?
- Я подумал о других вариантах, таких как выполнение вычислений в момент сохранения каждой сделки или по ночам, если нужно, и сохранение результатов в статистическом документе, который я затем мог запросить, чтобы вся обработка была выполнена заранее. Я хотел бы, чтобы это было последним средством, потому что тогда я не могу действительно отфильтровать сделки по периодам времени динамически, как мне бы очень хотелось. (Мне нужен слайдер, который пользователь может перемещать, чтобы показывать сделки только с того периода времени, используя клавиши start и end в couchdb, если я могу.)
- Если я продолжу выполнять вычисления внутри приложения rails во время просмотра страницы, что я могу сделать, чтобы улучшить мою текущую реализацию. Я новичок в рельсах, кушетке и программировании в целом. Я уверен, что я мог бы сделать что-то лучше здесь. Нужно ли создавать массив для каждой статистики или есть лучший способ сделать это.
Полагаю, мне бы очень хотелось получить несколько советов о том, как решить эту проблему. Я хочу, чтобы время генерации страниц было минимальным, поскольку я ожидаю, что это одни из самых популярных страниц. Моя интуиция заключается в том, что мне нужно будет перенести расчет статистики на диван или запустить статистику заранее, когда они будут вызваны, но я не уверен.
И наконец: Как я уже упоминал выше, одна из основных причин использования кушетки состоит в том, чтобы позволить пользователям определять свои собственные вещи для отслеживания каждой сделки. Получить данные на диване не проблема, но как я могу взять массив custom_tracking и найти сколько выигрышных сделок для каждого именованного атрибута отслеживания? Если кто-нибудь может дать мне какие-либо намеки на возможность сделать это, это было бы здорово.
Спасибо большое. Буду очень признателен за любую помощь. Готов раскошелиться на $$$, если кто-то захочет взять на себя задачу за меня. (Не знаю, разрешено ли это при переполнении стека.)