2010-05-15 61 views
2

我的問題:我想爲貨幣交易者開發一個web應用程序。該應用程序允許交易者輸入或上傳有關其交易的信息,並且我想根據用戶輸入的內容計算各種統計數據。我應該如何爲CouchDB/Rails3應用程序生成貿易統計信息?

現在,通常我會爲此使用關係數據庫,但是我有兩個要求不適合關係數據庫,所以我嘗試使用couchdb。這兩個問題是:1)首先,我有一個伴侶桌面應用程序,用戶可以使用couchdb的真棒複製功能來使用並複製到該網站; 2)我希望允許用戶定義他們自己的自定義跟蹤交易的事情,並根據他們輸入的內容產生結果。沙發模式的本質在這裏看起來很完美,但最終可能比聽起來更難。 (我已經知道了沙發上,需要你提前和這樣的,所以我只是在堅持所有的自定義計劃在一個數組的屬性,然後發射從那裏查看和進一步處理數組定義視圖)。

我Am Doing:現在,我只是發出每個用戶系統鍵入的每筆交易,並使用系統的關鍵字查詢每個系統的交易數據。簡單。我目前沒有使用reduce函數來計算任何統計信息,因爲我無法弄清楚如何獲得我需要的所有信息而不會發生減少溢出錯誤。

下面是都可以從沙發上發射的行的一個示例:

{"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}} 
]} 

以我導軌3控制器我基本上只是填充交易的一個陣列,例如一個以上,然後提取出的相關數據到更小的數組中,我可以計算我的統計數據。

這裏是我的,我要顯示的統計數據,所有的交易頁面show動作:

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

我是什麼Wondering-最後是實際的問題:我開始變得很懷疑有多好這個方法將工作,當用戶有5000周的交易,而不是僅僅134就像這個例子。我預計大部分用戶每年只有200個以下的用戶,但一些用戶每年可能會有幾千筆交易。可能每年不超過5000次。它現在似乎可以正常工作,但頁面加載時間對我的口味來說已經很高了。 (根據rails日誌生成頁面的時間大約爲800ms,視圖層花費的時間大約爲250ms)。我肯定會緩存這個頁面,但我仍然需要在每次交易更新時重新生成頁面,並且我承受不了這太慢。 Sooo .....

  1. 在這裏做類似的事情可能與直couchdb reduce函數?我假設把它交給沙發可能會幫助更大的數據集。我無法弄清楚,但我想這並不意味着這是不可能的。如果可能的話,任何提示都會有幫助。
  2. 如果由於減少約束而導致減少不可用,我可以使用列表函數嗎? couchdb列表函數是否適合這種類型的計算?任何人都知道列表函數是否表現良好?任何提示我想要達到什麼樣的計算類型?
  3. 我想過其他選項,例如在每筆交易保存時或每晚都要運行計算,如果必須將結果保存到統計文檔,然後我可以查詢以便所有處理都提前完成。我希望這是最後的手段,因爲那樣我不能真正按照我真正喜歡的時間週期動態地過濾掉交易。 (我想有一個滑塊,用戶可以滑動到僅顯示那段時間內使用startchkey和endkey在couchdb中的交易,如果可以的話)。
  4. 如果我應該繼續在rails應用程序中運行時間頁面視圖,我能做些什麼來改進我目前的實現。我對軌道,沙發和一般編程都很陌生。我相信我可以在這裏做更好的事情。我是否需要爲每個屬性創建一個數組,或者有更好的方法來做到這一點。

我想我真的很想就如何解決這個問題提出一些建議。我希望儘可能減少頁面生成時間,因爲我預計這些頁面會成爲最高流量的頁面。我的直覺是,我需要將統計計算卸載到沙發上,或者在被調用之前運行統計數據,但我不確定。

最後:就像我上面提到的,使用沙發的主要原因之一是允許用戶定義他們自己的東西來跟蹤每筆交易。將數據存入沙發並不成問題,但我如何能夠使用custom_tracking數組並找出每個指定的跟蹤屬性有多少次獲勝交易。如果任何人都可以給我任何暗示這樣做的可能性會很大。

謝謝你一堆。非常感謝任何幫助。如果有人想爲我解決問題,願意分出一些$$$。 (不知道堆棧溢出是否允許。)

回答

1

首先,如果你想提供所有(由用戶)執行的交易的統計數據,那麼是的,減少視圖可以是真棒。由於減少的結果實際上存儲在視圖索引中的磁盤上,因此應該能夠大幅加快視圖的速度。

其次,CouchDB中的默認reduce_limit只是爲了限制。如果你知道你在做什麼,你應該禁用它並讓你的reduce函數返回更多的信息。(值得注意的是,我認爲這就是你正在運行的內容,默認的reduce_limit對返回的JSON結構有一個固定的大小限制;但是,如果返回的結構的大小在處理的行數上大致不變,那麼實際的大小並不是真正的問題 - 儘管它可能不會很大)。

我不認爲使用列表函數會對這裏有所幫助,但我對這些沒有多少經驗。

如果你願意,我可以幫你進一步賺錢,或者你可以在freenode上#couchdb停下來問一些問題。那裏通常有一個相當有知識的人羣。

相關問題