unageanu-jiji 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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