unageanu-jiji 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.
Files changed (61) hide show
  1. data/README +1 -0
  2. data/base/agents/moving_average_agent.rb +78 -0
  3. data/base/shared_lib/moving_average.rb +34 -0
  4. data/bin/jiji +5 -0
  5. data/html/css/default.css +7 -0
  6. data/html/img/button_calendar_over.gif +0 -0
  7. data/html/img/button_cancel.gif +0 -0
  8. data/html/img/button_no.gif +0 -0
  9. data/html/img/button_no_gray.gif +0 -0
  10. data/html/img/button_no_over.gif +0 -0
  11. data/html/img/button_save.gif +0 -0
  12. data/html/img/button_save_gray.gif +0 -0
  13. data/html/img/button_save_over.gif +0 -0
  14. data/html/img/button_update_s.gif +0 -0
  15. data/html/img/button_update_s_gray.gif +0 -0
  16. data/html/img/button_update_s_over.gif +0 -0
  17. data/html/img/button_yes.gif +0 -0
  18. data/html/img/button_yes_gray.gif +0 -0
  19. data/html/img/button_yes_over.gif +0 -0
  20. data/html/index.html +29 -33
  21. data/html/js/agent-editor-page.js +178 -88
  22. data/html/js/agent-selector.js +68 -39
  23. data/html/js/bt-create-page.js +24 -11
  24. data/html/js/dialog.js +43 -34
  25. data/html/js/result-page.js +37 -25
  26. data/html/js/rt-setting-page.js +13 -6
  27. data/html/js/sidebar.js +8 -5
  28. data/html/js/templates.js +37 -3
  29. data/html/js/utils.js +47 -9
  30. data/html/swf/chart.swf +0 -0
  31. data/lib/jiji/agent/agent_manager.rb +2 -2
  32. data/lib/jiji/agent/agent_registry.rb +4 -1
  33. data/lib/jiji/command.rb +6 -0
  34. data/lib/jiji/process.rb +32 -10
  35. data/lib/jiji/process_manager.rb +7 -0
  36. data/lib/jiji/registry.rb +6 -4
  37. data/lib/jiji/server.rb +6 -1
  38. data/lib/jiji/service/output_service.rb +10 -6
  39. data/swf/chart/fx/chart/Chart.as +4 -1
  40. data/swf/chart/fx/chart/ui/Constants.as +3 -3
  41. data/swf/chart/fx/chart/ui/InformationWindow.as +45 -41
  42. data/swf/chart/fx/chart/ui/Pointer.as +6 -4
  43. data/swf/chart/fx/chart/ui/Scroll.as +3 -2
  44. data/swf/chart/fx/chart/ui/Stage.as +3 -3
  45. data/swf/chart/fx/chart/ui/TradeDetailWindow.as +9 -8
  46. data/swf/chart/fx/chart/ui/TradeResult.as +3 -17
  47. data/swf/chart/fx/chart/ui/graph/Graph.as +4 -2
  48. data/swf/chart/fx/chart/ui/graph/GraphManager.as +3 -1
  49. data/swf/chart/fx/chart/ui/resource/fixed.gif +0 -0
  50. data/swf/chart/fx/chart/ui/resource/unfixed.gif +0 -0
  51. data/swf/chart/fx/net/StubFactory.as +3 -3
  52. data/test/all_tests.rb +1 -1
  53. data/test/test_AgentManager.rb +4 -4
  54. data/test/{test_AgentRegistory.rb → test_AgentRegistry.rb} +0 -0
  55. data/test/test_Collector.rb +1 -1
  56. data/test/test_Output_registry.rb +7 -3
  57. data/test/test_Process.rb +5 -5
  58. data/test/test_ProcessManager.rb +120 -68
  59. metadata +20 -14
  60. data/bin/jiji.rb +0 -6
  61. data/html/js/W3CDTF.js +0 -131
