tulirb 0.1.0 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71894a41382e1a2d581cd40f46e5cae0fa5b3d16f496f86b38ced085d94532bc
4
- data.tar.gz: b59d5863188a36eb43bc184289778bb207d1982ea03eacf3a591d09b8319aeb8
3
+ metadata.gz: 439ab7a08e2ecbe74674156913a01255c008e7e4768821dae21f4ccef2db95a5
4
+ data.tar.gz: 20df5ea27a9ef2c6a16aae50688b2fab30b3f4c6327ef0213b188642483b1249
5
5
  SHA512:
6
- metadata.gz: ff097d9c769fd60037af18e055e523f8f1e703f3649a43589390ccc178dd7934e699515baeefb7920b6b10299a025c115677786260540e67ccca2dc5b39aeb8e
7
- data.tar.gz: df0d53ecd8603a89cf0b355ab5ab39bae71ebfd79c9ab4e395ac7ad23f2bbe16debac1f46c20a8ad219224bf1871d5b596cb6a0e1fe446f5d9c0779a31404dad
6
+ metadata.gz: '059b4963c53683830ac7c169596ee001e11bab1c8ebf4ec6cd95d95d92bfdc22c7b5f5647b4698d9b2528c381d5089c52ede0084a97e53d7370508416c620284'
7
+ data.tar.gz: 0edb7138cc91a916ed717aed369115140041491b53a22fc2f2967439cace19bc58771a55b6a91b252c0a8f888d6ba1063b0a7c7145d5ee3e866b8f94c3aaa399
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
- TargetRubyVersion: 2.6
3
+ TargetRubyVersion: 2.7
4
4
  Exclude:
5
5
  - ext/tulirb/extconf.rb
6
6
  - Gemfile.lock
@@ -16,6 +16,13 @@ Style/StringLiteralsInInterpolation:
16
16
  EnforcedStyle: double_quotes
17
17
  Style/Documentation:
18
18
  Enabled: false
19
+ Metrics/ModuleLength:
20
+ Enabled: false
21
+ Metrics/ClassLength:
22
+ Enabled: false
23
+ Metrics/MethodLength:
24
+ CountAsOne: ['array', 'heredoc', 'method_call']
25
+ Max: 30
19
26
 
20
27
 
21
28
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
- ## [Unreleased]
1
+ # Tulirb Changelog
2
+
3
+ ## [1.0.0] - 2025-02-24
4
+
5
+ - Fix all compiler warnings in C extension and ensure there are no memory leaks.
6
+ - [internal] Added AddressSanitizer to detect memory leaks in the C extension.
7
+ - [internal] Added Dockerfile and docker-compose.yml to run tests in a Linux environment.
8
+
9
+ ## [0.1.1] - 2024-01-22
10
+
11
+ - Fixed ArgumentError messages in C extension.
12
+ - [interna] Replace metaprogrammed Ruby wrapper methods with explicitly defined methods.
13
+ - [internal] Added tests for wrapper methods.
2
14
 
3
15
  ## [0.1.0] - 2023-12-31
4
16
 
5
17
  - Initial release
