OmegaChartのソースコードの保守
Rev. | abec95183e38adccdd3ae834f0e303862ebeff62 |
---|---|
크기 | 24,614 bytes |
Time | 2022-12-15 22:48:19 |
Author | panacoran |
Log Message | Yahooファイナンスからの株価取得が途中で止まるのを回避
|
/*
* Copyright (c) Daisuke OKAJIMA All rights reserved.
*
* $Id$
*/
// This file is modified by panacoran.
// Copyright (C) 2013 panacoran <panacoran@users.sourceforge.jp>
// This program is part of OmegaChart.
// OmegaChart is licensed under the Apache License, Version 2.0.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text;
using Travis.Util;
using Zanetti.Data;
using Zanetti.Indicators;
using Zanetti.SystemTrading;
using Zanetti.SystemTrading.AutoTrading;
using Zanetti.Config; // for BookmarkFolder
namespace Zanetti.Forms {
internal class AutoTradingDialog : System.Windows.Forms.Form {
private static readonly int[] _signalCountValues = new int[] { 100,1000,Int32.MaxValue };
private static AutoTradingExecutor _prevExecutor; //パラメータ保存用
private AutoTradingExecutor _executor;
private int _currentBrandIndex;
private System.Windows.Forms.Button _okButton;
private System.Windows.Forms.Button _cancelButton;
private System.Windows.Forms.GroupBox _filterGroup;
private System.Windows.Forms.Label _messageLabel;
private System.Windows.Forms.Label _filterLabel;
private System.Windows.Forms.ComboBox _filterBox;
private System.Windows.Forms.GroupBox _autoTradingItemGroup;
private System.Windows.Forms.Label _lCondition;
private System.Windows.Forms.Label _autoTradingItemLabel;
private System.Windows.Forms.ComboBox _autoTradingItemBox;
private System.Windows.Forms.GroupBox _dateGroup;
private System.Windows.Forms.Label _startDateLabel;
private System.Windows.Forms.DateTimePicker _startDatePicker;
private System.Windows.Forms.Label _endDateLabel;
private System.Windows.Forms.DateTimePicker _endDatePicker;
private System.Windows.Forms.Label _signalCountLabel;
private System.Windows.Forms.ComboBox _signalCountBox;
private System.Windows.Forms.ProgressBar _progressBar;
private System.Windows.Forms.ComboBox _favoriteBox;
private System.Windows.Forms.Button _specBookmarkFolderButton;
private System.Windows.Forms.TextBox _bookmarkFolderTextBox;
private System.Windows.Forms.Label _filterBookmarkLabel;
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
private System.ComponentModel.Container components = null;
private BookmarkFolder _bookmarkFolder;
public AutoTradingDialog() {
//
// Windows フォーム デザイナ サポートに必要です。
//
InitializeComponent();
//
// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
//
InitUI();
}
public AutoTradingResult Result {
get {
return _executor==null? null : _executor.Result as AutoTradingResult;
}
}
/// <summary>
/// 使用されているリソースに後処理を実行します。
/// </summary>
protected override void Dispose( bool disposing ) {
if( disposing ) {
if(components != null) {
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows フォーム デザイナで生成されたコード
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
private void InitializeComponent() {
this._filterGroup = new System.Windows.Forms.GroupBox();
this._specBookmarkFolderButton = new System.Windows.Forms.Button();
this._bookmarkFolderTextBox = new System.Windows.Forms.TextBox();
this._filterBookmarkLabel = new System.Windows.Forms.Label();
this._filterBox = new System.Windows.Forms.ComboBox();
this._filterLabel = new System.Windows.Forms.Label();
this._messageLabel = new System.Windows.Forms.Label();
this._favoriteBox = new System.Windows.Forms.ComboBox();
this._autoTradingItemGroup = new System.Windows.Forms.GroupBox();
this._lCondition = new System.Windows.Forms.Label();
this._autoTradingItemBox = new System.Windows.Forms.ComboBox();
this._autoTradingItemLabel = new System.Windows.Forms.Label();
this._dateGroup = new System.Windows.Forms.GroupBox();
this._startDateLabel = new System.Windows.Forms.Label();
this._startDatePicker = new System.Windows.Forms.DateTimePicker();
this._endDateLabel = new System.Windows.Forms.Label();
this._endDatePicker = new System.Windows.Forms.DateTimePicker();
this._signalCountLabel = new System.Windows.Forms.Label();
this._signalCountBox = new System.Windows.Forms.ComboBox();
this._progressBar = new System.Windows.Forms.ProgressBar();
this._okButton = new System.Windows.Forms.Button();
this._cancelButton = new System.Windows.Forms.Button();
this._filterGroup.SuspendLayout();
this._autoTradingItemGroup.SuspendLayout();
this._dateGroup.SuspendLayout();
this.SuspendLayout();
//
// _filterGroup
//
this._filterGroup.Controls.Add(this._specBookmarkFolderButton);
this._filterGroup.Controls.Add(this._bookmarkFolderTextBox);
this._filterGroup.Controls.Add(this._filterBookmarkLabel);
this._filterGroup.Controls.Add(this._filterBox);
this._filterGroup.Controls.Add(this._filterLabel);
this._filterGroup.Controls.Add(this._messageLabel);
this._filterGroup.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._filterGroup.Location = new System.Drawing.Point(8, 8);
this._filterGroup.Name = "_filterGroup";
this._filterGroup.Size = new System.Drawing.Size(464, 96);
this._filterGroup.TabIndex = 0;
this._filterGroup.TabStop = false;
this._filterGroup.Text = "1 対象設定";
//
// _specBookmarkFolderButton
//
this._specBookmarkFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._specBookmarkFolderButton.Location = new System.Drawing.Point(368, 64);
this._specBookmarkFolderButton.Name = "_specBookmarkFolderButton";
this._specBookmarkFolderButton.Size = new System.Drawing.Size(80, 24);
this._specBookmarkFolderButton.TabIndex = 6;
this._specBookmarkFolderButton.Text = "フォルダ指定";
this._specBookmarkFolderButton.Click += new System.EventHandler(this.OnSelectBookmarkFolder);
//
// _bookmarkFolderTextBox
//
this._bookmarkFolderTextBox.Location = new System.Drawing.Point(136, 64);
this._bookmarkFolderTextBox.Name = "_bookmarkFolderTextBox";
this._bookmarkFolderTextBox.ReadOnly = true;
this._bookmarkFolderTextBox.Size = new System.Drawing.Size(224, 19);
this._bookmarkFolderTextBox.TabIndex = 5;
//
// _filterBookmarkLabel
//
this._filterBookmarkLabel.Location = new System.Drawing.Point(24, 64);
this._filterBookmarkLabel.Name = "_filterBookmarkLabel";
this._filterBookmarkLabel.Size = new System.Drawing.Size(72, 16);
this._filterBookmarkLabel.TabIndex = 4;
this._filterBookmarkLabel.Text = "お気に入り(&T)";
this._filterBookmarkLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _filterBox
//
this._filterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this._filterBox.Location = new System.Drawing.Point(136, 40);
this._filterBox.Name = "_filterBox";
this._filterBox.Size = new System.Drawing.Size(224, 20);
this._filterBox.TabIndex = 3;
this._filterBox.SelectedIndexChanged += new System.EventHandler(this.OnFilterBoxChanged);
//
// _filterLabel
//
this._filterLabel.Location = new System.Drawing.Point(24, 40);
this._filterLabel.Name = "_filterLabel";
this._filterLabel.Size = new System.Drawing.Size(64, 16);
this._filterLabel.TabIndex = 2;
this._filterLabel.Text = "対象(&F)";
this._filterLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _messageLabel
//
this._messageLabel.Location = new System.Drawing.Point(16, 16);
this._messageLabel.Name = "_messageLabel";
this._messageLabel.Size = new System.Drawing.Size(432, 16);
this._messageLabel.TabIndex = 1;
this._messageLabel.Text = "まず検索対象を決めます。ここでの対象銘柄数が少ないほど高速に結果が得られます。";
//
// _favoriteBox
//
this._favoriteBox.Location = new System.Drawing.Point(0, 0);
this._favoriteBox.Name = "_favoriteBox";
this._favoriteBox.Size = new System.Drawing.Size(121, 20);
this._favoriteBox.TabIndex = 0;
//
// _autoTradingItemGroup
//
this._autoTradingItemGroup.Controls.Add(this._lCondition);
this._autoTradingItemGroup.Controls.Add(this._autoTradingItemBox);
this._autoTradingItemGroup.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._autoTradingItemGroup.Location = new System.Drawing.Point(8, 112);
this._autoTradingItemGroup.Name = "_autoTradingItemGroup";
this._autoTradingItemGroup.Size = new System.Drawing.Size(464, 72);
this._autoTradingItemGroup.TabIndex = 4;
this._autoTradingItemGroup.TabStop = false;
this._autoTradingItemGroup.Text = "2 自動売買ルールの選択";
//
// _lCondition
//
this._lCondition.Location = new System.Drawing.Point(16, 16);
this._lCondition.Name = "_lCondition";
this._lCondition.Size = new System.Drawing.Size(416, 23);
this._lCondition.TabIndex = 5;
this._lCondition.Text = "自動売買ルールは拡張キットによって追加することができます。また売買は条件成立日の終値で行ったものとして計算されます。";
this._lCondition.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _autoTradingItemBox
//
this._autoTradingItemBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this._autoTradingItemBox.Location = new System.Drawing.Point(16, 40);
this._autoTradingItemBox.Name = "_autoTradingItemBox";
this._autoTradingItemBox.Size = new System.Drawing.Size(416, 20);
this._autoTradingItemBox.TabIndex = 7;
//
// _autoTradingItemLabel
//
this._autoTradingItemLabel.Location = new System.Drawing.Point(0, 0);
this._autoTradingItemLabel.Name = "_autoTradingItemLabel";
this._autoTradingItemLabel.Size = new System.Drawing.Size(100, 23);
this._autoTradingItemLabel.TabIndex = 0;
//
// _dateGroup
//
this._dateGroup.Controls.Add(this._startDateLabel);
this._dateGroup.Controls.Add(this._startDatePicker);
this._dateGroup.Controls.Add(this._endDateLabel);
this._dateGroup.Controls.Add(this._endDatePicker);
this._dateGroup.Controls.Add(this._signalCountLabel);
this._dateGroup.Controls.Add(this._signalCountBox);
this._dateGroup.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._dateGroup.Location = new System.Drawing.Point(8, 192);
this._dateGroup.Name = "_dateGroup";
this._dateGroup.Size = new System.Drawing.Size(464, 120);
this._dateGroup.TabIndex = 10;
this._dateGroup.TabStop = false;
this._dateGroup.Text = "3 対象期間など";
//
// _startDateLabel
//
this._startDateLabel.Location = new System.Drawing.Point(8, 16);
this._startDateLabel.Name = "_startDateLabel";
this._startDateLabel.Size = new System.Drawing.Size(64, 24);
this._startDateLabel.TabIndex = 0;
this._startDateLabel.Text = "開始日";
this._startDateLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _startDatePicker
//
this._startDatePicker.Checked = false;
this._startDatePicker.Location = new System.Drawing.Point(80, 16);
this._startDatePicker.Name = "_startDatePicker";
this._startDatePicker.Size = new System.Drawing.Size(200, 19);
this._startDatePicker.TabIndex = 1;
this._startDatePicker.ValueChanged += new System.EventHandler(this.OnStartDateChanged);
//
// _endDateLabel
//
this._endDateLabel.Location = new System.Drawing.Point(8, 40);
this._endDateLabel.Name = "_endDateLabel";
this._endDateLabel.Size = new System.Drawing.Size(64, 24);
this._endDateLabel.TabIndex = 2;
this._endDateLabel.Text = "終了日";
this._endDateLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _endDatePicker
//
this._endDatePicker.Location = new System.Drawing.Point(80, 40);
this._endDatePicker.Name = "_endDatePicker";
this._endDatePicker.Size = new System.Drawing.Size(200, 19);
this._endDatePicker.TabIndex = 3;
this._endDatePicker.Value = new System.DateTime(2010, 12, 31, 0, 0, 0, 0);
this._endDatePicker.ValueChanged += new System.EventHandler(this.OnEndDateChanged);
//
// _signalCountLabel
//
this._signalCountLabel.Location = new System.Drawing.Point(8, 64);
this._signalCountLabel.Name = "_signalCountLabel";
this._signalCountLabel.Size = new System.Drawing.Size(184, 24);
this._signalCountLabel.TabIndex = 4;
this._signalCountLabel.Text = "検索を打ち切るシグナル発生数(&S)";
this._signalCountLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// _signalCountBox
//
this._signalCountBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this._signalCountBox.Location = new System.Drawing.Point(192, 64);
this._signalCountBox.Name = "_signalCountBox";
this._signalCountBox.Size = new System.Drawing.Size(88, 20);
this._signalCountBox.TabIndex = 5;
//
// _progressBar
//
this._progressBar.Location = new System.Drawing.Point(8, 328);
this._progressBar.Name = "_progressBar";
this._progressBar.Size = new System.Drawing.Size(464, 23);
this._progressBar.TabIndex = 14;
//
// _okButton
//
this._okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
this._okButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._okButton.Location = new System.Drawing.Point(312, 360);
this._okButton.Name = "_okButton";
this._okButton.Size = new System.Drawing.Size(75, 23);
this._okButton.TabIndex = 15;
this._okButton.Text = "OK";
this._okButton.Click += new System.EventHandler(this.OnOK);
//
// _cancelButton
//
this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this._cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._cancelButton.Location = new System.Drawing.Point(400, 360);
this._cancelButton.Name = "_cancelButton";
this._cancelButton.Size = new System.Drawing.Size(75, 23);
this._cancelButton.TabIndex = 16;
this._cancelButton.Text = "キャンセル";
this._cancelButton.Click += new System.EventHandler(this.OnCancel);
//
// AutoTradingDialog
//
this.AcceptButton = this._okButton;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.CancelButton = this._cancelButton;
this.ClientSize = new System.Drawing.Size(482, 384);
this.Controls.Add(this._dateGroup);
this.Controls.Add(this._autoTradingItemGroup);
this.Controls.Add(this._progressBar);
this.Controls.Add(this._filterGroup);
this.Controls.Add(this._cancelButton);
this.Controls.Add(this._okButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AutoTradingDialog";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "自動売買ルール検証";
this._filterGroup.ResumeLayout(false);
this._filterGroup.PerformLayout();
this._autoTradingItemGroup.ResumeLayout(false);
this._dateGroup.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private void InitUI() {
if(_prevExecutor!=null) {
_startDatePicker.Value = Util.IntToDate(_prevExecutor.StartDate);
_endDatePicker.Value = Util.IntToDate(_prevExecutor.EndDate);
}
else {
DateTime ld = Util.GuessLatestTradeDate();
if(ld==DateTime.Today && DateTime.Now.Hour<17) {
ld = ld.AddDays(-1);
while(!Util.IsMarketOpenDate(ld)) ld = ld.AddDays(-1); //市場が開いている日の17時以前はデータ取れない
}
_endDatePicker.Value = ld;
ld = ld.AddYears(-1);
_startDatePicker.Value = ld;
}
AutoTradingItem[] target = Env.CurrentIndicators.AutoTradingItems;
for(int i=0; i<target.Length; i++) {
AutoTradingItem item = target[i];
_autoTradingItemBox.Items.Add(item.Header);
//if(o!=null && o.PrimaryItem==target[i])
// si = i;
}
if(_prevExecutor!=null) {
_autoTradingItemBox.SelectedIndex = _autoTradingItemBox.FindStringExact(_prevExecutor.Item.Header);
}
else
_autoTradingItemBox.SelectedIndex = 0;
_filterBox.Items.AddRange(EnumDescAttribute.For(typeof(FilterType)).DescriptionCollection());
_currentBrandIndex = _filterBox.Items.Count;
_filterBox.Items.Add(String.Format("現在表示している銘柄({0})", Env.Frame.ChartCanvas.GetBrand().Name));
if(_prevExecutor!=null) {
FilteredBrandEnumerator e = _prevExecutor.BrandEnumerator as FilteredBrandEnumerator;
_filterBox.SelectedIndex = e==null? _currentBrandIndex : (int)e.FilterType;
}
else
_filterBox.SelectedIndex = _currentBrandIndex;
for(int i=0; i<_signalCountValues.Length; i++) {
_signalCountBox.Items.Add(_signalCountValues[i]==Int32.MaxValue? "無制限" : _signalCountValues[i].ToString());
if(_prevExecutor!=null && _signalCountValues[i]==_prevExecutor.SignalCountLimit)
_signalCountBox.SelectedIndex = i;
}
if(_signalCountBox.SelectedIndex==-1)
_signalCountBox.SelectedIndex = 0;
}
private void OnOK(object sender, EventArgs args) {
this.DialogResult = DialogResult.None;
_executor = CreateExecutor();
if(_executor==null) return;
_okButton.Enabled = false;
_filterBox.Enabled = false;
_autoTradingItemBox.Enabled = false;
_startDatePicker.Enabled = false;
_endDatePicker.Enabled = false;
_signalCountBox.Enabled = false;
//!!これでは範囲がはみ出てしまうことがあった。派生銘柄や為替の対応などをしているうちにこのあたりの管理がおかしくなっているみたいだ
_progressBar.Maximum = _executor.BrandEnumerator.Count;
_progressBar.Value = 0;
_progressBar.Enabled = true;
this.Cursor = Cursors.AppStarting;
_executor.AsyncExecute(this.Handle);
}
private void OnCancel(object sender, EventArgs args) {
if(_executor!=null) {
_executor.Abort();
}
}
private void OnStartDateChanged(object sender, EventArgs args) {
}
private void OnEndDateChanged(object sender, EventArgs args) {
}
private AutoTradingExecutor CreateExecutor() {
if(_startDatePicker.Value.CompareTo(DateTime.Today)>0) {
Util.Warning(this, "開始日が未来です。");
return null;
}
if(_endDatePicker.Value.CompareTo(DateTime.Today)>0) {
Util.Warning(this, "終了日が未来です。");
return null;
}
if(_startDatePicker.Value.CompareTo(_endDatePicker.Value)>0) {
Util.Warning(this, "終了日が開始日の先に設定されています。");
return null;
}
AutoTradingItem[] items = Env.CurrentIndicators.AutoTradingItems;
int pr = _autoTradingItemBox.SelectedIndex;
AutoTradingExecutor ex = new AutoTradingExecutor(items[pr], Util.DateToInt(_startDatePicker.Value), Util.DateToInt(_endDatePicker.Value), _signalCountValues[_signalCountBox.SelectedIndex]);
if(_filterBox.SelectedIndex == _currentBrandIndex) {
ex.BrandEnumerator = new SingleBrandEnumerator(Env.Frame.ChartCanvas.GetBrand());
}
else {
FilterType filter = (FilterType)_filterBox.SelectedIndex;
if(filter == FilterType.Favorite){
if(_bookmarkFolder==null){
Util.Warning(this, "ブックマークのフォルダを指定してください。");
return null;
}
ex.BrandEnumerator = new BookmarkedBrandEnumerator(_bookmarkFolder);
}
else
ex.BrandEnumerator = new FilteredBrandEnumerator(filter);
}
return ex;
}
private void ExitSuccessFully() {
this.DialogResult = DialogResult.OK;
this.Cursor = Cursors.Default;
AutoTradingResult r = _executor.Result as AutoTradingResult;
_prevExecutor = _executor; //次回実行で使用
StringBuilder msg = new StringBuilder();
if(r.HasTooManuResults) {
Util.Warning(this, String.Format("シグナル発生数が制限に達したため途中で打ち切りました。条件や範囲を見直してください。"));
}
else {
if(r.CheckedBrandCount > 1) {
if(r.DataErrorBrands.Count==0) {
msg.AppendFormat("検証が完了しました。\n対象銘柄数は {0} でした。\n", r.CheckedBrandCount);
}
else {
msg.AppendFormat("検証が完了しました。\n対象銘柄数 {0} のうち、\n対象日付のデータがなかった {1} 銘柄", r.CheckedBrandCount, r.DataErrorBrands.Count);
if(r.DataErrorBrands.Count <= 10) {
for(int i=0; i<r.DataErrorBrands.Count; i++) {
if(i > 0) msg.Append(", ");
msg.Append((r.DataErrorBrands[i] as BasicBrand).Code.ToString());
}
}
msg.Append("は除外されました。");
}
Util.Information(this, msg.ToString());
}
}
Close();
}
protected override void WndProc(ref Message m) {
base.WndProc (ref m);
if(m.Msg==AsyncConst.WM_ASYNCPROCESS) {
if(m.LParam.ToInt32()==AsyncConst.LPARAM_PROGRESS_SUCCESSFUL || m.LParam.ToInt32()==AsyncConst.LPARAM_PROGRESS_FAILURE) {
if(_progressBar.Value<_progressBar.Maximum) _progressBar.Value++;
}
else if(m.LParam.ToInt32()==AsyncConst.LPARAM_FINISHED)
ExitSuccessFully();
else if(m.LParam.ToInt32()==AsyncConst.LPARAM_ERROR) {
this.Cursor = Cursors.Default;
_executor.Abort();
Util.Warning(this, _executor.ErrorMessage);
this.DialogResult = DialogResult.Abort;
Close();
}
}
}
private void OnSelectBookmarkFolder(object sender, System.EventArgs e){
SelectBookmarkFolder dlg = new SelectBookmarkFolder();
if(dlg.ShowDialog(Env.Frame)==DialogResult.OK){
_bookmarkFolder = dlg.ResultFolder;
_bookmarkFolderTextBox.Text = _bookmarkFolder.Name;
}
}
private void OnFilterBoxChanged(object sender, System.EventArgs e){
bool en = ((FilterType)_filterBox.SelectedIndex == FilterType.Favorite);
_bookmarkFolderTextBox.Enabled = en;
_specBookmarkFolderButton.Enabled = en;
}
}
}