Class: DhanHQ::Strategy::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/DhanHQ/strategy/base.rb

Overview

Base class for all strategies.

Provides DSL for defining entry/exit rules and risk management.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name: self.class.name, params: {}) ⇒ Base

Returns a new instance of Base.



53
54
55
56
57
58
59
60
61
# File 'lib/DhanHQ/strategy/base.rb', line 53

def initialize(name: self.class.name, params: {})
  @name = name
  @params = params
  @position = nil
  @entry_rules = {}
  @exit_rules = {}
  @risk_rules = {}
  @signals = []
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



51
52
53
# File 'lib/DhanHQ/strategy/base.rb', line 51

def name
  @name
end

#paramsObject (readonly)

Returns the value of attribute params.



51
52
53
# File 'lib/DhanHQ/strategy/base.rb', line 51

def params
  @params
end

#positionObject (readonly)

Returns the value of attribute position.



51
52
53
# File 'lib/DhanHQ/strategy/base.rb', line 51

def position
  @position
end

Class Method Details

.entry_rule(name, priority: 10, &block) ⇒ Object

Define an entry rule.

Parameters:

  • name (Symbol)

    Rule name

  • priority (Integer) (defaults to: 10)

    Rule priority (lower = higher priority)

  • block (Proc)

    Rule condition block



68
69
70
71
# File 'lib/DhanHQ/strategy/base.rb', line 68

def self.entry_rule(name, priority: 10, &block)
  @entry_rules ||= {}
  @entry_rules[name] = { priority: priority, block: block }
end

.entry_rulesObject

Get all entry rules for this strategy class.



93
94
95
# File 'lib/DhanHQ/strategy/base.rb', line 93

def self.entry_rules
  @entry_rules || {}
end

.exit_rule(name, priority: 10, &block) ⇒ Object

Define an exit rule.

Parameters:

  • name (Symbol)

    Rule name

  • priority (Integer) (defaults to: 10)

    Rule priority (lower = higher priority)

  • block (Proc)

    Rule condition block



78
79
80
81
# File 'lib/DhanHQ/strategy/base.rb', line 78

def self.exit_rule(name, priority: 10, &block)
  @exit_rules ||= {}
  @exit_rules[name] = { priority: priority, block: block }
end

.exit_rulesObject

Get all exit rules for this strategy class.



98
99
100
# File 'lib/DhanHQ/strategy/base.rb', line 98

def self.exit_rules
  @exit_rules || {}
end

.risk_rule(name, &block) ⇒ Object

Define a risk rule.

Parameters:

  • name (Symbol)

    Rule name

  • block (Proc)

    Risk check block



87
88
89
90
# File 'lib/DhanHQ/strategy/base.rb', line 87

def self.risk_rule(name, &block)
  @risk_rules ||= {}
  @risk_rules[name] = block
end

.risk_rulesObject

Get all risk rules for this strategy class.



103
104
105
# File 'lib/DhanHQ/strategy/base.rb', line 103

def self.risk_rules
  @risk_rules || {}
end

Instance Method Details

#check_risks(context) ⇒ Array<Symbol>

Check all risk rules.

Parameters:

  • context (Hash)

    Risk check context

Returns:

  • (Array<Symbol>)

    List of violated rule names



157
158
159
160
161
162
163
164
165
166
# File 'lib/DhanHQ/strategy/base.rb', line 157

def check_risks(context)
  violations = []

  self.class.risk_rules.each do |rule_name, block|
    result = block.call(context, params)
    violations << rule_name unless result
  end

  violations
end

#evaluate_entry(data) ⇒ DhanHQ::Strategy::Signal

Evaluate entry rules against market data.

Parameters:

Returns:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/DhanHQ/strategy/base.rb', line 111

def evaluate_entry(data)
  sorted_rules = self.class.entry_rules.sort_by { |_, v| v[:priority] }

  sorted_rules.each do |rule_name, rule|
    result = rule[:block].call(data, params)
    next unless result

    signal = Signal.new(
      type: :buy,
      strength: calculate_strength(result),
      metadata: { rule: rule_name, data: data }
    )
    @signals << signal
    return signal
  end

  Signal.new(type: :hold, strength: 0.0, metadata: { reason: :no_entry_signal })
end

#evaluate_exit(data) ⇒ DhanHQ::Strategy::Signal

Evaluate exit rules against market data.

Parameters:

Returns:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/DhanHQ/strategy/base.rb', line 134

def evaluate_exit(data)
  sorted_rules = self.class.exit_rules.sort_by { |_, v| v[:priority] }

  sorted_rules.each do |rule_name, rule|
    result = rule[:block].call(data, params)
    next unless result

    signal = Signal.new(
      type: :sell,
      strength: calculate_strength(result),
      metadata: { rule: rule_name, data: data }
    )
    @signals << signal
    return signal
  end

  Signal.new(type: :hold, strength: 0.0, metadata: { reason: :no_exit_signal })
end

#last_signalObject

Get the last signal.



174
175
176
# File 'lib/DhanHQ/strategy/base.rb', line 174

def last_signal
  @signals.last
end

#signalsObject

Get all signals generated by this strategy.



169
170
171
# File 'lib/DhanHQ/strategy/base.rb', line 169

def signals
  @signals.dup
end