18
+
19
+ ## [Unreleased]
data/Dockerfile ADDED
@@ -0,0 +1,10 @@
1
+ ARG RUBY_VERSION=3.4
2
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim AS base
3
+ WORKDIR /tulirb
4
+ COPY . /tulirb
5
+ RUN apt-get update -qq && \
6
+ apt-get install -y build-essential \
7
+ git
8
+ RUN bundle install
9
+ CMD [ "/bin/bash" ]
10
+ ENTRYPOINT [ "/bin/bash", "-c" ]
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Tulirb
2
- Ruby bindings for the Tulip indicators technical analysis indicator library (https://tulipindicators.org/). This can be used to build tools for financial trading and data analytics in Ruby.
2
+ Ruby bindings for the Tulip indicators technical analysis indicator library (https://tulipindicators.org/). This can be used to build tools for financial markets trading and analytics in Ruby.
3
3
 
4
4
  ## Installation
5
5
 
@@ -18,6 +18,8 @@ This library consists of a single module: `Tulirb`. All indicator functions are
18
18
  Example:
19
19
 
20
20
  ```ruby
21
+ require("tulirb")
22
+
21
23
  # Exponential Moving Average
22
24
  Tulirb.ema([[1.2, 1.5, 1, 1.8]], period: 5) # => [[1.2, 1.35, 1.175, 1.4875]]
23
25
 
@@ -34,15 +36,22 @@ Example:
34
36
  ) # => [[650, 720.2020202020201, 120.20202020202017], [480.80808080808083, 690.0673400673401, 496.80134680134677]]
35
37
  ```
36
38
 
39
+ ## Documentation
40
+ Find documentation for all indicator functions [here](https://www.rubydoc.info/github/ozone4real/tulirb/main/Tulirb). Information about the input and option parameters for each indicator method are also available in the `Tulirb::INDICATORS_INFO` hash.
41
+
37
42
  ## Development
38
43
 
39
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
44
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to compile the C extension, detect memory leaks in the C extension and run tests. [AddressSanitizer](https://github.com/google/sanitizers/wiki/addresssanitizer) is used to detect memory leaks in the C extension but it is only available on Linux. I'll recommend running the `rake` command with Docker to run in a Linux environment. There is a Dockerfile and docker-compose.yml file in the root directory to help with this. You can run `rake` with Docker by executing:
45
+
46
+ $ docker compose run tulirb rake
47
+
48
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
40
49
 
41
50
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
51
 
43
52
  ## Contributing
44
53
 
45
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tulirb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/tulirb/blob/main/CODE_OF_CONDUCT.md).
54
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ozone4real/tulirb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ozone4real/tulirb/blob/main/CODE_OF_CONDUCT.md).
46
55
 
47
56
  ## License
48
57
 
@@ -50,4 +59,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
50
59
 
51
60
  ## Code of Conduct
52
61
 
53
- Everyone interacting in the Tulirb project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/tulirb/blob/main/CODE_OF_CONDUCT.md).
62
+ Everyone interacting in the Tulirb project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ozone4real/tulirb/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,5 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ def windows?
4
+ RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
5
+ end
6
+
7
+ def silence_stream(stream)
8
+ old_stream = stream.dup
9
+ stream.reopen(File::NULL)
10
+ stream.sync = true
11
+ yield
12
+ ensure
13
+ stream.reopen(old_stream)
14
+ end
15
+
16
+ def reenable_task_with_prereqs(task_name)
17
+ task = Rake::Task[task_name]
18
+ return unless task.already_invoked # Skip if task hasn't run before
19
+
20
+ task.prerequisite_tasks.each { |prereq| reenable_task_with_prereqs(prereq) } # Recursively reset prerequisites
21
+ task.reenable # Reset the main task itself
22
+ end
23
+
24
+ def detect_memory_leaks!
25
+ asan_path = `gcc -print-file-name=libasan.so`.strip
26
+ env = { "LD_PRELOAD" => asan_path }
27
+ Open3.capture3(env,
28
+ "ruby -Ilib:ext -r tulirb -e \"puts Tulirb.ema([[2, 4, 6]], period: 5)\"").tap do |_, error, status|
29
+ puts("Running memory leak detection with AddressSanitizer")
30
+ unless status.success?
31
+ errors = error.split("\n\n").grep(%r{ext/tulirb})
32
+ if errors.any?
33
+ elog = "Memory leaks detected in C extension:\n\n"
34
+ elog += errors.join("\n\n")
35
+ raise(elog)
36
+ end
37
+ end
38
+
39
+ puts("No memory leaks detected in C extension")
40
+ end
41
+ end
42
+
3
43
  require("bundler/gem_tasks")
4
44
  require("rake/testtask")
5
45
 
@@ -10,15 +50,30 @@ Rake::TestTask.new(:test) do |t|
10
50
  end
11
51
 
12
52
  require("rubocop/rake_task")
13
-
14
53
  RuboCop::RakeTask.new
15
54
 
16
55
  require("rake/extensiontask")
17
-
18
56
  task(build: :compile)
19
-
20
57
  Rake::ExtensionTask.new("tulirb") do |ext|
21
58
  ext.lib_dir = "lib/tulirb"
22
59
  end
23
60
 
24
- task(default: %i[clobber compile test rubocop])
61
+ task(detect_memory_leaks: :clobber) do
62
+ next if windows?
63
+
64
+ require("open3")
65
+ ENV["SANITIZE"] = "true"
66
+ silence_stream($stderr) { Rake::Task["compile"].invoke }
67
+
68
+ begin
69
+ detect_memory_leaks!
70
+ ensure
71
+ reenable_task_with_prereqs("clobber")
72
+ Rake::Task["clobber"].invoke
73
+ ENV["SANITIZE"] = "false"
74
+ reenable_task_with_prereqs("clobber")
75
+ reenable_task_with_prereqs("compile")
76
+ end
77
+ end
78
+
79
+ task(default: %i[detect_memory_leaks compile test rubocop clobber])
data/code_generator.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("tulirb")
4
+ require("active_support/core_ext/string")
5
+
6
+ file = File.open("code_output.rb", "a+")
7
+
8
+ file.write("class << self\n")
9
+
10
+ Tulirb::INDICATORS_INFO.each do |k, v|
11
+ kwargs = v[:options].map { |o| "#{o}:" }.join(", ")
12
+ kwargs = kwargs.empty? ? "" : ", #{kwargs}"
13
+ options_doc = v[:options].map { |o| "# @param #{o} [Numeric] #{o.titleize}" }
14
+ options_doc = options_doc.empty? ? "" : "\n#{options_doc.join(".\n")}."
15
+ func = <<~RUBY
16
+ # #{v[:full_name]}.
17
+ # @param inputs [Array<Array<Numeric>>] 2d array of inputs. #{options_doc}
18
+ # @return [Array<Array<Numeric>>] 2d array of results.
19
+ # @see Official TulipIndicators docs for detailed explanation and formular for this indicator function: (https://tulipindicators.org/#{k})
20
+ def #{k}(inputs#{kwargs})
21
+ super(inputs, [#{v[:options].join(", ")}])
22
+ end
23
+
24
+ RUBY
25
+ file.write(func)
26
+ end
27
+
28
+ file.write("end")
29
+ file.close
@@ -0,0 +1,8 @@
1
+ version: '3.4'
2
+
3
+ services:
4
+ tulirb:
5
+ platform: linux/amd64
6
+ build: .
7
+ volumes:
8
+ - .:/tulirb
@@ -2,8 +2,12 @@
2
2
 
3
3
  require "mkmf"
4
4
 
5
- # $LDFLAGS << " -fsanitize=address,undefined"
6
- # $CFLAGS << " -fsanitize=address,undefined"
5
+ if ENV["SANITIZE"] == "true"
6
+ CONFIG["optflags"] = "-O0"
7
+ CONFIG["debugflags"] = "-ggdb3"
8
+ $CFLAGS << " -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls -DTULIRB_SANITIZE=1"
9
+ $LDFLAGS << " -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls"
10
+ end
7
11
 
8
12
  $srcs = %w[tiamalgamation.c tulirb.c]
9
13
  create_makefile("tulirb/tulirb")