Module: OrderHandling

Included in:
IB::Gateway
Defined in:
lib/ib/gateway/order-handling.rb

Instance Method Summary collapse

Instance Method Details

#initialize_order_handlingObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ib/gateway/order-handling.rb', line 23

def initialize_order_handling
  tws.subscribe( :CommissionReport, :ExecutionData, :OrderStatus, :OpenOrder, :OpenOrderEnd, :NextValidId ) do |msg|
    case msg

    when IB::Messages::Incoming::CommissionReport
      # Commission-Reports are not assigned to a order -
      logger.info "CommissionReport -------#{msg.exec_id} :...:C: #{msg.commission} :...:P/L: #{msg.realized_pnl}-"
    when IB::Messages::Incoming::OrderStatus

      # The order-state only links via local_id and perm_id to orders.
      # There is no reference to a contract or an account

      success = update_order_dependent_object( msg.order_state) do |o|
        o.order_states.update_or_create msg.order_state, :status
      end

      logger.info {  "Order State not assigned-- #{msg.order_state.to_human} ----------" } if success.nil?

    when IB::Messages::Incoming::OpenOrder
      (msg.order.) do |  |
        # first update the contracts
        # make open order equal to IB::Spreads (include negativ con_id)
        msg.contract[:con_id] = -msg.contract.combo_legs.map{|y| y.con_id}.sum  if msg.contract.is_a? IB::Bag
        msg.contract.orders.update_or_create msg.order, :local_id
        .contracts.first_or_create msg.contract, :con_id
        # now save the order-record
        msg.order.contract = msg.contract
        .orders.update_or_create msg.order, :local_id
      end

      #     update_ib_order msg  ## aus support
    when IB::Messages::Incoming::OpenOrderEnd
      #             exitcondition=true
      logger.debug { "OpenOrderEnd" }

    when IB::Messages::Incoming::ExecutionData
      # Excution-Data are fired independly from order-states.
      # The Objects are stored at the associated order
      success = update_order_dependent_object( msg.execution) do |o|
        o.executions << msg.execution
        if msg.execution.cumulative_quantity.to_i == o.total_quantity.abs
          logger.info{ "#{o.} --> #{o.contract.symbol}: Execution completed" }
          o.order_states.first_or_create( IB::OrderState.new( perm_id: o.perm_id,
                                                             local_id: o.local_id,
                                                             status: 'Filled' ), :status )
          # update portfoliovalue
          a = @accounts.detect{ | x | x. == o. } #  we are in a mutex controlled environment
          pv = a.portfolio_values.detect{ | y | y.contract.con_id == o.contract.con_id}
          change = o.action == :sell ? -o.total_quantity : o.total_quantity
          if pv.present?
            pv.update_attribute :position, pv.position + change
          else
            a.portfolio_values << IB::PortfolioValue.new( position: change, contract: o.contract )
          end
        else
          logger.debug{ "#{o.} --> #{o.contract.symbol}: Execution not completed (#{msg.execution.cumulative_quantity.to_i}/#{o.total_quantity.abs})" }
        end  # branch
      end # block

      logger.error { "Execution-Record not assigned-- #{msg.execution.to_human} ----------" } if success.nil?

    end  # case msg.code
  end # do
end

#request_open_ordersObject Also known as: update_orders



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ib/gateway/order-handling.rb', line 94

def request_open_orders

  q =  Queue.new
  subscription = tws.subscribe( :OpenOrderEnd ) { q.push(true) }  # signal succsess
   {|  | .orders = [] }
  send_message :RequestAllOpenOrders
  ## the OpenOrderEnd-message usually appears after 0.1 sec.
  ## we wait for 1 sec.
  th =  Thread.new{   sleep 1 ; q.close  }

  q.pop # wait for OpenOrderEnd or finishing of thread

  tws.unsubscribe subscription
  if q.closed?
    5.times do
    logger.fatal { "Is the API in read-only modus?  No Open Order Message received! "}
    sleep  0.2
    end
  else
    Thread.kill(th)
    q.close
     {|  | .orders } # reset order array
  end
end

#update_order_dependent_object(order_dependent_object) ⇒ Object

UpdateOrderDependingObject

Generic method which enables operations on the order-Object, which is associated to OrderState-, Execution-, CommissionReport- events fired by the tws. The order is identified by local_id and perm_id

Everything is carried out in a mutex-synchonized environment



13
14
15
16
17
18
19
20
21
22
# File 'lib/ib/gateway/order-handling.rb', line 13

def update_order_dependent_object order_dependent_object  # :nodoc:
   do  | a |
    order = if order_dependent_object.local_id.present?
              a.locate_order( :local_id => order_dependent_object.local_id)
            else
              a.locate_order( :perm_id => order_dependent_object.perm_id)
            end
    yield order if order.present?
  end
end