ãã©ãããªãã¼ãã¤ããã³ã®ãããªæ³¨æãçºè¡ããã¨ã¼ã¸ã§ã³ãã®ãµã³ãã«
FXã·ã¹ãã ãã¬ã¼ããã¬ã¼ã ã¯ã¼ã¯ãJijiãã®ãµã³ãã« ãã®2ãã¨ãã¦ã ãã©ãããªãã¼ãã¤ããã³ã®ãããªæ³¨æãçºè¡ããã¨ã¼ã¸ã§ã³ããä½ã£ã¦ã¿ã¾ããã
â»ãã©ãããªãã¼ãã¤ããã³(ãã©ãªã)ã¯ãããã¼ã¹ã¯ã¦ã§ã¢ã¸ã£ãã³ï¼M2Jï¼ã®ç»é²åæ¨ã§ãã
ãã©ãããªãã¼ãã¤ããã³ã¨ã¯
æå¤/éæå¤ã®æ³¨æã¨æ±ºæ¸ãè¤æ°çµã¿åããã¦è¡ãããã®ä¸ã§ã¬ã¼ããä¸ä¸ãããã¨ã§å©çãåºããã¨ãçããçºæ³¨ãã¸ãã¯ã§ãã å ·ä½çã«ã©ããã£ãåããããã®ãã¯ãããã¼ã¹ã¯ã¦ã§ã¢ã¸ã£ãã³ ã®ãµã¤ããã¨ã¦ãããããããã®ã§ããã¡ããã覧ãã ããã
ç¹å¾´
FXç 究æ¥è¨ããã®è©ä¾¡è¨äºãåèã«ãªãã¾ãã
- ã¬ã³ã¸ç¸å ´ã§ã¯ãå©çãåºãããã
- Ãã¬ã¼ããéè¡ããã¨æ失ã貯ãããã§ãã¾ã
ä»çµã¿ãããã¦ãããããã³ãã³ããã«ã³ãªã·ã¹ãã ã¨ããå°è±¡ã§ãã ã¬ã³ã¸ç¸å ´ãªãå©çãç©ã¿ä¸ããããã®ã§ããã¬ã³ããå¤å®ãããã¸ãã¯ã¨çµã¿åããã¦ãã¬ã¼ããä¸å®ã®ã¬ã³ã¸ã§åä½ãããã«ãªã£ãã稼åãããããªã©ããã°ä½¿ããããã
ã¨ã¼ã¸ã§ã³ãã®ã³ã¼ã
- å®è£ ã¯ãこちらã®ãµã¤ãã§é å¸ããã¦ããEAãåèã«ããã¦ããã ãã¾ããã
TrapRepeatIfDoneAgent
ããã¨ã¼ã¸ã§ã³ãã®æ¬ä½ã§ãããããããã¯ãã¹ãããªã¢ã«ãã¬ã¼ãã§åä½ãããã°OKã- ã¨ã¼ã¸ã§ã³ããã¡ã¤ã«ã®è¿½å ã®æ¹æ³ãªã©ãJijiã®åºæ¬çãªä½¿ãæ¹ã¯ãã¡ããã覧ãã ããã
- æ©è½ã®åå©ç¨ãã§ããããã«ãçºæ³¨å¦çã¯
TrapRepeatIfDone
ã«å®è£ ãã¦ãã¾ãã
# === ãã©ãããªãã¼ãã¤ããã³ã®ãããªæ³¨æãçºè¡ããã¨ã¼ã¸ã§ã³ã class TrapRepeatIfDoneAgent include Jiji::Model::Agents::Agent def self.description <<-STR ãã©ãããªãã¼ãã¤ããã³ã®ãããªæ³¨æãçºè¡ããã¨ã¼ã¸ã§ã³ã STR end # UIããè¨å®å¯è½ãªããããã£ã®ä¸è¦§ def self.property_infos [ Property.new('trap_interval_pips', 'ãã©ãããä»æããéé(pips)', 50), Property.new('trade_units', '1注æãããã®åå¼æ°é', 1), Property.new('profit_pips', 'å©çã確å®ããpips', 100), Property.new('slippage', '許容ã¹ãªããã¼ã¸(pips)', 3) ] end def post_create @trap_repeat_if_done = TrapRepeatIfDone.new( broker.pairs.find {|p| p.name == :USDJPY }, :buy, @trap_interval_pips.to_i, @trade_units.to_i, @profit_pips.to_i, @slippage.to_i, logger) end def next_tick(tick) @trap_repeat_if_done.register_orders(broker) end def state @trap_repeat_if_done.state end def restore_state(state) @trap_repeat_if_done.restore_state(state) end end # ãã©ãããªãã¼ãã¤ããã³ã®ãããªæ³¨æãçºè¡ããã¯ã©ã¹ class TrapRepeatIfDone # ã³ã³ã¹ãã©ã¯ã¿ # # target_pair:: ç¾å¨ã®ä¾¡æ ¼ãæ ¼ç´ããTick::Valueãªãã¸ã§ã¯ã # sell_or_buy:: åå¼ã¢ã¼ãã :buy ã®å ´åãè²·ã注æãçºè¡ããã :sellã®å ´åã売 # trap_interval_pips:: ãã©ãããä»æããéé(pips) # trade_units:: 1注æãããã®åå¼æ°é # profit_pips:: å©çã確å®ããpips # slippage:: 許容ã¹ãªããã¼ã¸ãnilã®å ´åãæå®ããªã def initialize(target_pair, sell_or_buy=:buy, trap_interval_pips=50, trade_units=1, profit_pips=100, slippage=3, logger=nil) @target_pair = target_pair @trap_interval_pips = trap_interval_pips @slippage = slippage @mode = if sell_or_buy == :sell Sell.new(target_pair, trade_units, profit_pips, slippage, logger) else Buy.new(target_pair, trade_units, profit_pips, slippage, logger) end @logger = logger @registerd_orders = {} end # 注æãç»é²ãã # # broker:: broker def register_orders(broker) broker.instance_variable_get(:@broker).refresh_positions # 常ã«ææ°ã®å»ºçãåå¾ãã¦å©ç¨ããããã«ãã # TODO å ¬éAPIã«ãã each_traps(broker.tick) do |trap_open_price| next if order_or_position_exists?(trap_open_price, broker) register_order(trap_open_price, broker) end end def state @registerd_orders end def restore_state(state) @registerd_orders = state unless state.nil? end private def each_traps(tick) current_price = @mode.resolve_current_price(tick[@target_pair.name]) base = resolve_base_price(current_price) 6.times do |n| # baseãåºæºã«ãä¸ä¸3ã¤ã®ãã©ãããä»æãã trap_open_price = BigDecimal.new(base, 10) \ + BigDecimal.new(@trap_interval_pips, 10) * (n-3) * @target_pair.pip yield trap_open_price end end # ç¾å¨ä¾¡æ ¼ãtrap_interval_pipsã§ä¸¸ããä¾¡æ ¼ãè¿ãã # # ä¾) trap_interval_pipsã50ã®å ´åã # resolve_base_price(120.10) # -> 120.00 # resolve_base_price(120.49) # -> 120.00 # resolve_base_price(120.51) # -> 120.50 # def resolve_base_price(current_price) current_price = BigDecimal.new(current_price, 10) pip_precision = 1 / @target_pair.pip (current_price * pip_precision / @trap_interval_pips ).ceil \ * @trap_interval_pips / pip_precision end # trap_open_priceã«å¯¾å¿ãããªã¼ãã¼ãç»é²ãã def register_order(trap_open_price, broker) result = @mode.register_order(trap_open_price, broker) unless result.order_opened.nil? @registerd_orders[key_for(trap_open_price)] \ = result.order_opened.internal_id end end # trap_open_priceã«å¯¾å¿ãããªã¼ãã¼ãç»é²æ¸ã¿ãè©ä¾¡ãã def order_or_position_exists?(trap_open_price, broker) order_exists?(trap_open_price, broker) \ || position_exists?(trap_open_price, broker) end def order_exists?(trap_open_price, broker) key = key_for(trap_open_price) return false unless @registerd_orders.include? key id = @registerd_orders[key] order = broker.orders.find {|o| o.internal_id == id } return !order.nil? end def position_exists?(trap_open_price, broker) # trapã®ãªãããä»è¿ã§ã¬ã¼ããä¸ä¸ãã¦æ³¨æã大éã«çºæ³¨ãããªãããã # trapã®ãªãããä»è¿ãéå§å¤ã¨ãã建çãåå¨ããéã¯ãtrapã®æ³¨æãçºè¡ããªã slipage_price = (@slippage.nil? ? 10 : @slippage) * @target_pair.pip position = broker.positions.find do |p| # 注ææã«æå®ããpriceã¡ããã©ã§ç´å®ããªãå ´åãèæ ®ãã¦ã # æå®ããslippage(æå®ãªãã®å ´åã¯10pips)ã®èª¤å·®ãèæ ®ãã¦åå¨å¤å®ããã p.entry_price < trap_open_price + slipage_price \ && p.entry_price > trap_open_price - slipage_price end return !position.nil? end def key_for(trap_open_price) (trap_open_price * (1 / @target_pair.pip)).to_i.to_s end # åå¼ã¢ã¼ã(売 or è²·) # è²·(Buy)ã®å ´åãè²·ã§ãªã¼ãã¼ãè¡ãã売(Sell)ã®å ´åã売ã§ãªã¼ãã¼ãè¡ãã class Mode def initialize(target_pair, trade_units, profit_pips, slippage, logger) @target_pair = target_pair @trade_units = trade_units @profit_pips = profit_pips @slippage = slippage @logger = logger end # ç¾å¨ä¾¡æ ¼ãåå¾ãã(è²·ã®å ´åAskã¬ã¼ãã売ã®å ´åBidã¬ã¼ãã使ã) # # tick_value:: ç¾å¨ã®ä¾¡æ ¼ãæ ¼ç´ããTick::Valueãªãã¸ã§ã¯ã # æ»ãå¤:: ç¾å¨ä¾¡æ ¼ def resolve_current_price(tick_value) end # 注æãç»é²ãã def register_order(trap_open_price, broker) end def calculate_price(price, pips) price = BigDecimal.new(price, 10) pips = BigDecimal.new(pips, 10) * @target_pair.pip (price + pips).to_f end def pring_order_log(mode, options, timestamp) return unless @logger message = [ mode, timestamp, options[:price], options[:take_profit], options[:lower_bound], options[:upper_bound] ].map {|item| item.to_s }.join(" ") @logger.info message end end class Sell < Mode def resolve_current_price(tick_value) tick_value.bid end def register_order(trap_open_price, broker) timestamp = broker.tick.timestamp options = create_option(trap_open_price, timestamp) pring_order_log("sell", options, timestamp) broker.sell(@target_pair.name, @trade_units, :marketIfTouched, options) end def create_option(trap_open_price, timestamp) options = { price: trap_open_price.to_f, take_profit: calculate_price(trap_open_price, @profit_pips*-1), expiry: timestamp + 60*60*24*7 } unless @slippage.nil? options[:lower_bound] = calculate_price(trap_open_price, @slippage*-1) options[:upper_bound] = calculate_price(trap_open_price, @slippage) end options end end class Buy < Mode def resolve_current_price(tick_value) tick_value.ask end def register_order(trap_open_price, broker) timestamp = broker.tick.timestamp options = create_option(trap_open_price, timestamp) pring_order_log("buy", options, timestamp) broker.buy(@target_pair.name, @trade_units, :marketIfTouched, options) end def create_option(trap_open_price, timestamp) options = { price: trap_open_price.to_f, take_profit: calculate_price(trap_open_price, @profit_pips), expiry: timestamp + 60*60*24*7 } unless @slippage.nil? options[:lower_bound] = calculate_price(trap_open_price, @slippage*-1) options[:upper_bound] = calculate_price(trap_open_price, @slippage) end options end end end