finexclub 0.4.3 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +46 -1
- data/VERSION +1 -1
- data/finexclub.gemspec +2 -2
- data/lib/finexclub/app.rb +10 -4
- data/lib/finexclub/chart.rb +47 -15
- data/lib/finexclub/core.rb +17 -16
- data/lib/finexclub/document.rb +5 -0
- data/lib/finexclub/fabrication.rb +2 -1
- data/lib/finexclub/manager.rb +45 -18
- data/lib/finexclub.rb +3 -1
- data/spec/finexclub/app_spec.rb +106 -38
- data/spec/finexclub/chart_spec.rb +131 -37
- data/spec/finexclub/core_spec.rb +31 -31
- data/spec/finexclub/manager_spec.rb +205 -54
- data/spec/spec_helper.rb +7 -1
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -1,6 +1,51 @@
|
|
1
1
|
= finexclub
|
2
2
|
|
3
|
-
Nobody is really interested in this gem. Finexclub gem helps us to run http://trendsonforex.com and http://finexclub.net
|
3
|
+
Nobody is really interested in this gem. Finexclub gem helps us to run http://trendsonforex.com and http://finexclub.net.
|
4
|
+
|
5
|
+
Signals are saved into MongoDB according to the scheme:
|
6
|
+
|
7
|
+
chart:
|
8
|
+
symbol: 'eurusd' # Currency pair symbol, eg. 'eurusd', 'gbpusd', etc.
|
9
|
+
timeframe: 'h1' # Timeframe 'h1', 'h4', 'd1'
|
10
|
+
starts: 1293447600 # Timestamp when this timeframe slot starts, eg. Dec, 27 11:00:00
|
11
|
+
expires: 1293451200 # Timestamp when this timeframe slot is expired, eg. Dec, 27 12:00:00
|
12
|
+
updated: 1293447840 # UTC timestamp when this timeframe was last updated, eg. Dec, 27 11:04:00
|
13
|
+
indicators: # Latest data from indicators
|
14
|
+
|
15
|
+
alpha: # Alpha: trendline analysis
|
16
|
+
updated: 1293447840
|
17
|
+
index: 89 # Trend stability index 0..100
|
18
|
+
direction: 'up' # Trend direction 'up', 'down'
|
19
|
+
|
20
|
+
octopus: # Octopus: wave based analysis
|
21
|
+
updated: 1293447840
|
22
|
+
action: 'buy' # Order 'buy', 'sell', 'hold_buy', 'hold_sell', 'stop'
|
23
|
+
take_profit: 1.3350
|
24
|
+
profit: 90 # Possible profit in pips
|
25
|
+
stop_loss: 1.3250
|
26
|
+
loss: 60 # Possible loss in pips
|
27
|
+
index: 89 # Wave quality index 0..100; 0 - no wave matches found
|
28
|
+
screenshot: '...' # Path to S3 image
|
29
|
+
|
30
|
+
prognosis: # Prognosis: chaos theory based analysis
|
31
|
+
updated: 1293447840
|
32
|
+
action: 'hold_buy'
|
33
|
+
take_profit: 1.3350
|
34
|
+
profit: 90
|
35
|
+
stop_loss: 1.3250
|
36
|
+
loss: 60
|
37
|
+
acceleration: 'low' # 'high', 'low', 'undefined'
|
38
|
+
screenshot: '...'
|
39
|
+
|
40
|
+
zeta: # Zeta: support & resistance channels
|
41
|
+
updated: 1293447840
|
42
|
+
up_support: 1.3350 # 0 if no up-channel found
|
43
|
+
up_resist: 1.3250
|
44
|
+
down_support: 1.3250 # 0 if no down-channel found
|
45
|
+
down_resist: 1.3250
|
46
|
+
screenshot: '...'
|
47
|
+
|
48
|
+
To save a signal it looks for a valid (not expired) chart record in MongoDB that corresponds to the given symbol and timeframe. If chart has expired, it creates a new one with prolongated expiration date to accumulate incoming signals.
|
4
49
|
|
5
50
|
== Copyright
|
6
51
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.1
|
data/finexclub.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{finexclub}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex Levin"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-02-04}
|
13
13
|
s.default_executable = %q{finexclub_updater}
|
14
14
|
s.description = %q{Finexclub gem stores and retrieves Forex signals and screenshots. It is the heart of the http://trendsonforex.com and http://finexclub.net}
|
15
15
|
s.email = %q{clubfinex@gmail.com}
|
data/lib/finexclub/app.rb
CHANGED
@@ -19,10 +19,16 @@ module Finexclub
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
post "/:
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
post "/:indicator" do
|
23
|
+
indicator = params[:indicator].to_sym
|
24
|
+
indicator_data = params[indicator]
|
25
|
+
|
26
|
+
indicator_data = params[indicator].is_a?(Array) ? params[indicator] : [ params[indicator] ]
|
27
|
+
indicator_data.each do |s|
|
28
|
+
ap s.merge(:updated => Time.now.utc)
|
29
|
+
Finexclub.signals.add_signal(indicator, s, Time.now.utc)
|
30
|
+
end
|
31
|
+
|
26
32
|
status 200
|
27
33
|
end
|
28
34
|
end
|
data/lib/finexclub/chart.rb
CHANGED
@@ -4,35 +4,67 @@ module Finexclub
|
|
4
4
|
|
5
5
|
include Document
|
6
6
|
|
7
|
-
field :updated, :timestamp
|
8
7
|
field :symbol, :symbol
|
9
8
|
field :timeframe, :string
|
10
|
-
field :
|
9
|
+
field :starts, :timestamp
|
10
|
+
field :expires, :timestamp
|
11
|
+
field :updated, :timestamp
|
11
12
|
|
12
13
|
attr_reader :core
|
14
|
+
attr_accessor :indicators
|
15
|
+
|
16
|
+
doc_fields :symbol, :timeframe, :starts, :expires, :updated, :indicators
|
13
17
|
|
14
18
|
def initialize(core)
|
15
19
|
@core = core
|
16
|
-
@
|
20
|
+
@indicators = {}
|
17
21
|
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
def handler_for(indicator)
|
24
|
+
self.class.handler_for(indicator)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.build_new(core, symbol, tf, time)
|
28
|
+
time = time.is_a?(Time) ? time : Time.at(time).utc
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
c = Chart.new(core)
|
31
|
+
c.updated= time.to_i
|
32
|
+
c.symbol= symbol
|
33
|
+
c.timeframe = tf
|
34
|
+
c.starts = Time.utc(time.year, time.month, time.day, time.hour, 0).to_i
|
35
|
+
c.expires = c.starts + 1*60*60
|
36
|
+
c
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.indicator_handler(indicator, indicator_handler_class)
|
40
|
+
add_handler_for(indicator, indicator_handler_class)
|
41
|
+
|
42
|
+
#define_method("#{indicator}=") do |doc|
|
43
|
+
#@indicator_docs[indicator] = doc
|
44
|
+
#end
|
45
|
+
|
46
|
+
define_method("#{indicator}") do
|
47
|
+
return nil unless doc = indicators[indicator.to_s]
|
48
|
+
|
49
|
+
indicator_obj = handler_for(indicator.to_s).new(core)
|
50
|
+
indicator_obj.build(doc)
|
51
|
+
indicator_obj
|
27
52
|
end
|
28
53
|
end
|
29
54
|
|
30
|
-
def
|
31
|
-
@
|
55
|
+
def self.add_handler_for(indicator, klass)
|
56
|
+
@handlers ||= {}
|
57
|
+
@handlers[indicator.to_s] = klass
|
32
58
|
end
|
33
|
-
|
34
|
-
def
|
35
|
-
|
59
|
+
|
60
|
+
def self.handler_for(indicator)
|
61
|
+
@handlers ||= {}
|
62
|
+
@handlers[indicator.to_s]
|
36
63
|
end
|
64
|
+
|
65
|
+
indicator_handler :alpha, Finexclub::Signals::Alpha
|
66
|
+
indicator_handler :zeta, Finexclub::Signals::Zeta
|
67
|
+
indicator_handler :octopus, Finexclub::Signals::Octopus
|
68
|
+
indicator_handler :prognosis, Finexclub::Signals::Prognosis
|
37
69
|
end
|
38
70
|
end
|
data/lib/finexclub/core.rb
CHANGED
@@ -17,23 +17,24 @@ module Finexclub
|
|
17
17
|
self
|
18
18
|
end
|
19
19
|
|
20
|
-
def store(signal_type, params)
|
21
|
-
params = params.is_a?(Array) ? params : [params]
|
22
|
-
params.each do |s|
|
23
|
-
signals.add_signal(signal_type, s)
|
24
|
-
end
|
25
|
-
end
|
20
|
+
#def store(signal_type, params)
|
21
|
+
#params = params.is_a?(Array) ? params : [params]
|
22
|
+
#params.each do |s|
|
23
|
+
#signals.add_signal(signal_type, s)
|
24
|
+
#end
|
25
|
+
#end
|
26
|
+
|
27
|
+
#def find(symbol_or_array, date)
|
28
|
+
#case symbol_or_array
|
29
|
+
#when :all
|
30
|
+
#signals.find(:date => date)
|
31
|
+
#when Array
|
32
|
+
#signals.find(:date => date, :symbol => {:$in => symbol_or_array})
|
33
|
+
#when String
|
34
|
+
#signals.find_one(:date => date, :symbol => symbol_or_array)
|
35
|
+
#end
|
36
|
+
#end
|
26
37
|
|
27
|
-
def find(symbol_or_array, date)
|
28
|
-
case symbol_or_array
|
29
|
-
when :all
|
30
|
-
signals.find(:date => date)
|
31
|
-
when Array
|
32
|
-
signals.find(:date => date, :symbol => {:$in => symbol_or_array})
|
33
|
-
when String
|
34
|
-
signals.find_one(:date => date, :symbol => symbol_or_array)
|
35
|
-
end
|
36
|
-
end
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
data/lib/finexclub/document.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Finexclub
|
2
2
|
module Fabrication
|
3
3
|
def raw_alpha_hash(options = {})
|
4
|
-
{"symbol" => "EURUSD", "index"=>"2", "direction"=>"1"}.merge(options)
|
4
|
+
{"symbol" => "EURUSD", "timeframe" => 'h1', "index"=>"2", "direction"=>"1"}.merge(options)
|
5
5
|
end
|
6
6
|
|
7
7
|
def raw_zeta_hash(options={})
|
8
8
|
{
|
9
9
|
"symbol" => "EURUSD",
|
10
|
+
"timeframe" => "h1",
|
10
11
|
"up_support" => "1.124",
|
11
12
|
"up_resist" => "1.123",
|
12
13
|
"down_support" => "1.124",
|
data/lib/finexclub/manager.rb
CHANGED
@@ -12,34 +12,61 @@ module Finexclub
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def collection
|
15
|
-
raise("No db configured") if db.nil?
|
15
|
+
raise ConfigurationError.new("No db is configured") if db.nil?
|
16
16
|
db.collection('charts')
|
17
17
|
end
|
18
18
|
|
19
19
|
def find(query, opts = {})
|
20
|
-
Cursor.new(core, Chart, collection.find(query, opts))
|
20
|
+
Cursor.new(core, Finexclub::Chart, collection.find(query, opts))
|
21
21
|
end
|
22
22
|
|
23
|
-
def find_one(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
chart
|
23
|
+
def find_one(symbol, tf, time = nil)
|
24
|
+
time ||= Time.now.utc
|
25
|
+
time = time.respond_to?(:to_i) ? time.to_i : time
|
26
|
+
find({:symbol => symbol, :timeframe => tf, :starts => {:$lte => time}, :expires => {:$gt => time}}, :limit => 1, :sort => [[:expires, -1]]).first
|
28
27
|
end
|
29
28
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
29
|
+
def find_many(symbol_or_array, tf, time = nil)
|
30
|
+
time ||= Time.now.utc
|
31
|
+
time = time.respond_to?(:to_i) ? time.to_i : time
|
32
|
+
find({:symbol => {:$in => symbol_or_array}, :timeframe => tf, :starts => {:$lte => time}, :expires => {:$gt => time}}, :limit => 1, :sort => [[:expires, -1]])
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
def find_latest(symbol, tf)
|
36
|
+
find({:symbol => symbol, :timeframe => tf}, :sort => [[:expires, :desc]], :limit => 1).first
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_one_or_create(symbol, tf, time)
|
40
|
+
chart = find_one(symbol, tf, time)
|
41
|
+
return chart if chart
|
42
|
+
|
43
|
+
id = collection.insert(Chart.build_new(core, symbol, tf, time).to_doc)
|
44
|
+
find({"_id" => id}).first
|
45
|
+
end
|
46
|
+
|
47
|
+
def last_updated(tf)
|
48
|
+
doc = collection.find({:timeframe => tf}, :fields => {:updated => 1}, :sort => [[:updated, :desc]], :limit => 1).first
|
49
|
+
doc.nil?? nil : doc["updated"]
|
50
|
+
end
|
51
|
+
|
52
|
+
def last_updated_at(tf)
|
53
|
+
ts = last_updated(tf)
|
54
|
+
ts.nil? ? nil : Time.at(ts).utc
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_signal(indicator, params, time)
|
58
|
+
time = time.respond_to?(:to_i) ? time.to_i : time
|
59
|
+
|
60
|
+
signal = Signal.build(core, indicator, params.merge(:updated => time))
|
61
|
+
chart = find_one_or_create(signal.symbol, signal.timeframe, time)
|
62
|
+
|
63
|
+
c = if chart._id
|
64
|
+
{"_id" => chart._id}
|
65
|
+
else
|
66
|
+
chart.to_doc
|
67
|
+
end
|
68
|
+
|
69
|
+
collection.update(c, {"$set" => {:updated => signal.updated, "indicators.#{indicator}" => signal.to_doc}}, :upsert => true)
|
43
70
|
end
|
44
71
|
|
45
72
|
class Cursor
|
data/lib/finexclub.rb
CHANGED
@@ -33,9 +33,11 @@ autoload_files_in_dir("#{File.dirname(__FILE__)}/finexclub", 'Finexclub')
|
|
33
33
|
require 'forwardable'
|
34
34
|
|
35
35
|
module Finexclub
|
36
|
+
class ConfigurationError < StandardError; end
|
37
|
+
|
36
38
|
class << self
|
37
39
|
extend Forwardable
|
38
|
-
def_delegators :core, :
|
40
|
+
def_delegators :core, :configure
|
39
41
|
def_delegators :core, :images, :signals
|
40
42
|
|
41
43
|
def core
|
data/spec/finexclub/app_spec.rb
CHANGED
@@ -24,62 +24,130 @@ def make_request(url, opts = {})
|
|
24
24
|
last_response
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
describe 'Finexclub::App' do
|
28
|
+
before do
|
29
|
+
charts.drop
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
describe 'Alpha' do
|
33
|
+
before do
|
34
|
+
@params = {}
|
35
|
+
@params[:alpha] = []
|
36
|
+
|
37
|
+
Finexclub::Chart::SYMBOLS.each do |symbol|
|
38
|
+
@params[:alpha] << {
|
39
|
+
"symbol" => symbol.upcase,
|
40
|
+
"timeframe" => 'h1',
|
41
|
+
"direction" => 1,
|
42
|
+
"index" => 100
|
43
|
+
}
|
44
|
+
end
|
45
|
+
@params
|
46
|
+
end
|
37
47
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
it 'should save signal' do
|
49
|
+
response = nil
|
50
|
+
Timecop.travel(Time.utc(2010, 12, 27, 11, 5)) do
|
51
|
+
response = make_request('/alpha', @params)
|
52
|
+
end
|
53
|
+
response.status.should == 200
|
44
54
|
|
45
|
-
|
46
|
-
|
55
|
+
charts.find(:timeframe => 'h1').count.should == 28
|
56
|
+
c = charts.find_one(:symbol => 'eurusd')
|
57
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
58
|
+
c["indicators"]["alpha"].should.not.be.nil?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'Zeta' do
|
47
63
|
before do
|
48
|
-
|
64
|
+
@params = {}
|
65
|
+
@params[:zeta] = [{
|
66
|
+
"symbol" => "EURUSD",
|
67
|
+
"timeframe" => "h1",
|
68
|
+
"up_support" => "1.124",
|
69
|
+
"up_resist" => "1.123",
|
70
|
+
"down_support" => "2.124",
|
71
|
+
"down_resist" => "2.123",
|
72
|
+
"screenshot_filename" => "egg.png"
|
73
|
+
}]
|
49
74
|
end
|
50
75
|
|
51
|
-
it 'should
|
52
|
-
response =
|
76
|
+
it 'should save signal' do
|
77
|
+
response = nil
|
78
|
+
Timecop.travel(Time.utc(2010, 12, 27, 11, 5)) do
|
79
|
+
response = make_request('/zeta', @params)
|
80
|
+
end
|
53
81
|
response.status.should == 200
|
54
82
|
|
55
|
-
charts.find().count.should ==
|
56
|
-
charts.find_one(:
|
83
|
+
charts.find(:timeframe => 'h1').count.should == 1
|
84
|
+
c = charts.find_one(:symbol => 'eurusd')
|
85
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
86
|
+
c["indicators"]["zeta"].should.not.be.nil?
|
57
87
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'Octopus' do
|
91
|
+
before do
|
92
|
+
@params = {}
|
93
|
+
@params[:octopus] = [{
|
94
|
+
"symbol" => "EURUSD",
|
95
|
+
"timeframe" => "h1",
|
96
|
+
"action" => "buy",
|
97
|
+
"take_profit" => 1.123,
|
98
|
+
"profit" => 100,
|
99
|
+
"stop_loss" => 2.123,
|
100
|
+
"loss" => 50,
|
101
|
+
"index" => 100,
|
102
|
+
"tsi" => 90,
|
103
|
+
"trend" => 1,
|
104
|
+
"screenshot_filename" => "egg.png"
|
105
|
+
}]
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should save signal' do
|
109
|
+
response = nil
|
110
|
+
Timecop.travel(Time.utc(2010, 12, 27, 11, 5)) do
|
111
|
+
response = make_request('/octopus', @params)
|
112
|
+
end
|
62
113
|
response.status.should == 200
|
63
114
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
charts.find_one(:date => date, :symbol => 'eurusd')["alpha"].size.should == 2
|
115
|
+
charts.find(:timeframe => 'h1').count.should == 1
|
116
|
+
c = charts.find_one(:symbol => 'eurusd')
|
117
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
118
|
+
c["indicators"]["octopus"].should.not.be.nil?
|
69
119
|
end
|
70
120
|
end
|
71
|
-
|
72
|
-
describe '
|
121
|
+
|
122
|
+
describe 'Prognosis' do
|
73
123
|
before do
|
74
|
-
|
124
|
+
@params = {}
|
125
|
+
@params[:prognosis] = [{
|
126
|
+
"symbol" => "EURUSD",
|
127
|
+
"timeframe" => "h1",
|
128
|
+
"action" => "buy",
|
129
|
+
"acceleration" => "undefined",
|
130
|
+
"take_profit" => 1.123,
|
131
|
+
"profit" => 100,
|
132
|
+
"stop_loss" => 2.123,
|
133
|
+
"loss" => 50,
|
134
|
+
"tsi" => 90,
|
135
|
+
"trend" => 1,
|
136
|
+
"screenshot_filename" => "egg.png"
|
137
|
+
}]
|
75
138
|
end
|
76
139
|
|
77
|
-
it 'should
|
78
|
-
response =
|
140
|
+
it 'should save signal' do
|
141
|
+
response = nil
|
142
|
+
Timecop.travel(Time.utc(2010, 12, 27, 11, 5)) do
|
143
|
+
response = make_request('/prognosis', @params)
|
144
|
+
end
|
79
145
|
response.status.should == 200
|
80
146
|
|
81
|
-
charts.find().count.should == 1
|
82
|
-
charts.find_one(:
|
147
|
+
charts.find(:timeframe => 'h1').count.should == 1
|
148
|
+
c = charts.find_one(:symbol => 'eurusd')
|
149
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
150
|
+
c["indicators"]["prognosis"].should.not.be.nil?
|
83
151
|
end
|
84
152
|
end
|
85
153
|
|
@@ -2,59 +2,153 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
3
3
|
describe 'Finexclub::Chart' do
|
4
4
|
before do
|
5
|
-
@core =
|
5
|
+
@core = test_core
|
6
6
|
@chart = Finexclub::Chart.new(@core)
|
7
|
+
|
8
|
+
Finexclub.signals.collection.drop
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'indicators handling' do
|
12
|
+
before do
|
13
|
+
class Omega < Finexclub::Signal
|
14
|
+
field :symbol, :symbol
|
15
|
+
field :timeframe, :string
|
16
|
+
field :updated, :timestamp
|
17
|
+
field :foo, :string
|
18
|
+
|
19
|
+
doc_fields :foo, :updated
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'Chart#indicator_handler(:omega, Omega)' do
|
24
|
+
before do
|
25
|
+
Finexclub::Chart.indicator_handler(:omega, Omega)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should return valid class as indicator handler' do
|
29
|
+
Finexclub::Chart.handler_for(:omega).should == Omega
|
30
|
+
@chart.handler_for(:omega) == Omega
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#omega signal accessor' do
|
34
|
+
before do
|
35
|
+
@omega_doc = {:symbol => 'usdjpy', :timeframe => 'h1', :foo => "Ololo!"}
|
36
|
+
Finexclub.signals.add_signal(:omega, @omega_doc, Time.utc(2010, 12, 27, 11, 5))
|
37
|
+
@chart = Finexclub.signals.find_one('usdjpy', 'h1', Time.utc(2010, 12, 27, 11, 10))
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return valid Omega object' do
|
41
|
+
@chart.should.respond_to?(:omega)
|
42
|
+
@chart.omega.should.not == nil
|
43
|
+
@chart.omega.class.should == Omega
|
44
|
+
|
45
|
+
@chart.omega.foo.should == "Ololo!"
|
46
|
+
@chart.omega.updated.should == Time.utc(2010, 12, 27, 11, 5).to_i
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should return nil if no indicator doc is available' do
|
50
|
+
@chart.alpha.should == nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#it 'should add #omega=(Signal) accessor to save raw document' do
|
55
|
+
#omega_doc = {:foo => "Ololo!", :updated => Time.now.utc.to_i}
|
56
|
+
#@chart.omega =
|
57
|
+
#@chart.indicators[:omega].should == omega_doc
|
58
|
+
#end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'complex chart with default indicators' do
|
62
|
+
before do
|
63
|
+
Finexclub.signals.add_signal(:alpha, {:symbol => 'eurusd', :timeframe => 'h1'}, Time.now.utc)
|
64
|
+
Finexclub.signals.add_signal(:zeta, {:symbol => 'eurusd', :timeframe => 'h1'}, Time.now.utc)
|
65
|
+
Finexclub.signals.add_signal(:octopus, {:symbol => 'eurusd', :timeframe => 'h1'}, Time.now.utc)
|
66
|
+
Finexclub.signals.add_signal(:prognosis, {:symbol => 'eurusd', :timeframe => 'h1'}, Time.now.utc)
|
67
|
+
end
|
68
|
+
|
69
|
+
{
|
70
|
+
:alpha => Finexclub::Signals::Alpha,
|
71
|
+
:zeta => Finexclub::Signals::Zeta,
|
72
|
+
:octopus => Finexclub::Signals::Octopus,
|
73
|
+
:prognosis => Finexclub::Signals::Prognosis
|
74
|
+
}.each do |indicator, klass|
|
75
|
+
it "should have :#{indicator} handler as #{klass}" do
|
76
|
+
Finexclub::Chart.handler_for(indicator).should == klass
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should access chart.#{indicator}" do
|
80
|
+
chart = Finexclub.signals.find_one('eurusd', 'h1')
|
81
|
+
chart.send(indicator).class.should == klass
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'Chart.build_signal(indicator, params)' do
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'Chart.build_new(symbol, tf, time)' do
|
91
|
+
before do
|
92
|
+
@chart = Finexclub::Chart.build_new(@core, 'eurusd', 'h1', Time.utc(2010, 12, 27, 11, 30).to_i)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should return valid new (unsaved) chart instance' do
|
96
|
+
@chart._id.should == nil
|
97
|
+
@chart.symbol.should == 'eurusd'
|
98
|
+
@chart.timeframe.should == 'h1'
|
99
|
+
@chart.starts.should == Time.utc(2010, 12, 27, 11, 0).to_i
|
100
|
+
@chart.expires.should == Time.utc(2010, 12, 27, 12, 0).to_i
|
101
|
+
@chart.updated.should == Time.utc(2010, 12, 27, 11, 30).to_i
|
102
|
+
@chart.indicators.should == {}
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should build valid chart given time as Time object' do
|
106
|
+
Finexclub::Chart.build_new(@core, 'eurusd', 'h1', Time.utc(2010, 12, 27, 11, 30)).starts.should == Time.utc(2010, 12, 27, 11, 0).to_i
|
107
|
+
end
|
108
|
+
|
7
109
|
end
|
110
|
+
|
8
111
|
|
9
|
-
describe '
|
112
|
+
describe 'instance' do
|
10
113
|
before do
|
11
114
|
@a1, @a2 = mock('a1'), mock('a2')
|
12
|
-
@z1
|
13
|
-
@ts = Time.now.to_i
|
115
|
+
@z1 = mock('z1')
|
14
116
|
|
15
|
-
chart_doc = {
|
117
|
+
@chart_doc = {
|
16
118
|
:symbol => 'eurusd',
|
17
|
-
:date => '2010-09-08',
|
18
119
|
:timeframe => 'h1',
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
120
|
+
:starts => Time.utc(2010, 12, 27, 11, 0).to_i,
|
121
|
+
:expires => Time.utc(2010, 12, 27, 12, 0).to_i,
|
122
|
+
:updated => Time.utc(2010, 12, 27, 11, 5).to_i,
|
123
|
+
:indicators => {
|
124
|
+
:alpha => @a1,
|
125
|
+
:zeta => @z1
|
126
|
+
}
|
22
127
|
}
|
23
|
-
@chart.build(chart_doc)
|
24
|
-
end
|
25
128
|
|
26
|
-
|
27
|
-
@chart.symbol.should == 'eurusd'
|
28
|
-
@chart.timeframe.should == 'h1'
|
29
|
-
@chart.date.should == '2010-09-08'
|
30
|
-
@chart.updated.should == @ts
|
129
|
+
@chart.build(@chart_doc)
|
31
130
|
end
|
32
|
-
end
|
33
131
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
:prognosis
|
39
|
-
].each do |indicator|
|
40
|
-
describe "#{indicator} signals" do
|
41
|
-
before do
|
42
|
-
@s1, @s2 = mock("signal_#{indicator}_1"), mock("signal_#{indicator}_2")
|
43
|
-
@chart.build(indicator => [@s1, @s2])
|
44
|
-
end
|
132
|
+
it 'should provide access to raw indicator documents' do
|
133
|
+
@chart.indicators[:alpha].should == @a1
|
134
|
+
@chart.indicators[:zeta].should == @z1
|
135
|
+
end
|
45
136
|
|
46
|
-
|
47
|
-
|
48
|
-
|
137
|
+
it 'should update raw indicator document' do
|
138
|
+
@chart.indicators[:alpha] = @a2
|
139
|
+
@chart.indicators[:alpha].should == @a2
|
140
|
+
end
|
49
141
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
142
|
+
it 'should provide common accessors' do
|
143
|
+
@chart.symbol.should == 'eurusd'
|
144
|
+
@chart.timeframe.should == 'h1'
|
145
|
+
@chart.updated.should == @chart_doc[:updated]
|
146
|
+
@chart.starts.should == @chart_doc[:starts]
|
147
|
+
@chart.expires.should == @chart_doc[:expires]
|
54
148
|
end
|
55
149
|
|
56
|
-
it
|
57
|
-
@chart.
|
150
|
+
it 'should export valid document' do
|
151
|
+
@chart.to_doc.should == @chart_doc
|
58
152
|
end
|
59
153
|
end
|
60
154
|
|
data/spec/finexclub/core_spec.rb
CHANGED
@@ -59,41 +59,41 @@ describe 'Finexclub::Core' do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
describe '#find' do
|
63
|
-
before do
|
64
|
-
|
65
|
-
end
|
62
|
+
#describe '#find' do
|
63
|
+
#before do
|
64
|
+
#@core = test_core
|
65
|
+
#end
|
66
66
|
|
67
|
-
it 'should fetch all charts for given date' do
|
68
|
-
|
69
|
-
|
70
|
-
end
|
67
|
+
#it 'should fetch all charts for given date' do
|
68
|
+
#@core.signals.should.receive(:find).with({:date => "2010-10-01"}).and_return(c = mock('cursor'))
|
69
|
+
#@core.find(:all, "2010-10-01").should == c
|
70
|
+
#end
|
71
71
|
|
72
|
-
it 'should fetch an array of charts for given date' do
|
73
|
-
|
74
|
-
|
75
|
-
end
|
72
|
+
#it 'should fetch an array of charts for given date' do
|
73
|
+
#@core.signals.should.receive(:find).with({:symbol => {:$in => ["eurusd", "usdjpy"]}, :date => "2010-10-01"}).and_return(c = mock('cursor'))
|
74
|
+
#@core.find(["eurusd", "usdjpy"], "2010-10-01").should == c
|
75
|
+
#end
|
76
76
|
|
77
|
-
it 'should allow fetching signals by date and symbol' do
|
78
|
-
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
77
|
+
#it 'should allow fetching signals by date and symbol' do
|
78
|
+
#@core.signals.should.receive(:find_one).with({:date => "2010-10-01", :symbol => "eurusd"}).and_return(chart = mock('chart'))
|
79
|
+
#@core.find("eurusd", "2010-10-01").should == chart
|
80
|
+
#end
|
81
|
+
#end
|
82
82
|
|
83
|
-
describe '#store' do
|
84
|
-
before do
|
85
|
-
|
86
|
-
end
|
87
|
-
it 'should store each signal given an array of params' do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
it 'should store signal given signle hash of params' do
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
83
|
+
#describe '#store' do
|
84
|
+
#before do
|
85
|
+
#@core = test_core
|
86
|
+
#end
|
87
|
+
#it 'should store each signal given an array of params' do
|
88
|
+
#@core.signals.should.receive(:add_signal).with(:alpha,p1=mock('p1'))
|
89
|
+
#@core.signals.should.receive(:add_signal).with(:alpha,p2=mock('p2'))
|
90
|
+
#@core.store(:alpha, [p1, p2])
|
91
|
+
#end
|
92
|
+
#it 'should store signal given signle hash of params' do
|
93
|
+
#@core.signals.should.receive(:add_signal).with(:alpha,p1=mock('p1'))
|
94
|
+
#@core.store(:alpha, p1)
|
95
|
+
#end
|
96
|
+
#end
|
97
97
|
|
98
98
|
end
|
99
99
|
|
@@ -4,59 +4,161 @@ describe 'Finexclub::Manager' do
|
|
4
4
|
before do
|
5
5
|
@core = mock_core
|
6
6
|
@manager = Finexclub::Manager.new(@core)
|
7
|
-
@manager.db = mock_mongo
|
8
|
-
end
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
it 'should provide mongo instance' do
|
16
|
-
@manager.db.should == @mongo
|
17
|
-
end
|
18
|
-
it 'should have collection accessor' do
|
19
|
-
@mongo.stub!(:collection).and_return(coll = mock('coll'))
|
20
|
-
@manager.collection.should == coll
|
21
|
-
end
|
8
|
+
@mongo = test_mongo
|
9
|
+
@manager.db = @mongo
|
10
|
+
|
11
|
+
@mongo.collection("charts").drop
|
22
12
|
end
|
23
13
|
|
24
|
-
describe '.
|
25
|
-
it 'should
|
26
|
-
@manager.
|
27
|
-
@manager.find(:date => "2010-10-01")
|
14
|
+
describe '.db' do
|
15
|
+
it 'should return mongo instance' do
|
16
|
+
@manager.db.should == @mongo
|
28
17
|
end
|
29
18
|
end
|
30
19
|
|
31
|
-
describe '.
|
32
|
-
it 'should
|
33
|
-
@manager.
|
34
|
-
|
20
|
+
describe '.collection' do
|
21
|
+
it 'should raise if no db is configured' do
|
22
|
+
@manager.db = nil
|
23
|
+
should.raise(Finexclub::ConfigurationError) { @manager.collection }
|
35
24
|
end
|
36
25
|
|
37
|
-
it 'should return
|
38
|
-
@manager.collection.
|
39
|
-
@manager.
|
26
|
+
it 'should return charts collection' do
|
27
|
+
@manager.collection.is_a?(Mongo::Collection).should.be.true
|
28
|
+
@manager.collection.name.should == "charts"
|
40
29
|
end
|
41
30
|
end
|
42
31
|
|
43
|
-
describe '
|
32
|
+
describe 'finding charts' do
|
44
33
|
before do
|
45
|
-
|
34
|
+
charts = @mongo.collection('charts')
|
35
|
+
charts.drop
|
36
|
+
@c1 = {:symbol => 'eurusd', :timeframe => 'h1', :starts => Time.utc(2010, 12, 27, 11, 0).to_i, :expires => Time.utc(2010, 12, 27, 12, 0).to_i, :updated => Time.utc(2010, 12, 27, 11, 3).to_i}
|
37
|
+
@c2 = {:symbol => 'eurusd', :timeframe => 'h1', :starts => Time.utc(2010, 12, 27, 12, 0).to_i, :expires => Time.utc(2010, 12, 27, 13, 0).to_i, :updated => Time.utc(2010, 12, 27, 12, 5).to_i}
|
38
|
+
@c3 = {:symbol => 'usdjpy', :timeframe => 'h1', :starts => Time.utc(2010, 12, 27, 12, 0).to_i, :expires => Time.utc(2010, 12, 27, 13, 0).to_i, :updated => Time.utc(2010, 12, 27, 12, 30).to_i}
|
39
|
+
@c4 = {:symbol => 'usdjpy', :timeframe => 'h1', :starts => Time.utc(2010, 12, 27, 13, 0).to_i, :expires => Time.utc(2010, 12, 27, 14, 0).to_i, :updated => Time.utc(2010, 12, 27, 13, 30).to_i}
|
40
|
+
|
41
|
+
@id1 = charts.insert(@c1)
|
42
|
+
@id2 = charts.insert(@c2)
|
43
|
+
@id3 = charts.insert(@c3)
|
44
|
+
@id4 = charts.insert(@c4)
|
46
45
|
end
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
describe 'generalized .find()' do
|
48
|
+
#it 'should pass given query and options to collection#find' do
|
49
|
+
#@mongo.collection.should.receive(:find).with({:symbol => 'eurusd'}, {})
|
50
|
+
#@manager.find({:symbol => 'eurusd'})
|
51
|
+
#end
|
52
|
+
|
53
|
+
it 'should return Cursor object' do
|
54
|
+
cursor = lambda {|obj| obj.is_a? Finexclub::Manager::Cursor}
|
55
|
+
@manager.find(:symbol => 'eurusd').should.be.a cursor
|
56
|
+
end
|
51
57
|
end
|
52
58
|
|
53
|
-
|
54
|
-
|
55
|
-
|
59
|
+
describe 'find single chart' do
|
60
|
+
describe '.find_one(symbol, tf, time)' do
|
61
|
+
it 'should find a chart given time as Time' do
|
62
|
+
c = @manager.find_one('eurusd', 'h1', Time.utc(2010, 12, 27, 11, 30))
|
63
|
+
c._id.should == @id1
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should find a chart given symbol, timeframe and time' do
|
67
|
+
c = @manager.find_one('eurusd', 'h1', Time.utc(2010, 12, 27, 11, 30).to_i)
|
68
|
+
c._id.should == @id1
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should find a chart at present moment (Time.now) by default ' do
|
72
|
+
Timecop.travel(Time.utc(2010, 12, 27, 11, 30))
|
73
|
+
c = @manager.find_one('eurusd', 'h1')
|
74
|
+
Timecop.return
|
75
|
+
|
76
|
+
c._id.should == @id1
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return nil given time greather then the last available chart' do
|
80
|
+
@manager.find_one('eurusd', 'h1', Time.utc(2010, 12, 27, 13, 30).to_i).should == nil
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return nil if nothing found for given timeframe' do
|
84
|
+
@manager.find_one('eurusd', 'h4').should == nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should return nil if nothing found for given symbol' do
|
88
|
+
@manager.find_one('usdcad', 'h1').should == nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '.find_one_or_create(symbol, tf, time)' do
|
93
|
+
it 'should return existing chart for given symbol, timeframe and time' do
|
94
|
+
c = @manager.find_one_or_create('eurusd', 'h1', Time.utc(2010, 12, 27, 11, 30))
|
95
|
+
c._id.should == @id1
|
96
|
+
end
|
97
|
+
|
98
|
+
#it 'should build valid chart if no chart exists' do
|
99
|
+
#Finexclub::Chart.should.receive(:build_new).with(@core, 'eurusd', 'h1', Time.utc(2010, 12, 27, 13, 5)).and_return(c = mock('chart'))
|
100
|
+
#@manager.find_one_or_create('eurusd', 'h1', Time.utc(2010, 12, 27, 13, 5)).should == c
|
101
|
+
#end
|
102
|
+
|
103
|
+
it 'should create a new chart if no chart exists' do
|
104
|
+
c = @manager.find_one_or_create('eurusd', 'h1', Time.utc(2010, 12, 27, 13, 5))
|
105
|
+
c._id.should.not.be.nil?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '.find_latest(symbol, tf)' do
|
110
|
+
it 'should find the latest chart by symbol and timeframe' do
|
111
|
+
c = @manager.find_latest('eurusd', 'h1')
|
112
|
+
c._id.should == @id2
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should return nil if nothing found for given timeframe' do
|
116
|
+
@manager.find_latest('eurusd', 'h4').should == nil
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should return nil if nothing found for given symbol' do
|
120
|
+
@manager.find_latest('usdcad', 'h1').should == nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '.last_updated(tf)' do
|
125
|
+
it 'should return timestamp of the latest update through out all symbols for given timeframe' do
|
126
|
+
# it should be @c4, which is usdjpy:h1
|
127
|
+
@manager.last_updated('h1').should == @c4[:updated]
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should return nil if no charts found' do
|
131
|
+
@manager.last_updated('h4').should == nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '.last_updated_at(tf)' do
|
136
|
+
it 'should return Time of the latest collection update' do
|
137
|
+
@manager.last_updated_at('h1').is_a? Time
|
138
|
+
@manager.last_updated_at('h1').should == Time.at(@c4[:updated]).utc
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should return nil if no charts found' do
|
142
|
+
@manager.last_updated_at('h4').should == nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe 'find many charts' do
|
148
|
+
describe '.find_many(symbol_or_arr, tf_or_arr, time)' do
|
149
|
+
it 'should find charts given time as Time' do
|
150
|
+
#cur = @manager.find_many(['eurusd', 'usdcad'], 'h1', Time.utc(2010, 12, 27, 12, 40))
|
151
|
+
#cur.count.should == 2
|
152
|
+
#[ cur[0]._id, cur[1]._id ].should.be.same_as [@id2, @id3]
|
153
|
+
should.flunk
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
56
157
|
end
|
158
|
+
|
57
159
|
end
|
58
160
|
|
59
|
-
describe '
|
161
|
+
describe 'saving signals' do
|
60
162
|
before do
|
61
163
|
class Omega < Finexclub::Signal
|
62
164
|
field :symbol, :symbol
|
@@ -66,28 +168,77 @@ describe 'Finexclub::Manager' do
|
|
66
168
|
|
67
169
|
doc_fields :foo, :updated
|
68
170
|
end
|
171
|
+
Finexclub::Chart.indicator_handler(:omega, Omega)
|
172
|
+
|
173
|
+
charts = @mongo.collection('charts')
|
174
|
+
charts.drop
|
175
|
+
@c1 = {
|
176
|
+
:symbol => 'eurusd',
|
177
|
+
:timeframe => 'h1',
|
178
|
+
:starts => Time.utc(2010, 12, 27, 11, 0).to_i,
|
179
|
+
:expires => Time.utc(2010, 12, 27, 12, 0).to_i,
|
180
|
+
:updated => nil,
|
181
|
+
:indicators => {}
|
182
|
+
}
|
183
|
+
@c2 = {
|
184
|
+
:symbol => 'usdcad',
|
185
|
+
:timeframe => 'h1',
|
186
|
+
:starts => Time.utc(2010, 12, 27, 11, 0).to_i,
|
187
|
+
:expires => Time.utc(2010, 12, 27, 12, 0).to_i,
|
188
|
+
:updated => Time.utc(2010, 12, 27, 11, 3).to_i,
|
189
|
+
:indicators => {
|
190
|
+
:omega => {:foo => "bar", :updated => Time.utc(2010, 12, 27, 11, 3).to_i}
|
191
|
+
}
|
192
|
+
}
|
193
|
+
@id1 = charts.insert(@c1)
|
194
|
+
@id2 = charts.insert(@c2)
|
69
195
|
end
|
70
196
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
"
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
197
|
+
describe '.add_signal(indicator, raw_params, time)' do
|
198
|
+
it 'should add signal to existing chart' do
|
199
|
+
@manager.add_signal(:omega, {"symbol" => "EURUSD", "timeframe" => "h1", "foo" => "bar"}, Time.utc(2010, 12, 27, 11, 5))
|
200
|
+
|
201
|
+
c = @manager.collection.find_one({"_id" => @id1})
|
202
|
+
c["symbol"].should == 'eurusd'
|
203
|
+
c["timeframe"].should == 'h1'
|
204
|
+
c["starts"].should == Time.utc(2010, 12, 27, 11, 0).to_i
|
205
|
+
c["expires"].should == Time.utc(2010, 12, 27, 12, 0).to_i
|
206
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
207
|
+
c["indicators"]["omega"].should == {
|
208
|
+
"foo" => "bar",
|
209
|
+
"updated" => Time.utc(2010, 12, 27, 11, 5).to_i
|
210
|
+
}
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'should update existing signal on existing chart' do
|
214
|
+
@manager.add_signal(:omega, {"symbol" => "USDCAD", "timeframe" => "h1", "foo" => "ololo!"}, Time.utc(2010, 12, 27, 11, 30))
|
215
|
+
|
216
|
+
c = @manager.collection.find_one({"_id" => @id2})
|
217
|
+
c["symbol"].should == 'usdcad'
|
218
|
+
c["timeframe"].should == 'h1'
|
219
|
+
c["starts"].should == Time.utc(2010, 12, 27, 11, 0).to_i
|
220
|
+
c["expires"].should == Time.utc(2010, 12, 27, 12, 0).to_i
|
221
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 30).to_i
|
222
|
+
c["indicators"]["omega"].should == {
|
223
|
+
"foo" => "ololo!",
|
224
|
+
"updated" => Time.utc(2010, 12, 27, 11, 30).to_i
|
225
|
+
}
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should add signals to non-existent chart' do
|
229
|
+
@manager.add_signal(:omega, {"symbol" => "EURUSD", "timeframe" => "h4", "foo" => "bar"}, Time.utc(2010, 12, 27, 11, 5))
|
230
|
+
|
231
|
+
c = @manager.collection.find_one({:symbol => 'eurusd', :timeframe => 'h4'})
|
232
|
+
c["symbol"].should == 'eurusd'
|
233
|
+
c["timeframe"].should == 'h4'
|
234
|
+
c["starts"].should == Time.utc(2010, 12, 27, 11, 0).to_i
|
235
|
+
c["expires"].should == Time.utc(2010, 12, 27, 12, 0).to_i
|
236
|
+
c["updated"].should == Time.utc(2010, 12, 27, 11, 5).to_i
|
237
|
+
c["indicators"]["omega"].should == {
|
238
|
+
"foo" => "bar",
|
239
|
+
"updated" => Time.utc(2010, 12, 27, 11, 5).to_i
|
240
|
+
}
|
241
|
+
end
|
91
242
|
end
|
92
243
|
end
|
93
244
|
|
data/spec/spec_helper.rb
CHANGED
@@ -25,9 +25,15 @@ class Bacon::Context
|
|
25
25
|
}.merge(extra_stubs)
|
26
26
|
)
|
27
27
|
end
|
28
|
+
|
29
|
+
def test_mongo
|
30
|
+
Mongo::Connection.new().db('finexclub_test')
|
31
|
+
end
|
28
32
|
|
29
33
|
def test_core
|
30
|
-
Finexclub::Core.send(:new)
|
34
|
+
core = Finexclub::Core.send(:new)
|
35
|
+
Finexclub.signals.db = test_mongo
|
36
|
+
core
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 5
|
8
|
+
- 1
|
9
|
+
version: 0.5.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alex Levin
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-02-04 00:00:00 +07:00
|
18
18
|
default_executable: finexclub_updater
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|