Day26 - 用 Ruby on Rails 写分析股票的技术指标

前言

在做选股之前,可透过技术指标来分析,像是可以用 KD、均线、量价...等

说明

这边要申明下,这边是以技术交流为主,不会有任何投资建议,当自己写了一套选股策略後,除了要做回测外,要知道没有 100% 胜率且永远有效的方法,如果有,请私讯让我知道 xDD

实作

# app/models/stock.rb

class Stock < ApplicationRecord
  def specify_date(date)
    daily_quotes.find_by(transaction_date: date.to_date)
  end

  def self.simple_moving_average(code, number)
    stock = self.find_by!(code: code)
    stock.simple_moving_average(number)
  rescue ActiveRecord::RecordNotFound => e
    puts "无此股票代号: #{code}"
  end

  def simple_moving_average(number)
    result = daily_quotes.order("transaction_date DESC").limit(number).select(:closing_price)
    if result.size == number
      (result.sum(&:closing_price) / number).round(2)
    else
      0
    end
  end

  # 找出指定日期,成交量前几名的股票
  def self.top_ranks_trade_volume(number, date = nil)
    self.latest_transaction_date(date)
        .order("daily_quotes.trade_volume DESC")
        .limit(number)
        .select(:name, :code, "daily_quotes.trade_volume")
        .map { |stock| { "股票名称" => stock.name, "股票代号" => stock.code, "成交量(张)" => stock.trade_volume / 1000 } }
  end

  # 找出指定日期,成交量破XXXX张的股票
  def self.volume_broke_lot(number, date = nil)
    self.latest_transaction_date(date)
        .where("daily_quotes.trade_volume > ?", number * 1000)
        .order("daily_quotes.trade_volume DESC")
        .select(:name, :code, "daily_quotes.trade_volume")
        .map { |stock| { "股票名称" => stock.name, "股票代号" => stock.code, "成交量(张)" => stock.trade_volume / 1000 } }
  end

  # 找出指定日期,涨停的股票
  def self.find_limit_up_stocks(date = nil)
    latest_transaction_date = find_latest_transaction_dates(2, date)
    candidate_stocks = find_ups_and_downs(latest_transaction_date)
    candidate_stocks.select do |key, values|
      latest_info = nil
      yesterday_info = nil
      values.each do |value|
        if value.transaction_date == latest_transaction_date[0]
          latest_info = value
        else
          yesterday_info = value
        end
      end
      next if latest_info.ups_and_downs != "+" || latest_info.closing_price != latest_info.highest_price

      latest_info.closing_price >= yesterday_info.closing_price * 1.095
    end.keys
  end

  # 找出指定日期,跌停的股票
  def self.find_limit_down_stocks(date = nil)
    latest_transaction_date = find_latest_transaction_dates(2, date)
    candidate_stocks = find_ups_and_downs(latest_transaction_date)
    candidate_stocks.select do |key, values|
      latest_info = nil
      yesterday_info = nil
      values.each do |value|
        if value.transaction_date == latest_transaction_date[0]
          latest_info = value
        else
          yesterday_info = value
        end
      end
      next if latest_info.ups_and_downs != "-" || latest_info.closing_price != latest_info.lowest_price

      latest_info.closing_price <= yesterday_info.closing_price / 1.095
    end.keys
  end

  private

  # 找出最新 X 天的交易日期
  def self.find_latest_transaction_dates(number, date = nil)
    if date
      DailyQuote.where("transaction_date <= ?", date.to_date)
    else
      DailyQuote
    end.select(:transaction_date).order("transaction_date DESC").distinct.limit(number).pluck(:transaction_date)
  end

  def self.find_ups_and_downs(latest_transaction_date)
    self.joins(:daily_quotes)
        .where(daily_quotes: { transaction_date: latest_transaction_date[-1]..latest_transaction_date[0] })
        .order("daily_quotes.trade_volume DESC")
        .select(:code, :name,
                "daily_quotes.transaction_date", "daily_quotes.opening_price", "daily_quotes.closing_price",
                "daily_quotes.highest_price", "daily_quotes.lowest_price", "daily_quotes.ups_and_downs",
               )
        .group_by { |stock| { "股票名称" => stock.name, "股票代号" => stock.code } }
  end
end

实际执行画面

小结

每当写完一个技术指标後,如何验证自己写的是否正确呢?

我的做法是去用其他平台,然後看结果是否与我一样 XD

有更好的方法或发现有写错的地方,欢迎和我说喔

与「台湾证券交易所」有关的系列文,这边告一段落了,後面还有 4 篇铁人赛文章要写 (掩面哭,怎还没结束 QAQ)


铁人赛文章连结:https://ithelp.ithome.com.tw/articles/10273425
medium 文章连结:https://link.medium.com/G7zXw5NuTjb
本文同步发布於 小菜的 Blog https://riverye.com/

备注:之後文章修改更新,以个人部落格为主


<<:  企划实现(24)

>>:  企划实现(24)

C#学习笔记4:C#的基本运算

这是我一边学习一边写下的笔记,如果内容有错,恳请在下方留言跟我说,我会非常感谢的!!! 基本运算 一...

[Lesson10] Machine Learning

今天要来试着使用Firebase的机器学习套件,点击左边的Machine Learning 可以看到...

[Day 13] 非同步的操作资料库?谈 suspendedTransactionAsync

前面我们聊到了如何存取资料库,以及遇到 N+1 问题时该如何发现以及解决问题。 今天我们来谈谈 Ex...

【从零开始的 C 语言笔记】第十五篇-String 函式库介绍与应用

不怎麽重要的前言 上一篇我们介绍了array的延伸应用,利用字元阵列我们可以当作储存字串的工具。 今...

[Day29] Template Driven Form

昨天我们完成了 service 的部分,已经可以用程序码打 API 来做 CRUD,但是我们还没有准...