/// <summary> /// もし404エラー(接続切れ)になっていたらログインを再度行う /// </summary> public void RetryLogin() { try { // エラーになっていないかどうか確認 見つかった場合は何もしない this.IsActivate(); if (this.chrome.IsFindElementById("header")) { return; } // 見つからない場合はログインしなおし TODO:デモと本番の切り替えられるようにする chrome.Navigate().Refresh(); chrome.WaitCompleteDelay(1000); // 歓迎ボタンを押す IWebElement welcomeBtn = CommonDriverControl. GetSafeWebElementByXPath(this.chrome, Constants.XPATH_HL_Welcome_Button); welcomeBtn.Click(); CommonControl.SleepWait(1000); CommonControl.DebugPrint("リフレッシュした。"); } catch (Exception e) { CommonControl.DebugPrint(e, "RetryLogin"); } }
/// <summary> /// 【シグナルメッセージ専用】 /// 対象の部屋にメッセージを書き込む /// </summary> /// <param name="toWriteRoomName">書き込む対象の部屋名</param> /// <param name="signalRoomName">実際に来たシグナルの部屋</param> /// <param name="argMsg">メッセージ</param> public void putSignalMsgToRoom(string toWriteRoomName, string signalRoomName, string argMsg) { try { // LINEをアクティブに this.chrome.SwitchWindowLine(); // 対象の部屋をアクティブに RoomAvtive(toWriteRoomName); // メッセージを書き込む IWebElement msgInputTxtBox = this.chrome.FindElementById("_chat_room_input"); msgInputTxtBox.Click(); // フォーカスあてる代わり //CommonControl.SleepWait(2000); msgInputTxtBox.SendKeys(signalRoomName); System.Windows.Forms.SendKeys.SendWait("+~"); // Shift + Enter string[] aryMsg = argMsg.Split(new string[] { Constants.LINE_CRLF }, StringSplitOptions.None); for (int i = 0; i < aryMsg.Length; i++) { msgInputTxtBox.SendKeys(aryMsg[i]); System.Windows.Forms.SendKeys.SendWait("+~"); // Shift + Enter } CommonControl.SleepWait(500); msgInputTxtBox.SendKeys(Keys.Enter); // 送信 } catch (Exception e) { CommonControl.DebugPrint(e, "メッセージの送信に失敗しました"); } }
/// <summary> /// 【デモ版】ハイローにログインする /// </summary> public void demoLogin() { // デモログインボタン 見つかるまで IWebElement demoLoginLink = CommonDriverControl.GetSafeWebElementByXPath( chrome, "//*[@id='header']/div/div/div/div/div/span/span/a[1]"); demoLoginLink.Click(); this.chrome.WaitCompleteDelay(3000); // 歓迎ボタンを押す IWebElement welcomeBtn = CommonDriverControl. GetSafeWebElementByXPath(this.chrome, Constants.XPATH_HL_Welcome_Button); welcomeBtn.Click(); CommonControl.SleepWait(500); }
/// <summary> /// ラインにログインする /// </summary> public void LoginLINE(String address, String passWord) { try { this.chrome.Url = Constants.URL_LINE_Index; // TODO:空白ぺージを完全と誤って判断している? 読み込み待ち用 chrome.WaitCompleteDelay(1000); // ラインのハンドルをキープ Constants.CHROME_HANDLE_LINE = chrome.CurrentWindowHandle; // アドレス 一回入力すれば、プロファイルから省略可 //IWebElement eleAdrs = this.chrome.FindElementById("line_login_email"); //eleAdrs.SendKeys(address); // パス IWebElement eleLoginPwd = CommonDriverControl.GetSafeWebElementById(this.chrome, "line_login_pwd"); eleLoginPwd.SendKeys(passWord); Thread.Sleep(500); // ログイン IWebElement eleLoginBtn = CommonDriverControl.GetSafeWebElementById(this.chrome, "login_btn"); eleLoginBtn.Click(); // 部屋名が現れるまで待つ CommonControl.SleepWait(1000); CommonDriverControl.WaitElementArrivalById(this.chrome, Constants.HTML_ID_LINE_ChatRoomDivId); // TODO:LINEの読み込み処理を完全に待つ方法がわからない this.chrome.WaitCompleteDelay(2000); // 部屋リストを最後までスクロールして部屋名リストを全部読みこむ ChatRoomListScrollEnd(); CommonControl.SleepWait(300); ChatRoomListScrollTop(); CommonControl.SleepWait(500); } catch (Exception e) { throw e; } }
/// <summary> /// 【正規版】本番にログインを行う /// </summary> public void Login() { try { //// ログインボタンを押す IWebElement loginBtn = CommonDriverControl.GetSafeWebElementByXPath( this.chrome, "//*[@id='header']/div/div/div/div/div/span/span/a[2]"); loginBtn.Click(); // ログイン後、ロードが走る場合があるのでそれを考慮 CommonControl.SleepWait(2000); // ログインID IWebElement eleLoginId = CommonDriverControl. GetSafeWebElementById(this.chrome, "login-username"); eleLoginId.SendKeys(Constants.Login_HL_ID); CommonControl.SleepWait(500); // ログインパスワード IWebElement eleLoginPassWord = CommonDriverControl. GetSafeWebElementById(this.chrome, "login-password"); eleLoginPassWord.SendKeys(Constants.Login_HL_PassWord); CommonControl.SleepWait(500); // なんかログインボタンがうまく取れないのでエンターで代用 eleLoginPassWord.SendKeys("\r\n"); //// ログインボタン 押下 //IWebElement eleLoginTriggerBtn = CommonDriverControl. // GetSafeWebElementByXPath(this.chrome, "//*[@id='signin - popup']/div[1]/div/div[2]/div[1]/form/div/div[6]"); //eleLoginTriggerBtn.Click(); } catch (Exception e) { // 何らかの原因でログインに失敗した CommonControl.DebugPrint(e, "HighLow Login"); throw; } }
static void Main(string[] args) { //ForDebugOnly(); // デバッグ用関数 //return; try { // ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== // 起動準備 & 引数用意 // ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== // パラメータ設定の初期化(取得) Constants.Initialize(); // ブラウザ立ち上げ ChromeDriverEx chrome = CreateNewChromeDriver(); // 経済指標を取得 //InvestingCalender InvC = new InvestingCalender(ref chrome); //InvC.GetInvestingCalender(); //// LINE用 LINEControl cLINE = new LINEControl(ref chrome); // ログイン ライン cLINE.LoginLINE(); //// 初回ログイン時はログイン情報だけを記憶させて終了 //if (Constants.Login_Line_First) return; //// highlow 本トレ HighLowControl cHighLow_Real = new HighLowControl(ref chrome); cHighLow_Real.Open(false); // 本番OPEN cHighLow_Real.Login(); // 本トレログイン ///// highlowデモ HighLowControl cHighLow_Demo = new HighLowControl(ref chrome); cHighLow_Demo.Open(true); // デモOPEN cHighLow_Demo.demoLogin(); // デモログイン CommonControl.SleepWait(500); // ユーザーによるコマンド受付 情報保持用 string userCommandStatus = string.Empty; //ハイロー入札履歴 List <BoHistroyContainer> HL_History = new List <BoHistroyContainer>(); #if DEBUG //ForDebugOnly(chrome); //return; #endif // シグナルが来るまで待つか、[コマンド]終了を受け付けたら終了 while (true) { //CommonControl.DebugPrint("待機開始・・・"); // メッセージを待つ string signalRoomName = WaitLineGroupsNewArraival(cLINE); // なければ、終了定期処理へ if (string.IsNullOrEmpty(signalRoomName)) { CommonControl.DebugPrint("この時間来ませんでした" + DateTime.Now); goto finallyProcess; // 終了まで飛ばす } // 以下、シグナル受信していたら // メッセージが来た時 // 新着対象の部屋のメッセージ群を取得する ArrayList newMsgList = cLINE.getNewMsgText(signalRoomName); // メッセージがあるか?(通知に気づいたときには古いメッセージしかなくて新着メッセージないときは抜ける) if (newMsgList.Count == 0) { // 新着に気づいたが、メッセージが古い時間のものしか無かった時 CommonControl.DebugPrint("気づくのが遅かった・・・部屋名:" + signalRoomName); goto finallyProcess; // 終了まで飛ばす } string newMsg = ""; if (!userCommandStatus.Equals("stop")) { // エントリーの情報1つのみに絞り込むか又は命令メッセージ(最初に見つかったエントリー メッセージを取得) newMsg = HighLowControl.SelectSignalMsg(signalRoomName, newMsgList); } else { newMsg = (string)newMsgList[newMsgList.Count - 1]; } if (Constants.LINE_RECEIVER_SIDE) { // 子機の場合は冒頭についているどの部屋から来たか情報を取り出し // メッセージの冒頭の親からのヘッダパラメータをカットしてシグナル文のみにする signalRoomName = HighLowControl.AnalysisReceiverSide(ref newMsg); } // ※Stop時以外 // 命令かバイナリー配信かを判断する if (IsSignalMsg(signalRoomName, newMsg)) { // バイナリー配信の時 // 親機の時のみ if (Constants.LINE_RECEIVER_SIDE == false) { // 対象の部屋(グループ)へメッセージをコピー cLINE.putSignalMsgToRoom(Constants.ROOM_NAME_BoSignal, signalRoomName, newMsg); } // シグナル解析 SignalOrder sig = HighLowControl.AnalysisWord(signalRoomName, newMsg); // 指標の高い重要度の時間帯でないか\ // 又は、指定した時間帯 //if (!InvC.JudgeEnvironmentSignalZone(ref sig, ref cLINE)) //sig.Environment = EnvState.esTest; // 無条件デモ HighLowControl.JudgeRealDemo(ref sig); // エントリー結果 bool entryResult = false; if (sig.Environment.Equals(EnvState.esReal)) { // リアルトレード entryResult = cHighLow_Real.EntryHighLow(ref sig); } else { // デモトレード entryResult = cHighLow_Demo.EntryHighLow(ref sig); } // 結果をラインに表示 if (entryResult) { //成功時 cLINE.putSignalMsgToRoom(Constants.ROOM_NAME_CmdLine, signalRoomName, "エントリーに成功。" + Constants.LINE_CRLF + sig.getEntryNoticeMsg()); // シグナル履歴にストック BoHistroyContainer boc = new BoHistroyContainer(HistoryState.hsWaitResult, sig); HL_History.Add(boc); } else { CommonControl.DebugPrint("エントリーに失敗。" + sig.rawOriginalMessage); // デバッグ用 //cLINE.putSignalMsgToRoom(Constants.ROOM_NAME_CmdLine, signalRoomName, "エントリーに失敗。" + sig.rawOriginalMessage); } // 待機に戻る } else { // バイナリー配信ではなくて、命令の時 ステータスにセット if (signalRoomName.Equals(Constants.ROOM_NAME_CmdLine)) // 命令は指定のルームからのメッセージのみ受け取る { // 命令の抽出 string comResult = CommandProc(newMsg, userCommandStatus, out userCommandStatus); // エラーがあった場合 if (comResult.Length != 0) { cLINE.putSignalMsgToRoom(Constants.ROOM_NAME_CmdLine, "", comResult); } // 命令実行 TODO:今は仮 if (userCommandStatus.IndexOf("end") >= 0) // 終了時 { cLINE.putSignalMsgToRoom(Constants.ROOM_NAME_CmdLine, signalRoomName, "プログラムを終了します。" + newMsg); break; } } } // 1通り終了時 定期的に行う処理 finallyProcess: // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- // 溜まったタスクを消化 // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- System.Windows.Forms.Application.DoEvents(); ClickActionTrigger += 1; // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- // 結果を見に行き、新着があればそれを部屋に出力 // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- cHighLow_Real.getSignalResult(ref HL_History); // 本トレ cHighLow_Demo.getSignalResult(ref HL_History); // デモ それぞれに見に行く for (int i = 0; i < HL_History.Count; i++) { if (HL_History[i].State == HistoryState.hsDone) { continue; // 全て完了済みのものは飛ばす } bool ret = false; HL_History[i].PostResultData = CommonControl.PostBoResult(HL_History[i]); // Google送信 // postデータが作られていたら成功 HL_History[i].State = string.IsNullOrEmpty(HL_History[i].PostResultData) ? HL_History[i].State : HistoryState.hsPostDataComplete; // 成功したかどうか ret = CommonControl.OutPutTextBoResult(HL_History[i]); // テキスト吐き出し // テキスト掃き出しできたらすべて完了 HL_History[i].State = ret ? HistoryState.hsDone : HL_History[i].State; } // TODO: コンプリートしたBOコンテナ要素はここで削除しても良いかも // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- // 2minに一回何らかのアクションを起こしてメッセージの受信頻度を上げる // スリープ(LINE受信しなくなる)対策 // ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- if (ClickActionTrigger % 2 == 0) { CommonControl.ClickAction(); ClickActionTrigger = 0; // 受信が行われるようにActiveWindowsの切り替えを行う //TODO:実験成功? 画面のライトがONOFFしなくても受信できるかチェックする SendKeys.SendWait("%{TAB}"); CommonControl.SleepWait(500); SendKeys.SendWait("%{TAB}"); // ネットワークが切れていれば 再ログイン 効果未確認 cHighLow_Real.RetryLogin(); } // debug用 //break; } // main end // ハイローログアウト //cHighLow_Demo.Logout(); //cHighLow_Real.Logout(); chrome.Quit(); } catch (Exception e) { // 想定外エラー発生時 // 原因調査用 CommonControl.DebugPrint(e, "Main Exception"); } finally { CommonControl.DebugPrint("プログラムを終了しました"); } }
/// <summary> /// ハイローにエントリーする /// </summary> /// <param name="sig">シグナル情報 コンテナ</param> /// <returns>True エントリー成功 / False エントリー失敗</returns> public Boolean EntryHighLow(ref SignalOrder sig) { try { // シグナルのステータスがエントリーのみ実行 if (sig.mainState != SignalState.soEntry) { return(false); } // ハイローをアクティブに this.IsActivate(); // 要素が押せるようにスクロールをトップに chrome.ExecuteScript("document.scrollingElement.scrollTop = 140"); // 対象の取引する銘柄へ移動 // ===== ===== ===== ===== ===== ===== // 銘柄リストを開く // ===== ===== ===== ===== ===== ===== IWebElement BrandList = this.chrome.FindElementByXPath("//*[@id='highlow-asset-filter']"); CommonDriverControl.ScrollTargetElementView(BrandList); BrandList.Click(); CommonControl.SleepWait(500); // ===== ===== ===== ===== ===== ===== // 銘柄を選ぶ // ===== ===== ===== ===== ===== ===== // 検索にかける IWebElement eleSearchBox = this.chrome.FindElementById("searchBox"); eleSearchBox.SendKeys(sig.tradeBrand); CommonControl.SleepWait(200); // ヒットした一番目を選択(1つしかないはず) IWebElement eleResultList = this.chrome.FindElementByXPath("//*[@id='assetsFilteredList']/div[1]"); eleResultList.Click(); // ===== ===== ===== ===== ===== ===== // 15分固定 // ===== ===== ===== ===== ===== ===== IWebElement timeTab = this.chrome.FindElementByXPath( "//*[@id='assetsCategoryFilterZoneRegion']/div/div[2]"); CommonDriverControl.ScrollTargetElementView(timeTab); timeTab.Click(); CommonControl.SleepWait(500); // ===== ===== ===== ===== ===== ===== // エントリーする判定時刻 フレーム時間のタブを見つける // ===== ===== ===== ===== ===== ===== IReadOnlyCollection <IWebElement> frameTimeDigits = this.chrome.FindElementsByXPath("//*[@class='time-digits']"); // 最大3つある フレームタイムの時間を見に行き、同じ時間を探す bool findFrameFlag = false; for (int i = 0; i < frameTimeDigits.Count(); i++) { //シグナル時間の取得 string chkFrameTime = frameTimeDigits.ElementAt(i).GetAttribute("textContent"); // 次のシグナルの時間か? if (sig.tradeTimeFrame.Equals(chkFrameTime)) { // 表示 frameTimeDigits.ElementAt(i).Click(); findFrameFlag = true; // 見つかった break; // 1つしかない } } // 見つからなかったとき if (findFrameFlag == false) { // エントリー失敗 CommonControl.DebugPrint("entryHighLow", "対象のタイムフレーム時間が見つからなかった為、エントリー出来ませんでした"); CommonControl.DebugPrint("探そうとしたタイムフレーム" + sig.tradeTimeFrame); return(false); } CommonControl.SleepWait(500); // ===== ===== ===== ===== ===== ===== // エントリー金額を入力する // ===== ===== ===== ===== ===== ===== // TODO:実際は総資金の10分の1入札する この仕組みは後に作る 今は単純に10分の1でエントリーする // 10分1が20万を超えた場合は以下のようにする // 例:22万円の場合、11万*2回エントリーする // 30万円の場合、15万円*2回エントリーする // 残高 // タイムフレームを押した後、読み込み中である可能性があるので取得可能になるまで待つ(GetSafeWebElementById) IWebElement eleBalance = CommonDriverControl.GetSafeWebElementById(chrome, Constants.HTML_ID_HL_Balance); int balance = int.Parse(eleBalance.GetAttribute("textContent") .Replace(@"¥", "").Replace(",", "")); // 入力 IWebElement eleAmount = chrome.FindElementById(Constants.HTML_ID_HL_Amount); // TODO:たまに失敗してる? 要調査 念のため2回おこなう CommonDriverControl.ScrollTargetElementView(eleAmount); // 見えていないとクリアできない CommonDriverControl.ScrollTargetElementView(eleAmount); // 見えていないとクリアできない eleAmount.Clear(); // 既存入力額をクリア CommonControl.SleepWait(200); int amount = balance / 2000; // 資産の 20分の1で amount = amount * 100; // 100の倍数にする if (amount < 1000) { amount = 1000; // 1000円未満になった場合は1000円 } if (amount > 200000) { amount = 200000; // 20万を超える場合は20万 (20万以上はエントリーできないため) } eleAmount.SendKeys(amount.ToString()); // ===== ===== ===== ===== ===== ===== // High Or Low 入力 // ===== ===== ===== ===== ===== ===== // 要素が押せるようにスクロールトップの調整 chrome.ExecuteScript("document.scrollingElement.scrollTop = 275"); IWebElement btn; switch (sig.arrow) { case arrowState.asLow: btn = this.chrome.FindElementByXPath(Constants.XPATH_HL_Low_Button); break; case arrowState.asHigh: btn = this.chrome.FindElementByXPath(Constants.XPATH_HL_High_Button); break; default: CommonControl.DebugPrint("ハイ、又はローが分かりませんでした。"); return(false); } btn.Click(); CommonControl.SleepWait(200); // ===== ===== ===== ===== ===== ===== // エントリー時間になるまで待つ // ===== ===== ===== ===== ===== ===== IWebElement rTime = this.chrome.FindElementByXPath(Constants.XPATH_HL_Remaining_Time); string[] timeTxt = rTime.GetAttribute("textContent").Split(new string[] { ":" }, StringSplitOptions.None); // 後どれだけ待てば良いかを求める 5分前まで TimeSpan tsReman = new TimeSpan(0, int.Parse(timeTxt[0]), int.Parse(timeTxt[1])) - new TimeSpan(0, 5, 0); while (true) { // 残り時刻が5分切るまで待機 if (tsReman > new TimeSpan(0, 0, 0)) { CommonControl.SleepWait((int)tsReman.TotalMilliseconds); } break; } // 成功するまで エントリーを行う int tryTime = 0; bool entryFlag = false; while (entryFlag == false) { IWebElement entryBtn = this.chrome.FindElementById("invest_now_button"); entryBtn.Click(); CommonControl.SleepWait(1250); IWebElement eleNotice = this.chrome.FindElementById(Constants.HTML_ID_HL_NoticeMsg); if (eleNotice.Text.Equals("成功")) { //エントリーに成功した entryFlag = true; } tryTime += 1; if (tryTime > 2) { break; // 3回目失敗したら強制終了 } } #if debug if (tryTime == 3) { CommonControl.DebugPrint("3回エントリー失敗した"); } #endif // 処理自体のエントリー結果を返す return(entryFlag); } catch (Exception e) { // エントリーに失敗した CommonControl.DebugPrint(e, "EntryHighLow エントリーに失敗しました"); //throw;// 投げない return(false); } }