data/html/js/utils.js CHANGED
@@ -239,7 +239,10 @@ util.Button = function( id, imgName, action, alt, accesskey, enable, prefix, suf
239
239
  if (accesskey) { this.a.accessKey = accesskey; }
240
240
  this.n.appendChild( this.a );
241
241
  this.img = document.createElement("img");
242
- if (alt) { this.img.alt = accesskey ? alt + "( " +accesskey+ " )" : alt; }
242
+ if (alt) {
243
+ this.img.alt = accesskey ? alt + "( " +accesskey+ " )" : alt;
244
+ this.img.title = this.img.alt;
245
+ }
243
246
  this.img.src = prefix + this.imgName + suffix;
244
247
  this.img.style.width = this.n.style.width;
245
248
  var self = this;
@@ -389,6 +392,25 @@ util.BasicTable = {
389
392
  self.table.subscribe("rowMouseoverEvent", self.table.onEventHighlightRow);
390
393
  self.table.subscribe("rowMouseoutEvent", self.table.onEventUnhighlightRow);
391
394
  self.table.subscribe("rowClickEvent", self.table.onEventSelectRow);
395
+
396
+ // リサイザーを強制的に利用可にする。
397
+ var res = document.getElementsByClassName("yui-dt-resizer", self.elementId);
398
+ for ( var i=0,n=res.length;i<n;i++ ) {
399
+ res[i].style.height = "19px";
400
+ }
401
+
402
+ // ローディングを作成
403
+ this.table_elm = document.getElementById(self.elementId);
404
+ this.loading_elm = document.createElement('div');
405
+ this.loading_elm.innerHTML = fx.template.Templates.common.loading;
406
+ this.loading_elm.style.padding = "10px";
407
+ this.loading_elm.style.display = "none";
408
+ this.table_elm.parentNode.appendChild(this.loading_elm);
409
+ this.loading(true);
410
+ },
411
+ loading : function( on ) {
412
+ this.loading_elm.style.display = on ? "block" : "none";
413
+ this.table_elm.style.display = on ? "none" : "block";
392
414
  },
393
415
  setData: function( data ) {
394
416
  if ( this.length() > 0 ) {
@@ -466,7 +488,7 @@ util.TopicPath.prototype = {
466
488
  set: function( path ) {
467
489
  var el = document.getElementById( this.elementId );
468
490
  if ( path ) {
469
- el.innerHTML = "<li>" + path.split(":").join("</li><li>") + "</li>";
491
+ el.innerHTML = "<li>" + path.escapeHTML().split(":").join("</li><li>") + "</li>";
470
492
  } else {
471
493
  el.innerHTML = "";
472
494
  }
@@ -507,7 +529,7 @@ util.DateInput.prototype = {
507
529
  var el = document.getElementById( this.elementId );
508
530
  el.innerHTML = this.template.evaluate( {
509
531
  elementId: this.elementId,
510
- title: this.title
532
+ title: this.title.escapeHTML()
511
533
  } );
512
534
  this.calendar = new YAHOO.widget.Calendar(this.elementId+"_cal", {
513
535
  iframe:false, // Turn iframe off, since container has iframe support.
@@ -625,9 +647,9 @@ util.ColorPicker.prototype = {
625
647
  var bottom = "";
626
648
  var current = top;
627
649
  var list = ["11","33","55","77","99","BB","DD","FF"];
628
- for ( var g=0;g<list.length;g++ ) {
629
- for ( var r=0;r<list.length;r++ ) {
630
- for ( var b=0;b<list.length;b++ ) {
650
+ for ( var g=0,gn=list.length;g<gn;g++ ) {
651
+ for ( var r=0,rn=list.length;r<rn;r++ ) {
652
+ for ( var b=0,bn=list.length;b<bn;b++ ) {
631
653
  var c = list[r] + list[g] +list[b];
632
654
  str = '<td><div class="block" style="background-color:#' + c + ';border:1px solid #' + c + ';"></div></td>'
633
655
  if ( r <= 3 ) {
@@ -673,9 +695,13 @@ util.ColorPicker.prototype = {
673
695
  }
674
696
  for ( var i=0,n=blocks.length;i<n;i++ ) {
675
697
  if ( blocks[i] == el ) { continue; }
676
- YAHOO.util.Event.addListener(blocks[i], "mouseover", enter);
677
- YAHOO.util.Event.addListener(blocks[i], "mouseout", out);
678
- YAHOO.util.Event.addListener(blocks[i], "click", click);
698
+ // IE7だとリスナ登録がやたら遅いので、直接イベントハンドラを割り当てる。
699
+ // YAHOO.util.Event.addListener(blocks[i], "mouseover", enter);
700
+ // YAHOO.util.Event.addListener(blocks[i], "mouseout", out);
701
+ // YAHOO.util.Event.addListener(blocks[i], "click", click);
702
+ blocks[i].onmouseover=enter;
703
+ blocks[i].onmouseout=out;
704
+ blocks[i].onclick=click;
679
705
  }
680
706
 
681
707
  YAHOO.util.Event.addListener(document.body, "click", function( ev ) {
@@ -712,5 +738,17 @@ util.ColorPicker.prototype = {
712
738
  }
713
739
  }
714
740
 
741
+ ///**テンプレートに、引数の文字列をエスケープする機能を追加*/
742
+ //Template.prototype.evaluate_org = Template.prototype.evaluate;
743
+ //Template.prototype.evaluate = function( object ) {
744
+ // for( var i in object ) {
745
+ // if ( Object.isFunction(object[i].escapeHTML) ) {
746
+ // object[i] = object[i].escapeHTML();
747
+ // }
748
+ // }
749
+ // return this.evaluate_org( object );
750
+ //}
751
+
752
+
715
753
  /**制御文字*/
716
754
  util.CONTROLL_CODE = /[\x00-\x1F\x7F]/
data/html/swf/chart.swf CHANGED
Binary file
@@ -33,7 +33,7 @@ module JIJI
33
33
  if @agents.key? id
34
34
  raise UserError.new( JIJI::ERROR_ALREADY_EXIST, "agent is already exist. id=#{id}")
35
35
  end
36
- output = @registory.output( @id, id )
36
+ output = @registry.output( @id, id )
37
37
  op = AgentOperator.new( @operator, name )
38
38
  safe( conf.get( [:agent,:safe_level], 4) ){
39
39
  agent.operator = op
@@ -127,7 +127,7 @@ module JIJI
127
127
  attr :trade_result_dao, true
128
128
  attr :operator, true
129
129
  attr :conf, true
130
- attr :registory, true
130
+ attr :registry, true
131
131
  end
132
132
 
133
133
  end
@@ -236,7 +236,10 @@ module JIJI
236
236
  checked << m
237
237
  m.constants.each {|name|
238
238
  cl = m.const_get name
239
- block.call( "#{get_name(cl.name)}@#{file}" ) if cl.kind_of?(Class) && cl < JIJI::Agent
239
+ begin
240
+ block.call( "#{get_name(cl.name)}@#{file}" ) if cl.kind_of?(Class) && cl < JIJI::Agent
241
+ rescue Exception
242
+ end
240
243
  find_agent( file, cl, checked, &block ) if cl.kind_of?(Module)
241
244
  }
242
245
  end
data/lib/jiji/command.rb CHANGED
@@ -86,6 +86,12 @@ securities:
86
86
  DATA
87
87
  }
88
88
  FileUtils.chmod(0600, "#{dir}/conf/configuration.yaml")
89
+
90
+ # サンプルエージェント
91
+ ["agents","shared_lib"].each {|d|
92
+ mkdir("#{dir}/#{d}")
93
+ FileUtils.copy( Dir.glob("#{__FILE__}/../../../base/#{d}/*"), "#{dir}/#{d}" )
94
+ }
89
95
  rescue Exception
90
96
  puts "[ERROR] setting failed.(#{$!.to_s})"
91
97
  return
data/lib/jiji/process.rb CHANGED
@@ -15,7 +15,10 @@ module JIJI
15
15
 
16
16
  # コンストラクタ
17
17
  # 再起動後の復元の場合、プロパティを指定しないこと。この場合設定ファイルからロードされる。
18
- def initialize( id, process_dir, agent_manager, props=nil, ignore_error=false )
18
+ def initialize( id, process_dir, agent_manager, props=nil, registry=nil, ignore_error=false )
19
+
20
+ is_recreate = props == nil
21
+ @registry = registry
19
22
  @id = id
20
23
  @agent_manager = agent_manager
21
24
  @process_dir = process_dir
@@ -26,7 +29,7 @@ module JIJI
26
29
  FileUtils.mkdir_p dir
27
30
 
28
31
  prop_file = "#{dir}/props.yaml"
29
- if props
32
+ if !is_recreate
30
33
  @props = props
31
34
  @props["agents"] = [] unless @props.key? "agents"
32
35
  save_props
@@ -40,8 +43,20 @@ module JIJI
40
43
  }
41
44
  @props["agents"] = [] unless @props.key? "agents"
42
45
  end
43
- load_agent(ignore_error)
44
46
 
47
+ # 新規作成の場合はエージェントをロード
48
+ # 再起動後の再作成時は、アウトプロットのみ作成。
49
+ @outputs = {}
50
+ if !is_recreate
51
+ load_agent(ignore_error)
52
+ else
53
+ if @props && @props["agents"]
54
+ @props["agents"].each {|v|
55
+ @outputs[v["id"]] = @registry.output( @id, v["id"] )
56
+ }
57
+ end
58
+ end
59
+
45
60
  # 取引の有効状態を更新
46
61
  @agent_manager.operator.trade_enable =
47
62
  @props["trade_enable"] ? true : false
@@ -55,8 +70,7 @@ module JIJI
55
70
  collector.start
56
71
  }
57
72
  # 状態を覚えておく
58
- props["state"] = collector.state
59
- save_props
73
+ self["state"] = collector.state
60
74
  end
61
75
 
62
76
  def stop
@@ -64,14 +78,18 @@ module JIJI
64
78
  if @started # 起動していない場合は何もしない
65
79
  observer_manager.stop
66
80
  collector.stop
67
- collector.logger.close
68
81
 
69
82
  # 状態を覚えておく
70
- props["state"] = collector.state
71
- save_props
83
+ self["state"] = collector.state
72
84
  @started = false
85
+ else
86
+ # 待機中の場合、キャンセル状態にする。
87
+ if props["state"] == :WAITING
88
+ self["state"] = :CANCELED
89
+ end
73
90
  end
74
91
  }
92
+ collector.logger.close
75
93
  end
76
94
 
77
95
  def state
@@ -132,7 +150,9 @@ module JIJI
132
150
  attr :observer_manager, true
133
151
  attr :process_dir, true
134
152
  attr :agent_manager, true
135
-
153
+ attr :outputs, true
154
+ attr :registry, true
155
+
136
156
  private
137
157
 
138
158
  # 任意のエージェントの設定を更新する。
@@ -170,10 +190,12 @@ module JIJI
170
190
  begin
171
191
  agent = agent_manager.agent_registry.create( v["class"], v["properties"] )
172
192
  agent_manager.add( v["id"], agent, v["name"] )
193
+ @outputs[v["id"]] = agent.output
173
194
  rescue Exception
174
195
  raise $! unless ignore_error
175
196
  # リアルトレードの場合、停止中にエージェントが破棄された場合を考慮し
176
- # エージェントの初期化で失敗しても無視する。
197
+ # エージェントの初期化で失敗しても無視し、出力先だけ作成
198
+ @outputs[v["id"]] = @registry.output( @id, v["id"] )
177
199
  end
178
200
  }
179
201
  end
@@ -40,6 +40,10 @@ module JIJI
40
40
  @registry.operator( "rmt", false, nil).stop
41
41
  @rmt.stop
42
42
  @mutex.synchronize {
43
+ @waiting.each {|i|
44
+ i.collector.listeners.delete(self)
45
+ i.stop
46
+ }
43
47
  @waiting.clear
44
48
  if @running != nil
45
49
  @running.collector.listeners.delete(self)
@@ -164,6 +168,9 @@ module JIJI
164
168
  else
165
169
  @running = nil
166
170
  end
171
+ else
172
+ # 待機中であればキューから除外。
173
+ @waiting = @waiting.reject{|i| i.id == id }
167
174
  end
168
175
  }
169
176
  @back_tests.delete( id )
data/lib/jiji/registry.rb CHANGED
@@ -74,7 +74,9 @@ module JIJI
74
74
  r.register( :server_logger ) {
75
75
  dir = "#{r.base_dir}/#{r.conf.get([:dir,:log], "logs")}"
76
76
  FileUtils.mkdir_p dir
77
- Logger.new( dir + "/log.txt", 10, 512*1024 )
77
+ l = Logger.new( dir + "/log.txt", 10, 512*1024 )
78
+ l.level = Logger::DEBUG
79
+ l
78
80
  }
79
81
  r.register( :process_logger, :model=>:multiton_initialize ) {|c,p,id|
80
82
  dir = "#{r.process_dir}/#{id}"
@@ -129,7 +131,7 @@ module JIJI
129
131
  c = JIJI::AgentManager.new( id, r.agent_registry, r.process_logger(id), failsafe )
130
132
  c.operator = r.operator(id, false, nil) # 作成段階では常に取引は行なわない。
131
133
  c.client = r.client
132
- c.registory = r
134
+ c.registry = r
133
135
  c.conf = r.conf
134
136
  c.trade_result_dao = r.trade_result_dao(id)
135
137
  c
@@ -177,7 +179,7 @@ module JIJI
177
179
 
178
180
  # RMTプロセス
179
181
  r.register( :rmt_process ) {
180
- c = JIJI::Process.new("rmt", r.process_dir, r.agent_manager("rmt",true), nil, true)
182
+ c = JIJI::Process.new("rmt", r.process_dir, r.agent_manager("rmt",true), nil, r, true)
181
183
  c.observer_manager = r.rmt_observer_manager
182
184
  c.collector = r.rmt_collector
183
185
  c
@@ -186,7 +188,7 @@ module JIJI
186
188
  r.register( :backtest_process, :model=>:multiton_initialize ) {|c,p,id, props|
187
189
  # 既存のバックテストを読み込む場合、プロパティはnil
188
190
  # このときエージェントの初期化で失敗しても無視する。(テスト実行後にエージェントが書き換えられた場合に起こりえる。)
189
- c = JIJI::Process.new(id, r.process_dir, r.agent_manager(id,false), props, props == nil)
191
+ c = JIJI::Process.new(id, r.process_dir, r.agent_manager(id,false), props, r, props == nil)
190
192
  c.observer_manager = r.backtest_observer_manager(id)
191
193
  c.collector = r.backtest_collector(id,
192
194
  Time.at( c["start_date"]), Time.at( c["end_date"]))
data/lib/jiji/server.rb CHANGED
@@ -14,7 +14,12 @@ module JIJI
14
14
 
15
15
  conf = registry[:conf]
16
16
  param[:Port] = conf.get([:server,:port], 7000).to_i
17
- param[:ServerType] = WEBrick::Daemon
17
+ begin
18
+ fork{}
19
+ param[:ServerType] = WEBrick::Daemon
20
+ rescue Exception
21
+ end
22
+
18
23
  param[:Logger] = registry[:server_logger]
19
24
  param[:DocumentRoot] = File.expand_path( "#{__FILE__}/../../../html" )
20
25
 
@@ -8,8 +8,9 @@ module JIJI
8
8
  list = {}
9
9
  names.each {|n|
10
10
  buff = []
11
- outputs = p.agent_manager.get(n[0]).output
12
- outputs.get(n[1]).each( scale,
11
+ outputs = p.outputs[n[0]]
12
+ next unless outputs
13
+ outputs.get(n[1]).each( scale,
13
14
  Time.at(start_time), Time.at(end_time) ) {|data|
14
15
  buff << data
15
16
  }
@@ -22,8 +23,8 @@ module JIJI
22
23
  # プロセスの出力一覧を取得する
23
24
  def list_outputs( process_id )
24
25
  p = process_manager.get( process_id )
25
- return p.agent_manager.inject({}) {|buff,item|
26
- buff[item[0]] = item[1].output.inject({}) {|r,v|
26
+ return p.outputs.inject({}) {|buff,item|
27
+ buff[item[0]] = item[1].inject({}) {|r,v|
27
28
  r[v[0]] = v[1].options
28
29
  r
29
30
  }
@@ -34,8 +35,11 @@ module JIJI
34
35
  # アウトプットのプロパティを設定
35
36
  def set_properties( process_id, name, properties )
36
37
  p = process_manager.get( process_id )
37
- outputs = p.agent_manager.get(name[0]).output
38
- outputs.get(name[1]).set_properties( properties )
38
+ outputs = p.outputs[name[0]]
39
+ raise UserError.new( JIJI::ERROR_NOT_FOUND, "output not found. name=#{name[0]}") unless outputs
40
+ out = outputs.get(name[1])
41
+ raise UserError.new( JIJI::ERROR_NOT_FOUND, "output not found. name=#{name[0]}:#{name[1]}") unless out
42
+ out.set_properties( properties )
39
43
  return :success
40
44
  end
41
45
 
@@ -94,7 +94,7 @@ package fx.chart {
94
94
 
95
95
 
96
96
  } catch ( ex:Error ) {
97
- log(ex.message + ":" + ex.getStackTrace());
97
+ //log(ex.message + ":" + ex.getStackTrace());
98
98
  }
99
99
  }
100
100
  /**
@@ -104,6 +104,9 @@ package fx.chart {
104
104
  ExternalInterface.addCallback("initializeChart", this.initializeChart );
105
105
  ExternalInterface.addCallback("setDate", function( date:Number ):void {
106
106
  ctrl.changeDate( Util.createDate(date) );
107
+ pointer.setPosition(
108
+ rc.stage.candle.left + (rc.stage.candle.width/2) + 11,
109
+ rc.stage.candle.bottom - (rc.stage.candle.height/4));
107
110
  } );
108
111
  ExternalInterface.addCallback("setGraphVisible", this.setGraphVisible );
109
112
  ExternalInterface.addCallback("setGraphColors", this.setGraphColors );
@@ -39,15 +39,15 @@ package fx.chart.ui {
39
39
  /**
40
40
  * 取引:+
41
41
  */
42
- public static const COLOR_UP:uint = 0xEE5B8E;//0xD65B7E;
42
+ public static const COLOR_UP:uint = 0xFE4B7E;//0xD65B7E;
43
43
  /**
44
44
  * 取引:-
45
45
  */
46
- public static const COLOR_DOWN:uint = 0x5B8Eee;//0x78A0D9;
46
+ public static const COLOR_DOWN:uint = 0x4B7EFF;//0x78A0D9;
47
47
  /**
48
48
  * 取引:同じ
49
49
  */
50
- public static const COLOR_DRAW:uint = 0xA79CE0;//0x8C83c2;
50
+ public static const COLOR_DRAW:uint = 0x978CD0;//0x8C83c2;
51
51
 
52
52
  public static const COLOR_UP_3:uint = 0xE35080;
53
53
  public static const COLOR_UP_2:uint = 0xC46F8A;
@@ -98,49 +98,53 @@ package fx.chart.ui {
98
98
  window.window.addChild( item );
99
99
  } );
100
100
  }
101
- public function onMouseMove( ev:MouseEvent ):void {
102
- var stageWidth:int = rc.stage.width;
103
- var stageHeight:int = rc.stage.height;
104
- if ( model.rateDatas &&
105
- ev.stageX >= rc.stage.candle.left+1 &&
106
- ev.stageX < rc.stage.candle.right &&
107
- ev.stageY > rc.stage.candle.top &&
108
- ev.stageY <= rc.stage.profit.bottom ) {
109
-
110
- window.window.visible = true;
111
-
112
- infoLayer.x = ev.stageX > rc.stage.candle.right - WIDTH -10 ? ev.stageX-15-WIDTH : ev.stageX+15;
113
- infoLayer.y = ev.stageY > rc.stage.profit.bottom - HEIGHT -10 ? ev.stageY-15-HEIGHT : ev.stageY+15;
114
-
115
- var daten:Number = model.positionManager.toDate(ev.stageX-rc.stage.candle.left-2);
116
- daten = Math.ceil( daten / model.scaleTime ) * model.scaleTime;
117
-
118
- // x,y
119
- var date:Date = new Date();
120
- date.setTime( daten*1000 );
121
- textFields["x"].text = Util.formatDate( date );
122
- if ( ev.stageY < rc.stage.candle.bottom ) {
123
- var rate:Number = model.positionManager.toRate(
124
- rc.stage.candle.bottom - ev.stageY, rc.stage.candle.height);
125
- var l:int = 5 - (rate == 0 ? 1 : Math.log(rate)*Math.LOG10E);
126
- textFields["y"].text = rate.toFixed(l);
127
- } else if ( ev.stageY > rc.stage.profit.top ) {
128
- var profit:Number = model.positionManager.toProfit(
129
- rc.stage.profit.bottom - ev.stageY, rc.stage.profit.height);
130
- textFields["y"].text = Math.ceil(profit/100)*100;
101
+ public function setPosition( x:int, y:int ):void {
102
+ var stageWidth:int = rc.stage.width;
103
+ var stageHeight:int = rc.stage.height;
104
+ if ( model.rateDatas &&
105
+ x >= rc.stage.candle.left+1 &&
106
+ x < rc.stage.candle.right &&
107
+ y > rc.stage.candle.top &&
108
+ y <= rc.stage.profit.bottom ) {
109
+
110
+ window.window.visible = true;
111
+
112
+ infoLayer.x = x > rc.stage.candle.right - WIDTH -10 ? x-15-WIDTH : x+15;
113
+ infoLayer.y = y > rc.stage.profit.bottom - HEIGHT -10 ? y-15-HEIGHT : y+15;
114
+
115
+ var daten:Number = model.positionManager.toDate(x-rc.stage.candle.left-2);
116
+ daten = Math.ceil( daten / model.scaleTime ) * model.scaleTime;
117
+
118
+ // x,y
119
+ var date:Date = new Date();
120
+ date.setTime( daten*1000 );
121
+ textFields["x"].text = Util.formatDate( date );
122
+ if ( y < rc.stage.candle.bottom ) {
123
+ var rate:Number = model.positionManager.toRate(
124
+ rc.stage.candle.bottom - y, rc.stage.candle.height);
125
+ var l:int = 5 - (rate == 0 ? 1 : Math.log(rate)*Math.LOG10E);
126
+ textFields["y"].text = rate.toFixed(l);
127
+ } else if ( y > rc.stage.profit.top ) {
128
+ var profit:Number = model.positionManager.toProfit(
129
+ rc.stage.profit.bottom - y, rc.stage.profit.height);
130
+ textFields["y"].text = Math.ceil(profit/100)*100;
131
+ } else {
132
+ textFields["y"].text = "-";
133
+ }
134
+
135
+ // レート
136
+ updateRate( daten );
137
+
138
+ // 収益
139
+ updateProfit(daten);
140
+
131
141
  } else {
132
- textFields["y"].text = "-";
142
+ window.window.visible = false;
133
143
  }
134
-
135
- // レート
136
- updateRate( daten );
137
-
138
- // 収益
139
- updateProfit(daten);
140
-
141
- } else {
142
- window.window.visible = false;
143
- }
144
+ }
145
+
146
+ public function onMouseMove( ev:MouseEvent ):void {
147
+ setPosition(ev.stageX, ev.stageY)
144
148
  }
145
149
  private function updateRate( date:Number ):void {
146
150
  if ( model.rateDatas ) {
@@ -48,11 +48,13 @@ package fx.chart.ui {
48
48
  // イベントをキャプチャ
49
49
  pointerLayer.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
50
50
  }
51
-
51
+ public function setPosition( x:int, y:int ):void {
52
+ pointerLayerY.x = x;
53
+ pointerLayerX.y = y;
54
+ informationWindow.setPosition(x,y);
55
+ }
52
56
  private function onMouseMove( ev:MouseEvent ):void {
53
- pointerLayerY.x = ev.stageX;
54
- pointerLayerX.y = ev.stageY;
55
- informationWindow.onMouseMove(ev);
57
+ setPosition( ev.stageX, ev.stageY );
56
58
  }
57
59
  }
58
60
 
@@ -139,8 +139,9 @@ package fx.chart.ui {
139
139
  if ( scrollMax <= scrollMin ) {
140
140
  // 移動後の範囲が、表示可能範囲外
141
141
  // スクロール不可
142
- step = 0;
143
- positionLeft = scroll.positionLeft;
142
+ // step = 0;
143
+ // positionLeft = scroll.positionLeft;
144
+ return;
144
145
  } else if ( scrollMax <= step ) {
145
146
  step = scrollMax;
146
147
  positionLeft = 0;
@@ -12,7 +12,7 @@ package fx.chart.ui {
12
12
  /** コントローラー */
13
13
  public static const CONTROLLER:Number = 30;
14
14
  /** グラフ表示領域 */
15
- public static const GRAPH:Number = 70;
15
+ public static const GRAPH:Number = 80;
16
16
  /** トレード結果表示領域 */
17
17
  public static const TRADE:Number = 40;
18
18
  /** X軸 */
@@ -72,9 +72,9 @@ package fx.chart.ui {
72
72
  height - (PADDING+PROFIT+X_AXIS+GRAPH+PADDING+CONTROLLER) );
73
73
  graph = new Rectangle(
74
74
  PADDING_LEFT,
75
- height - (PADDING+PROFIT+X_AXIS+GRAPH) -50 ,
75
+ height - (PADDING+PROFIT+X_AXIS+GRAPH) ,
76
76
  width - PADDING - PADDING_LEFT,
77
- GRAPH + 50 );
77
+ GRAPH );
78
78
  xAxis = new Rectangle(
79
79
  PADDING_LEFT,
80
80
  height - (PADDING+PROFIT+X_AXIS),
@@ -13,7 +13,7 @@ package fx.chart.ui {
13
13
  public class TradeDetailWindow extends AbstractChartUI {
14
14
 
15
15
  private static const WIDTH:int = 230;
16
- private static const HEIGHT:int = 100;
16
+ private static const HEIGHT:int = 117;
17
17
 
18
18
  private var infoLayer:Sprite;
19
19
  private var window:Window;
@@ -40,21 +40,21 @@ package fx.chart.ui {
40
40
 
41
41
  var g:Graphics = window.window.graphics;
42
42
 
43
- g.lineStyle( 0, 0xE3E3E0, 1,
43
+ g.lineStyle( 0, 0xD3D3D0, 1,
44
44
  true, LineScaleMode.NONE, CapsStyle.NONE, JointStyle.BEVEL );
45
45
  g.moveTo( 10, 35 );
46
46
  g.lineTo( WIDTH-10, 35 );
47
- g.moveTo( 10, 60 );
48
- g.lineTo( WIDTH-10, 60 );
47
+ g.moveTo( 10, 77 );
48
+ g.lineTo( WIDTH-10, 75 );
49
49
 
50
50
  // 最初は非表示
51
51
  infoLayer.visible = false;
52
52
 
53
53
  textFields["result"] = createTextField( 10,5,220,24,Constants.TEXT_FORMAT_TINFO_PROFIT_UP );
54
54
  textFields["info"] = createTextField( 40,40,180,15,Constants.TEXT_FORMAT_TINFO_INFO );
55
-
55
+ textFields["trader"] = createTextField( 10,57,180,15,Constants.TEXT_FORMAT_INFO_BASIC_L );
56
56
  (["start","end"]).forEach( function( item:*,i:int,arr:Array ):void{
57
- textFields[item] = createTextField( 40,63+i*15,190,15,Constants.TEXT_FORMAT_INFO_BASIC_L );
57
+ textFields[item] = createTextField( 40,80+i*15,190,15,Constants.TEXT_FORMAT_INFO_BASIC_L );
58
58
  } );
59
59
 
60
60
  sell = new Constants.ICON_SELL();
@@ -71,7 +71,7 @@ package fx.chart.ui {
71
71
  var end:Bitmap = new Constants.ICON_END_LABEL();
72
72
  ([start,end]).forEach( function( item:*,i:int,arr:Array ):void{
73
73
  item.x = 11;
74
- item.y = 66+i*15;
74
+ item.y = 82+i*15;
75
75
  window.window.addChild( item );
76
76
  } );
77
77
 
@@ -112,7 +112,8 @@ package fx.chart.ui {
112
112
  sell.visible = false;
113
113
  buy.visible = true;
114
114
  }
115
- textFields["info"].text = " / " + d["pair"] + " / " + int( d["price"] / d["rate"])
115
+ textFields["trader"].text = d["trader"] ? d["trader"] : "-";
116
+ textFields["info"].text = " / " + d["pair"] + " / " + int( d["price"] / d["rate"]);
116
117
  textFields["start"].text = d["rate"] + " " + formatDate( d["date"] );
117
118
  if ( d["fix_rate"] && d["fix_date"] ) {
118
119
  textFields["end"].text = d["fix_rate"] + " " + formatDate( d["fix_date"] );
@@ -198,14 +198,7 @@ package fx.chart.ui {
198
198
  var middle:int = profit.top + profit.height/2;
199
199
 
200
200
  // 0
201
- var zero:TextField = new TextField();
202
- zero.selectable = false;
203
- zero.text = "0";
204
- zero.width = profit.left-1;
205
- zero.setTextFormat( Constants.TEXT_FORMAT_SCALE_Y );
206
- zero.y = middle-7;
207
- zero.x = 0;
208
- axis.addChild(zero);
201
+ createText( "0", axis, Constants.TEXT_FORMAT_SCALE_Y, 0, middle-8, profit.left-2 );
209
202
 
210
203
  // 背景
211
204
  // axis.graphics.lineStyle( 0, Constants.COLOR_AXIS_HI );
@@ -238,14 +231,7 @@ package fx.chart.ui {
238
231
  lowAxis.graphics.moveTo( rc.stage.candle.left+1, y );
239
232
  lowAxis.graphics.lineTo( rc.stage.candle.right, y );
240
233
 
241
- var scaleText:TextField = new TextField();
242
- scaleText.selectable = false;
243
- scaleText.text = tmp.toString();
244
- scaleText.width = rc.stage.candle.left;
245
- scaleText.setTextFormat( Constants.TEXT_FORMAT_SCALE_Y );
246
- scaleText.y = y-7;
247
- scaleText.x = 0;
248
- axis.addChild(scaleText);
234
+ createText( tmp.toString(), axis, Constants.TEXT_FORMAT_SCALE_Y, 0, y-8, rc.stage.candle.left-2 );
249
235
  }
250
236
 
251
237
 
@@ -328,7 +314,7 @@ class Slot {
328
314
  public function add( trade:Object ):void {
329
315
  data.push( trade );
330
316
  last = trade.fix_date;
331
- log("last:" + String(last) )
317
+ //log("last:" + String(last) )
332
318
  }
333
319
  }
334
320