finexclub 0.4.3 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|