C# 주식분석 프로그램 처녀작품
마스터욱
0
49
0
0
2017-01-08 22:11:45
C# 을 처음 공부하게 된 계기가 된 개인 프로젝트
엄청난 구글링과 디버깅과 빨간 밑줄로 인해 나의 내공은 강해졌고, 결국 완성도 못한채 ㅄ 딴따라가 된 나의 C# 처녀작이다. 헤헤
C# 스승을 한분 두고싶다...
문법은 JAVA 랑 거의 흡사하지만 역시나 PHP 보다는 깐깐하다. PHP만세
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using System.Timers; namespace Stock { public partial class Form1 : Form { //==============================================================================// //종목별 모든 row 데이터를 저장하는 클래스 private class StockData { public string 종목코드; public string 종목이름; //종목의 Row 값을 모두 저장한다. //ex) 종목레코드['레코드_고유번호'] = StockRec 데이터 public Dictionary<int, StockRec> 종목레코드 = new Dictionary<int, StockRec>(); //string(레코드 고유번호), StockRec(로우정보) //체결량별 데이터를 묶음. //인덱스는 레코드의 고유번호이다. //ex) 체결량별_인덱스['100']['레코드_고유번호'] = StockRec 데이터 public Dictionary<int, Dictionary<int, StockRec>> 체결량별_인덱스 = new Dictionary<int, Dictionary<int, StockRec>>(); //string value 값 - 레코드_고유번호 //string value 값 - 규칙성존재함(해당시간에 데이터가 존재하고 규칙성까지 존재함.) //인덱스는 레코드의 체결시간이다.(해당 체결시간에 데이터가 존재하는지의 유무를 확인하기 위해 만듬) //ex) 체결량별_타임['100'][HHiiss_Mktime] = 레코드_고유번호 or "규칙성존재함"; public Dictionary<int, Dictionary<string, string>> 체결량별_타임 = new Dictionary<int, Dictionary<string, string>>(); //ex) 체결량별_규칙분석['100']['00060'] = StockRec; => 100개 체결이 60초 간격으로 존재하는 데이터를 넣음. public Dictionary<int, Dictionary<string, ArrayList>> 체결량별_규칙분석 = new Dictionary<int, Dictionary<string, ArrayList>>(); //ex) 체결량별_순위분석['100'] = 5회 규칙이상인 체결건 기준으로 (체결량 * 체결금액) 의 총합 public Dictionary<int, int> 체결량별_순위분석 = new Dictionary<int, int>(); private SimpleLogger logger = new SimpleLogger(); //Stock 의 레코드 정보를 담아둘 구조체 //private StockRec SR; public class StockRec { public string HHiiss; public int 체결량; public int 체결가; public int 레코드_고유번호; public string 규칙인터벌; //5자리 초단위 숫자(ex : 00060, 00120) } //규칙분석 데이터 만들기 public void SetStockAna() { Dictionary<int, Dictionary<string, ArrayList>> 체결량별_규칙분석_임시 = new Dictionary<int, Dictionary<string, ArrayList>>(); foreach (KeyValuePair<int, StockRec> row in 종목레코드) { int 체결량 = row.Value.체결량; string 규칙성 = row.Value.규칙인터벌; //5자리 초단위 string if (규칙성 == "") { //규칙성이 없는 자료는 굳이 보여줄 필요 없징 continue; } if (!체결량별_규칙분석_임시.ContainsKey(체결량)) { 체결량별_규칙분석_임시[체결량] = new Dictionary<string, ArrayList>(); } if (!체결량별_규칙분석_임시[체결량].ContainsKey(규칙성)) { 체결량별_규칙분석_임시[체결량][규칙성] = new ArrayList(); } 체결량별_규칙분석_임시[체결량][규칙성].Add(row.Value); } var TEMP = from entry in 체결량별_규칙분석_임시 orderby entry.Key descending select entry; //Dictionary<int, Dictionary<string, ArrayList>> 체결량별_규칙분석 = new Dictionary<int, Dictionary<string, ArrayList>>(); foreach (KeyValuePair<int, Dictionary<string, ArrayList>> row in TEMP) { //체결량별_규칙분석[row.Key] = 체결량별_규칙분석_임시[row.Key]; //call by reference //체결량별_규칙분석[row.Key] = new Dictionary<string, ArrayList>(체결량별_규칙분석_임시[row.Key]); //call by value int 체결량 = row.Key; 체결량별_규칙분석[체결량] = new Dictionary<string, ArrayList>(); foreach (KeyValuePair<string, ArrayList> cp_row in row.Value) // call by value { ArrayList StockRecList = new ArrayList(cp_row.Value); string 규칙성 = cp_row.Key; 체결량별_규칙분석[체결량][규칙성] = new ArrayList(); foreach (StockRec StockRow in StockRecList) { 체결량별_규칙분석[체결량][규칙성].Add(StockRow); } } } //같은체결량 안에서 구간(초단위 시간)이 -1,+1 구간이 겹치는 데이터를 합치자. /* foreach (KeyValuePair<int, Dictionary<string, ArrayList>> 임시로우 in 체결량별_규칙분석_임시) { int 체결량 = 임시로우.Key; foreach (KeyValuePair<string, ArrayList> 임시로우2 in 임시로우.Value) //동일체결량 { int second = int.Parse(임시로우2.Key); //인터벌 초단위 6자리 int start = second - 범위조정_체결시간; int end = second - 범위조정_체결시간; for(int i = start; i <= end; i++) { string 규칙성_초단위 = Regex.Replace(i.ToString(), @"\d+", n => n.Value.PadLeft(5, '0')); if(체결량별_규칙분석[체결량].ContainsKey(규칙성_초단위) && 체결량별_규칙분석[체결량].ContainsKey(임시로우2.Key)) { //체결량별_규칙분석[체결량][row2.Key] 와 체결량별_규칙분석[체결량][i] 를 합치고 체결량별_규칙분석[체결량][i] 를 제거하자. foreach(StockRec row3 in 체결량별_규칙분석[체결량][규칙성_초단위]) { 체결량별_규칙분석[체결량][임시로우2.Key].Add(row3); } 체결량별_규칙분석[체결량].Remove(규칙성_초단위); } } } } */ //다른 체결량과 비교하면서 체결량이 -1,+1 차이 범위안이고 시간(초단위)데이터도 -1,+1 차이 범위안이면 합치자. /* 체결량별_규칙분석_임시 = new Dictionary<int, Dictionary<string, ArrayList>>(); foreach (KeyValuePair<int, Dictionary<string, ArrayList>> row in 체결량별_규칙분석) // call by value 복사 { int 체결량 = row.Key; foreach (KeyValuePair<string, ArrayList> cp_row in row.Value) // call by value { ArrayList StockRecList = new ArrayList(cp_row.Value); string 규칙성 = cp_row.Key; 체결량별_규칙분석_임시[체결량] = new Dictionary<string, ArrayList>(); 체결량별_규칙분석_임시[체결량][규칙성] = StockRecList; } } foreach (KeyValuePair<int, Dictionary<string, ArrayList>> 임시로우 in 체결량별_규칙분석_임시) { int 체결량 = 임시로우.Key; int start = 체결량 - 범위조정_체결량; int end = 체결량 + 범위조정_체결량; for(int i = start; i <= end; i++) { //public Dictionary<int, Dictionary<string, ArrayList>> 체결량별_규칙분석 = new Dictionary<int, Dictionary<string, ArrayList>>(); //체결량별_규칙분석[100]['00060'] = StockRec; => 100개 체결이 60초 간격으로 존재하는 데이터를 넣음. if(체결량별_규칙분석.ContainsKey(i)) { int 근접한_체결량 = i; foreach(KeyValuePair<string, ArrayList> 로우1 in 임시로우.Value) //체결량 '100'의 row 들의 루프 { if(!체결량별_규칙분석[체결량].ContainsKey(로우1.Key)) //로우1.Key => 규칙성 5자리 { continue; } int 규칙성1 = int.Parse(로우1.Key); int 시작 = 규칙성1 - 범위조정_체결시간; int 종료 = 규칙성1 + 범위조정_체결시간; //체결량별_규칙분석[101]['00061'] = StockRec; => 101개 체결이 61초 간격으로 존재하는 데이터를 넣음. if (체결량별_규칙분석.ContainsKey(근접한_체결량)) { foreach (KeyValuePair<string, ArrayList> 로우2 in 체결량별_규칙분석_임시[근접한_체결량]) //체결량 '101'의 row 들의 루프 { if(!체결량별_규칙분석[근접한_체결량].ContainsKey(로우2.Key)) //로우2.Key => 규칙성 5자리 { continue; } //초단위가 -1,+1 사이에 있는지 확인 int 규칙성2 = int.Parse(로우2.Key); if (시작 <= 규칙성2 && 규칙성2 <= 종료) { //MessageBox.Show("합치기 체결량의 규칙성 = " + 체결량 + " : " + 로우1.Key); //MessageBox.Show(로우2.Value.Count.ToString()); //합치자 foreach (StockRec 레코드 in 로우2.Value) { //MessageBox.Show("로우1.Key = " + 로우1.Key); 체결량별_규칙분석[체결량][로우1.Key].Add(레코드); } //합쳤으니 뒤에껀 지우자 체결량별_규칙분석[근접한_체결량].Remove(로우2.Key); //MessageBox.Show("삭제된 체결량의 규칙성 = " + 근접한_체결량 + " : " + 로우2.Key); break; } } } } } } } */ //ex) 체결량별_규칙분석['100']['00060'] = StockRec; => 100개 체결이 60초 간격으로 존재하는 데이터를 넣음. foreach (KeyValuePair<int, Dictionary<string, ArrayList>> 키_체결량 in 체결량별_규칙분석) { //ex) 체결량별_순위분석['100'] = 5회 규칙이상인 체결건 기준으로 (체결량 * 체결금액) 의 총합 int 체결량 = 키_체결량.Key; if (체결량 < 0) //일단 마이너스는 배재하자. { //continue; } int SecondPrice = 0; foreach (KeyValuePair<string, ArrayList> 키_규칙인터벌 in 키_체결량.Value) //체결량이 같은 체결건들을 모아놓음 { if (키_규칙인터벌.Value.Count >= 규칙성기준) //규칙성이 5회 이상인 거래건에 한해서 합을 더하자. { int 규칙인터벌 = int.Parse(키_규칙인터벌.Key); int Sum = 0; foreach (StockRec 한줄_레코드 in 키_규칙인터벌.Value) //규칙인터벌이 동일한 리스트 { Sum += 한줄_레코드.체결가; } int SumAvr = Sum / 키_규칙인터벌.Value.Count; //평균체결가 //초당 금액을 구하자. SecondPrice += SumAvr * 체결량 / 규칙인터벌; } } if (SecondPrice != 0) { 체결량별_순위분석[체결량] = SecondPrice; } } } //종목데이터에 Row 삽입. public void SetStockRec(int 레코드_고유번호, string HHiiss, int 체결량, int 체결가) { StockRec SR = new StockRec(); SR.HHiiss = HHiiss; SR.체결량 = 체결량; SR.체결가 = 체결가; SR.레코드_고유번호 = 레코드_고유번호; SR.규칙인터벌 = ""; 종목레코드[레코드_고유번호] = SR; } //체결량별로 시간데이터를 쌓자. public Dictionary<int, Dictionary<int, StockRec>> GetStockData() { if (체결량별_인덱스.Count > 0) { return 체결량별_인덱스; } Dictionary<int, Dictionary<int, StockRec>> List = new Dictionary<int, Dictionary<int, StockRec>>(); foreach (KeyValuePair<int, StockRec> row in 종목레코드) { int 체결량 = row.Value.체결량; int 레코드_고유번호 = row.Value.레코드_고유번호; if (!List.ContainsKey(체결량)) { List[체결량] = new Dictionary<int, StockRec>(); 체결량별_타임[체결량] = new Dictionary<string, string>(); } List[체결량][레코드_고유번호] = row.Value; 체결량별_타임[체결량][GetMktime(row.Value.HHiiss).ToString()] = 레코드_고유번호.ToString(); } //체결량 오림차순 정렬 var ListSort = List.Keys.ToList(); ListSort.Sort(); foreach (var key in ListSort) { 체결량별_인덱스[key] = List[key]; } return 체결량별_인덱스; } } private Dictionary<string, StockData> 전체종목데이터 = new Dictionary<string, StockData>(); private Dictionary<string, float> 순위분석 = new Dictionary<string, float>(); //최종분석결과 private string 현재클릭종목; private string 레코드_마지막_HHiiss; private int 레코드_라스트_번호; private static int 규칙성기준 = 5; //5카운트 이상의 규칙성만 인정한다. private static int 범위조정_체결시간 = 1; //-1, +1 범위 => 이건 시간범위조정임(초단위) private static int 범위조정_체결량 = 1; //-1,+1 범위 => 이건 체결량범위조정임(건단위) private System.Windows.Forms.Timer 타이머 = new System.Windows.Forms.Timer(); private int 타이머카운트 = 0; private bool 모든종목분석 = false; private int CodeListAutoNumber = 0; //모든종목분석 순서 private static Dictionary<string, string> 코드번호_To_시가총액 = new Dictionary<string, string>(); private bool 분석중인지 = false; //==============================================================================// private string LoginName; private Dictionary<string, string> CodeToStockName = new Dictionary<string, string>(); //코드번호와 코드네임을 담을 변수 private Dictionary<int, string> CodeList = new Dictionary<int, string>(); //모든종목분석을 위한 코드번호를 담을 어레이리스트 private int GatherTime = 30; //최근 x분동안의 체결정보만 수집한다.(전체수집에 한해서) private int GatherStartTime; //정보수집 Start 시간 private int TestCodeCount = 10; //테스트할때 TestCodeCount 개수의 종목만 수집한다. private int LoginInterval = 10000; //종목 호출 횟수가 255개로 제한되어 있기 때문에 중간에 세션변경 => 이거 안되는 거임... private string LoginType = ""; //타입이 SESSION이 되면 종목다시 호출시작~, 최초로그인은 타입이 START 임. private SimpleLogger logger = new SimpleLogger(); public Form1() { InitializeComponent(); textBoxLoginInfo.Text = "Open API START" + Environment.NewLine; axKHOpenAPI1.Visible = false; logger.RemoveLog(); /* Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>(); test["100"] = new Dictionary<string, string>(); test["100"]["100_"] = "100_value"; Dictionary<string, Dictionary<string, string>> test2 = new Dictionary<string, Dictionary<string, string>>(test); test["100"]["100_"] = "100_value_re"; MessageBox.Show(test2["100"]["100_"]); */ } //주식종목리스트에서 주식 row를 클릭하면 실행 private void listBoxStock_SelectedIndexChanged(object sender, EventArgs e) { //161028 어차피 모든종목분석만 할거기 때문에 주석처리함. /* string listBoxText = this.listBoxStock.Items[this.listBoxStock.SelectedIndex].ToString(); string[] tmp = listBoxText.Split('('); string CodeName = tmp[0].Trim(); string CodeNumber = tmp[1].Replace(")", string.Empty).Trim(); textBoxLoginInfo.Text = ""; dataGridView1.Rows.Clear(); string obj_data = CodeNumber; listBoxStock_SelectedIndexChanged_Func(obj_data); */ } private void listBoxStock_SelectedIndexChanged_Func(string data) { /* if (CodeListAutoNumber != 0 && CodeListAutoNumber % LoginInterval == 0) { button1_Click_Func("SESSION"); //재로그인 return; } */ LogBox.Text += CodeToStockName[CodeList[CodeListAutoNumber]] + " 분석시작!" + Environment.NewLine; 현재클릭종목 = data; //MessageBox.Show(현재클릭종목); dataGridView1.Rows.Clear(); //===========================================// StockData 종목데이터 = new StockData(); 종목데이터.종목코드 = 현재클릭종목; 종목데이터.종목이름 = CodeToStockName[현재클릭종목]; //MessageBox.Show(종목데이터.종목이름); 전체종목데이터[현재클릭종목] = 종목데이터; 레코드_라스트_번호 = 0; 레코드_마지막_HHiiss = ""; 타이머카운트 = 0; //===========================================// //일단 기본정보부터 가져오자. 시가총액을 알아내기 위해서~ //axKHOpenAPI1.SetInputValue("종목코드", 현재클릭종목); //axKHOpenAPI1.CommRqData(현재클릭종목 + "_체결정보요청", "opt10003", 0, "0101"); //스레드 구조체값을 구분하기 위해 CodeNumber 값을 넘긴다. axKHOpenAPI1.SetInputValue("종목코드", 현재클릭종목); axKHOpenAPI1.CommRqData(현재클릭종목 + "_주식기본정보", "opt10001", 0, "0101"); } //실시간 시세 이벤트라는데 뭔지 잘 몰겠다. //이게 보니깐 주기적으로 호출이 된다... 아마도 특정초단위로 알아서 호출되는 건가보다... private void axKHOpenAPI1_OnReceiveRealData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealDataEvent e) { //textBoxLoginInfo.Text = "axKHOpenAPI1_OnReceiveRealData : " + e.sRealData + Environment.NewLine; } private void axKHOpenAPI1_OnReceiveTrData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveTrDataEvent e) { string[] tmp = e.sRQName.Split('_'); string CodeNumber = tmp[0]; string sRQName = tmp[1]; //MessageBox.Show(e.sPrevNext); 타이머카운트++; if (sRQName == "주식기본정보") { /* content += "종목명 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "종목명").Trim() + Environment.NewLine; content += "등락율 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "등락율").Trim() + Environment.NewLine; content += "거래량 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "거래량").Trim() + Environment.NewLine; content += "시가 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "시가").Trim() + Environment.NewLine; content += "고가 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "고가").Trim() + Environment.NewLine; content += "저가 : " + axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "저가").Trim() + Environment.NewLine; MessageBox.Show(content); */ //각 종목별로 시가총액을 저장하자. string 시가총액 = axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, 0, "시가총액").Trim(); //LogBox.Text += CodeToStockName[CodeNumber] + " => " + 시가총액 + Environment.NewLine; 코드번호_To_시가총액[CodeNumber] = 시가총액; //시가총액은 단위가 (억)임. axKHOpenAPI1.SetInputValue("종목코드", 현재클릭종목); axKHOpenAPI1.CommRqData(현재클릭종목 + "_체결정보요청", "opt10003", 0, "0101"); //스레드 구조체값을 구분하기 위해 CodeNumber 값을 넘긴다. } else if (sRQName == "체결정보요청") { //dataGridView1.Rows.Clear(); int cnt = axKHOpenAPI1.GetRepeatCnt(e.sTrCode, e.sRQName); textBoxLoginInfo.Text = ""; textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += " -> 전체 : " + CodeToStockName.Count + " / 현재 : " + CodeListAutoNumber + "개 완료" + Environment.NewLine; textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += " -> 종목 : " + CodeToStockName[현재클릭종목] + Environment.NewLine; textBoxLoginInfo.Text += " -> 전체 : " + 레코드_라스트_번호 + Environment.NewLine; textBoxLoginInfo.Text += " -> 호출 : " + 타이머카운트 + Environment.NewLine; textBoxLoginInfo.Text += " -> LAST : " + 레코드_마지막_HHiiss + Environment.NewLine; textBoxLoginInfo.Text += Environment.NewLine; bool IsEnd = false; for (int i = 0; i < cnt; i++) { //시간, 현재가, 전일대비, 대비율, 우선매도호가단위, 우선매수호가단위, 체결거래량, sign, 누적거래량, 누적거래대금, 체결강도 string 체결거래량 = axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, i, "체결거래량").ToString().Trim(); string 체결시간 = axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, i, "시간").ToString().Trim(); string 현재가 = axKHOpenAPI1.CommGetData(e.sTrCode, "", e.sRQName, i, "현재가").ToString().Trim(); 현재가 = 현재가.Replace("-", ""); // 마이너스 제거 if (체결거래량 != "") { string[] data = { 레코드_라스트_번호.ToString(), 체결거래량, 체결시간, 현재가, "같은거보기" }; //===========================================================// //종목데이터에 Row 자료를 담는다. //MessageBox.Show(현재클릭종목); StockData 종목데이터 = 전체종목데이터[현재클릭종목]; /* LogBox.Text += Environment.NewLine; LogBox.Text += " -> 레코드_라스트_번호 = " + 레코드_라스트_번호; LogBox.Text += " -> 체결시간 = " + 체결시간; LogBox.Text += " -> 체결거래량 = " + 체결거래량; LogBox.Text += " -> 현재가 = " + 현재가; LogBox.Text += Environment.NewLine; */ 종목데이터.SetStockRec(레코드_라스트_번호, 체결시간, int.Parse(체결거래량), int.Parse(현재가)); //따로 소팅할 필요도 없겠지 헤헤 레코드_라스트_번호++; 레코드_마지막_HHiiss = 체결시간; //===========================================================// dataGridView1.Rows.Add(data); //해쉬데이터입력(체결거래량, 체결시간, thread_info); if (모든종목분석 == true) { if (GetMktime(체결시간) < (GatherStartTime - (60 * GatherTime))) //수집시작시점을 기준으로 GatherTime(분)이 지난 데이터는 필요없다. { //LogBox.Text += GetMktime(체결시간) + " > " + (DateTime.Now.ToString("HHmmss")) + Environment.NewLine; IsEnd = true; break; } } } } //30 * 10 = 300 rows 가 넘어서면 중지하자. if (e.sPrevNext == "2" && IsEnd == false) { //5번 호출후에는 1초의 인터벌후에 호출해야 됨. if (타이머카운트 % 5 == 0) { textBoxLoginInfo.Text += "타이머 호출("+ (타이머카운트 / 5) + ")" + Environment.NewLine; //아귀먼트 전달을 위해 아래 타이머로 교체 //System.Threading.Timer timer = new System.Threading.Timer(timerHandler, thread_info.NowNum, 0, 2000); 타이머.Interval = 1000; //100 => 0.1 second 타이머.Tick += new EventHandler(timerHandler); 타이머.Start(); //The countdown is launched! } else { //textBoxLoginInfo.Text += "연속호출("+ thread_info.ClickCodeNumber + ")" + Environment.NewLine; axKHOpenAPI1.SetInputValue("종목코드", 현재클릭종목); axKHOpenAPI1.CommRqData(현재클릭종목 + "_체결정보요청", "opt10003", 2, "0101"); } } else if (!전체종목데이터.ContainsKey(현재클릭종목)) { MessageBox.Show(현재클릭종목 + " 데이터가 없습니다."); } else { textBoxLoginInfo.Text = "================= 데이터(" + 현재클릭종목 + ") 수집 끝 ================" + Environment.NewLine; //=======================================================// //StockData 에 값이 제대로 들어갔는지 확인. //MessageBox.Show(현재클릭종목); StockData 종목데이터 = 전체종목데이터[현재클릭종목]; //"종목데이터.체결량별_타임"도 같이 생성함. Dictionary<int, Dictionary<int, StockData.StockRec>> 체결량별_인덱스 = 종목데이터.GetStockData(); textBoxLoginInfo.Text += 현재클릭종목 + " 수집완료!" + Environment.NewLine; if (체결량별_인덱스.Count < 1) { textBoxLoginInfo.Text += "데이터가 없습니다!"; } else { /* * public Dictionary<int, Dictionary<int, StockRec>> 체결량별_인덱스 = new Dictionary<int, Dictionary<int, StockRec>>(); * 체결량별_인덱스[100] = 체결량이 '100'인 StockRec 데이터 리스트 * 체결량별_인덱스[105] = 체결량이 '105'인 StockRec 데이터 리스트 * ... * .. * . */ foreach (KeyValuePair<int, Dictionary<int, StockData.StockRec>> 체결량별_인덱스_배열 in 체결량별_인덱스) { //지금부터 주석의 예시는 체결량이 '100' 일경우로 가정한다. /* * 체결량별_인덱스_배열[레코드_고유번호1] = 레코드_고유번호1의 StockRec 데이터 * 체결량별_인덱스_배열[레코드_고유번호2] = 레코드_고유번호2의 StockRec 데이터 * ... * .. * . */ int 체결량 = 체결량별_인덱스_배열.Key; ArrayList 체결시간비교 = new ArrayList(); foreach (KeyValuePair<int, StockData.StockRec> row in 체결량별_인덱스_배열.Value.Reverse()) { string 체결시간_Mktime = GetMktime(row.Value.HHiiss).ToString(); if (체결시간_Mktime == "999999") //시간형식에 맞지않는 쓰레기 데이터가 가끔 온다. { continue; } 체결시간비교.Add(체결시간_Mktime); } /* * 체결시간비교[0] = 체결시간_MKTIME * 체결시간비교[1] = 체결시간_MKTIME * ... * .. * . */ //체결량당 체결시간 분석시작 if (체결시간비교.Count > 1) //시간데이터가 2줄 이상은 있어야 비교가 될테니깐... 어차피 2개라봐야 의미는 없지만... { foreach (KeyValuePair<int, StockData.StockRec> StockRecRow in 체결량별_인덱스_배열.Value.Reverse()) //체결량이 '100'인 StockRec 데이터 루프 { 체결시간비교.RemoveAt(0); if (체결시간비교.Count == 0) { break; } int 기준시간_Mktime = GetMktime(StockRecRow.Value.HHiiss); //public Dictionary<int, Dictionary<string, string>> 체결량별_타임 = new Dictionary<int, Dictionary<string, string>>(); /* * 체결량별_타임 딕셔너리는 레코드에 규칙성의 존재유무를 확인하기 위해 존재한다. * * 체결량별_타임[100][체결_MKTIME] = 레코드_고유번호 또는 * 체결량별_타임[100][체결_MKTIME] = "규칙성존재함" * ... * .. * . */ if (종목데이터.체결량별_타임[체결량][기준시간_Mktime.ToString()] == "규칙성존재함") { //기준데이터가 규칙성이 존재하면 패스 continue; } foreach (string 비교시간_Mktime in 체결시간비교) { if (종목데이터.체결량별_타임[체결량][비교시간_Mktime] == "규칙성존재함") { continue; } int 시간차_Mktime = int.Parse(비교시간_Mktime) - 기준시간_Mktime; if (시간차_Mktime != 0) //기준데이터와 비교데이터가 같지 않다면 { //1차 기준데이터 , 2차 비교데이터는 규칙성이 있다고 간주 SET_규칙인터벌(시간차_Mktime, int.Parse(비교시간_Mktime) + 시간차_Mktime, 종목데이터, 체결량); } } } } //if (체결시간비교.Count > 1) } //foreach (KeyValuePair<string, Dictionary<string, StockData.StockRec>> row in 체결량별_인덱스) } //분석데이터를 뿌리자 //MessageBox.Show(종목데이터.종목코드); 종목데이터.SetStockAna(); 분석데이터_뿌리기(종목데이터); listBoxAna.Items.Add(CodeToStockName[현재클릭종목] + " (" + 현재클릭종목 + ")"); //종목분석 완료된거 리스트에 넣기 if (모든종목분석 == true) { CodeListAutoNumber++; if (CodeList.ContainsKey(CodeListAutoNumber)) { if (CodeListAutoNumber < TestCodeCount) //테스트 삼아 10개만 순위분석 해보자. { //1초뒤에 다음종목을 분석하자. 타이머.Interval = 1000; //100 => 0.1 second 타이머.Tick += new EventHandler(timerHandler_AUTO); 타이머.Start(); //The countdown is launched! } else // 순위분석 결과를 뿌리자 { //체결량별_순위분석['100'] = 5회 규칙이상인 체결건 기준으로 (체결량 * 체결금액) 의 총합 //순위분석['1초당결제금액총합'] = 종목명; Dictionary<string, float> 순위분석_임시 = new Dictionary<string, float>(); foreach (KeyValuePair<string, StockData> 최종로우 in 전체종목데이터) { //string 1초당결제금액총합 = 최종로우.체결량별_순위분석.Sum(v => v.Value); int 초당결제금액총합 = 최종로우.Value.체결량별_순위분석.Sum(v => v.Value); // 초단위 규칙성 합계금액 // ---------------------- * 100 => 제일 높은거 // 시가총액 * 0.00001 //string log = "종목이름 : " + 종목이름 + " / 종목코드 : " + 종목코드 + " / 시가총액 : " + 코드번호_To_시가총액[종목코드]; //MessageBox.Show(log); int 시가총액 = int.Parse(코드번호_To_시가총액[최종로우.Value.종목코드]) * 1000; //100000000 * 0.00001 = 1000 float 평균점수 = (float)초당결제금액총합 / 시가총액 * 100; 평균점수 = (float)Math.Round(평균점수, 4); //MessageBox.Show(초당결제금액총합 + " / " + 시가총액 + " * 100 = " + 평균점수); 순위분석_임시[최종로우.Value.종목코드] = 평균점수; //오름차순 정렬 소팅이 안된 배열 } //오름차순 정렬 var 순위분석 = from entry in 순위분석_임시 orderby entry.Value descending select entry; //오름차순 정렬 /* var ListSort = 순위분석_임시.Keys.ToList(); ListSort.Sort(); foreach (var key in ListSort) { 순위분석[key] = 순위분석_임시[key]; } */ //LogBox.Text = "============ 최종순위 ============" + Environment.NewLine; int TopNumber = 0; foreach (KeyValuePair<string, float> 순위로우 in 순위분석) { TopNumber++; string 종목코드 = 순위로우.Key; StockData 종목데이터_임시 = 전체종목데이터[종목코드]; //LogBox.Text += TopNumber + ". " + 종목데이터_임시.종목이름 + "(" + 순위로우.Value + ")" + Environment.NewLine; listBoxRank.Items.Add(TopNumber + ". " + 종목데이터_임시.종목이름 + "(" + 종목데이터_임시.종목코드 + ") => " + 순위로우.Value + "(시총 : " + 코드번호_To_시가총액[종목데이터_임시.종목코드] + ")"); //랭크 } LogBox.Text += "======= 분석종료 =======" + Environment.NewLine; 분석중인지 = false; } } //if (CodeList.ContainsKey(CodeListAutoNumber)) else { string now = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"); MessageBox.Show("모든분석이 끝났습니다." + now); } } } //else } //else if (e.sRQName == "체결정보요청") } private void timerHandler_AUTO(object sender, System.EventArgs e) { 타이머.Stop(); 타이머 = new System.Windows.Forms.Timer(); //꼭 재시작 해줘야 한다. listBoxStock_SelectedIndexChanged_Func(CodeList[CodeListAutoNumber].ToString()); } private void 분석데이터_뿌리기(StockData 종목데이터) { textBoxLoginInfo.Text = ""; foreach (KeyValuePair<int, Dictionary<string, ArrayList>> 체결량배열 in 종목데이터.체결량별_규칙분석) { string RowText = ""; foreach (KeyValuePair<string, ArrayList> 규칙성배열 in 체결량배열.Value) { if (규칙성배열.Value.Count >= 규칙성기준) //5카운트 이상의 규칙성만 인정한다. { RowText += "규칙성 : " + 규칙성배열.Key + "(" + TimeShow(규칙성배열.Key) + ") => " + 규칙성배열.Value.Count + "개" + Environment.NewLine; } } if (RowText != "") { textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += "============== 체결량 분석 [" + 체결량배열.Key + "] ==============" + Environment.NewLine; textBoxLoginInfo.Text += RowText; } } if (종목데이터.체결량별_순위분석.Count > 0) { textBoxLoginInfo.Text += Environment.NewLine; foreach (KeyValuePair<int, int> row in 종목데이터.체결량별_순위분석) { textBoxLoginInfo.Text += "1초당 체결금액[" + row.Key + "] = " + row.Value + Environment.NewLine; } textBoxLoginInfo.Text += "★ 1초당 토탈 체결금액 -> " + 종목데이터.체결량별_순위분석.Sum(v => v.Value) + Environment.NewLine; textBoxLoginInfo.Text += Environment.NewLine; } else { textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += " -> 전체 : " + CodeToStockName.Count + " / 현재 : " + CodeListAutoNumber + Environment.NewLine; textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += " -> 종목 : " + CodeToStockName[현재클릭종목] + Environment.NewLine; textBoxLoginInfo.Text += Environment.NewLine; textBoxLoginInfo.Text += " ####### 규칙성이 존재하는 데이터가 없습니다. #######"; } } private void SET_규칙인터벌(int 시간차_Mktime, int 비교시간_Mktime, StockData 종목데이터, int 체결량) { int ok_time = chk_range_func(비교시간_Mktime, 종목데이터, 체결량); if (ok_time != 0) //-1, +1 시간범위안에 규칙성이 존재한다면 { 비교시간_Mktime = ok_time; } /* * 체결량별_타임 딕셔너리는 레코드에 규칙성의 존재유무를 확인하기 위해 존재한다. * * 체결량별_타임[100][체결_MKTIME] = 레코드_고유번호 또는 * 체결량별_타임[100][체결_MKTIME] = "규칙성존재함" * ... * .. * . */ if (종목데이터.체결량별_타임[체결량].ContainsKey(비교시간_Mktime.ToString())) //세번째 시간 규칙에 맞는 데이터가 존재하고 { if (종목데이터.체결량별_타임[체결량][비교시간_Mktime.ToString()] != "규칙성존재함") //그 세번째 데이터가 아직 다른 규칙성에 종속되어 있지 않다면 { string 규칙성_초단위 = Regex.Replace(시간차_Mktime.ToString(), @"\d+", n => n.Value.PadLeft(5, '0')); //다섯자리 숫자로 만들기 string 레코드_고유번호 = 종목데이터.체결량별_타임[체결량][비교시간_Mktime.ToString()]; //public Dictionary<int, StockRec> 종목레코드 = new Dictionary<int, StockRec>(); //string(레코드 고유번호), StockRec(로우정보) //종목데이터.종목레코드[레코드_고유번호] = StockRec 데이터 종목데이터.종목레코드[int.Parse(레코드_고유번호)].규칙인터벌 = 규칙성_초단위; 종목데이터.체결량별_타임[체결량][비교시간_Mktime.ToString()] = "규칙성존재함"; //규칙성을 종속시킴(다른 규칙성이 대입되는 것을 방지하기 위함.) SET_규칙인터벌(시간차_Mktime, 비교시간_Mktime + 시간차_Mktime, 종목데이터, 체결량); //다음 next 타임에도 규칙성이 존재하는지 재귀 } } } private int chk_range_func(int 비교시간_Mktime, StockData 종목데이터, int 체결량) { int 시작 = 비교시간_Mktime - 범위조정_체결시간; int 종료 = 비교시간_Mktime + 범위조정_체결시간; for (int i = 시작; i <= 종료; i++) { if(i == 비교시간_Mktime) { continue; } if (종목데이터.체결량별_타임[체결량].ContainsKey(i.ToString())) //타임범위(-1, +1)안에 시간 데이터가 존재하는지 { if (종목데이터.체결량별_타임[체결량][i.ToString()] != "규칙성존재함") //그 시간데이터가 다른 규칙성에 포함되어 있지 않다면 { return i; } } } return 0; } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { } //분석완료된 종목 row 클릭 private void listBoxAna_SelectedIndexChanged(object sender, EventArgs e) { if(분석중인지 == true) { MessageBox.Show("현재 분석중입니다..."); return; } string listBoxText = listBoxAna.Items[listBoxAna.SelectedIndex].ToString(); string[] tmp = listBoxText.Split('('); string CodeName = tmp[0].Trim(); string CodeNumber = tmp[1].Replace(")", string.Empty).Trim(); 현재클릭종목 = CodeNumber; dataGridView1.Rows.Clear(); StockData 종목데이터 = 전체종목데이터[현재클릭종목]; 분석데이터_뿌리기(종목데이터); foreach (KeyValuePair<int, StockData.StockRec> row in 종목데이터.종목레코드) { string 규칙인터벌 = "같은거보기"; if (row.Value.규칙인터벌 != "") { 규칙인터벌 = row.Value.규칙인터벌; } string[] data = { row.Value.레코드_고유번호.ToString(), row.Value.체결량.ToString(), row.Value.HHiiss, row.Value.체결가.ToString(), 규칙인터벌 }; dataGridView1.Rows.Add(data); } } //분석완료된 종목 row 클릭(RANK) private void listBoxRank_SelectedIndexChanged(object sender, EventArgs e) { string listBoxText = listBoxRank.Items[listBoxRank.SelectedIndex].ToString(); //listBoxRank.Items.Add(TopNumber + ". " + 종목데이터_임시.종목이름 + "(" + 종목데이터_임시.종목코드 + ") => " + 순위로우.Value); //랭크 string[] tmp = listBoxText.Split('('); string t = tmp[0].Trim(); string[] tt = t.Split('.'); string CodeName = tt[1].Trim(); //string CodeNumber = tmp[1].Replace(")", string.Empty).Trim(); string[] t2 = tmp[1].Split(')'); string CodeNumber = t2[0].Trim(); //MessageBox.Show(CodeNumber); 현재클릭종목 = CodeNumber; dataGridView1.Rows.Clear(); StockData 종목데이터 = 전체종목데이터[현재클릭종목]; 분석데이터_뿌리기(종목데이터); foreach (KeyValuePair<int, StockData.StockRec> row in 종목데이터.종목레코드) { string 규칙인터벌 = "같은거보기"; if(row.Value.규칙인터벌 != "") { 규칙인터벌 = row.Value.규칙인터벌; } string[] data = { row.Value.레코드_고유번호.ToString(), row.Value.체결량.ToString(), row.Value.HHiiss, row.Value.체결가.ToString(), 규칙인터벌 }; dataGridView1.Rows.Add(data); } } private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex == 4) //같은거보기 클릭 { dataGridView2.Rows.Clear(); DataGridViewRow CR = dataGridView1.CurrentRow; string 체결거래량 = CR.Cells[1].Value.ToString(); int RowCnt = dataGridView1.RowCount - 1; StockData 종목데이터 = 전체종목데이터[현재클릭종목]; //ex) 종목레코드['레코드_고유번호'] = StockRec 데이터 //ex) 종목데이터.체결량별_규칙분석['100']['00060'] = StockRec; => 100개 체결이 60초 간격으로 존재하는 데이터를 넣음. for (int i = 0; i < RowCnt; i++) { string 체결거래량_row = dataGridView1.Rows[i].Cells[1].Value.ToString(); if (체결거래량_row == 체결거래량) { string 체결일 = dataGridView1.Rows[i].Cells[2].Value.ToString(); string 레코드_고유번호 = dataGridView1.Rows[i].Cells[0].Value.ToString(); string 규칙성 = "-"; int 체결일_mktime = GetMktime(체결일); if (종목데이터.체결량별_규칙분석.ContainsKey(int.Parse(체결거래량))) { if (종목데이터.종목레코드[int.Parse(레코드_고유번호)].규칙인터벌 != "") { string 규칙인터벌 = 종목데이터.종목레코드[int.Parse(레코드_고유번호)].규칙인터벌; if (종목데이터.체결량별_규칙분석[int.Parse(체결거래량)][규칙인터벌].Count >= 규칙성기준) //5회 이상인 것들만 보이기 { DateTime NextTime = ConvertFromUnixTimestamp(체결일_mktime + int.Parse(규칙인터벌)); 규칙성 = 규칙인터벌 + " / 다음 - " + NextTime.ToString(); } } } string[] data = { ConvertFromUnixTimestamp(체결일_mktime).ToString(), GetMktime(체결일).ToString(), 규칙성 }; dataGridView2.Rows.Add(data); } } } } //private void timerHandler(object sender, EventArgs e) private void timerHandler(object sender, System.EventArgs e) { 타이머.Stop(); 타이머 = new System.Windows.Forms.Timer(); //꼭 재시작 해줘야 한다. axKHOpenAPI1.SetInputValue("종목코드", 현재클릭종목); axKHOpenAPI1.CommRqData(현재클릭종목 + "_체결정보요청", "opt10003", 2, "0101"); } //분석 쓰레드 돌리기 private void button4_Click(object sender, EventArgs e) { MessageBox.Show("키움증권에서 1초당 5회로 호출제한을 걸어둔 상태라서 분석 쓰레드는 불가능 ㅠㅠ"); } private void textBoxLoginInfo_TextChanged(object sender, EventArgs e) { } //모든종목분석 클릭 private void button9_Click(object sender, EventArgs e) { if(LoginName == null) { MessageBox.Show("로그인을 해주세요."); return; } //초기화 전체종목데이터 = new Dictionary<string, StockData>(); 순위분석 = new Dictionary<string, float>(); //최종분석결과 코드번호_To_시가총액 = new Dictionary<string, string>(); CodeListAutoNumber = 0; textBoxLoginInfo.Text = ""; LogBox.Text = ""; dataGridView1.Rows.Clear(); listBoxRank.Items.Clear(); listBoxAna.Items.Clear(); 분석중인지 = true; //모든 종목 분석 클릭 모든종목분석 = true; //수집시작시간을 저장, GatherStartTime string NowTime = DateTime.Now.ToString("HHmmss"); if (int.Parse(NowTime) > 153000) //오후3시30분에 장이 마감되기 때문에 3시30분 이후로는 3시30분으로 현재시간 인식하기 { NowTime = "153000"; } GatherStartTime = GetMktime(NowTime); listBoxStock_SelectedIndexChanged_Func(CodeList[0].ToString()); } private void button1_Click(object sender, EventArgs e) { button1_Click_Func("FIRST"); } private void button1_Click_Func(string type) { long Result; Result = axKHOpenAPI1.CommConnect(); if (Result != 0) { textBoxLoginInfo.Text = "로그인창 열기 실패!" + Environment.NewLine; } else { textBoxLoginInfo.Text = "로그인창 열기 성공!" + Environment.NewLine; } LoginType = type; } //Form1.Designer.cs 에서 //this.axKHOpenAPI1.OnEventConnect += new AxKHOpenAPILib._DKHOpenAPIEvents_OnEventConnectEventHandler(this.axKHOpenAPI1_OnEventConnect); //정의함. private void axKHOpenAPI1_OnEventConnect(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnEventConnectEvent e) { textBoxLoginInfo.Text = "개인정보 가져오기 성공!" + Environment.NewLine; GetInformation(); } private void GetInformation() { textBoxLoginInfo.Text = ""; textBoxLoginInfo.Text = "LOGIN ID : " + axKHOpenAPI1.GetLoginInfo("USER_ID") + Environment.NewLine; string str = axKHOpenAPI1.GetLoginInfo("ACCNO") + Environment.NewLine; string[] strArray = str.Split(';'); textBoxLoginInfo.Text = "보유한 계좌 : " + axKHOpenAPI1.GetLoginInfo("ACCOUNT_CNT") + Environment.NewLine; foreach (string forstring in strArray) { if (forstring.Trim() != "") { textBoxLoginInfo.Text = "Account : " + forstring + Environment.NewLine; } } textBoxLoginInfo.Text = "사용자명 : " + axKHOpenAPI1.GetLoginInfo("USER_NAME") + Environment.NewLine; textBoxLoginInfo.Text += "키보드보안 해지여부(0:정상, 1:해지) : " + axKHOpenAPI1.GetLoginInfo("KEY_BSECGB") + Environment.NewLine; textBoxLoginInfo.Text += "방화벽 설정 여부(0:미설정, 1:설정, 2:해지) : " + axKHOpenAPI1.GetLoginInfo("FIREW_SECGB") + Environment.NewLine; LoginName = axKHOpenAPI1.GetLoginInfo("USER_NAME"); //로그인박스 감추기 //button1.Visible = false; button3.Text = LoginName + " 님 어서오셩 (o^3^)o"; button3.Visible = true; if(LoginType == "FIRST") { button2_Click_Func(); //종목리스트 가져오기 } else if(LoginType == "SESSION") { listBoxStock_SelectedIndexChanged_Func(CodeList[CodeListAutoNumber].ToString()); } } private void button2_Click(object sender, EventArgs e) { button2_Click_Func(); } private void button2_Click_Func() { if (LoginName == null) { textBoxLoginInfo.Text = "로그인을 해주세요!" + Environment.NewLine; } else { if(CodeList.Count > 0) { //두번째 로그인 이후로는 리스트를 또 받아올 필요없음... //세션테스트를 위해 만들어 놓은거임. return; } //GetCodeListByMarket 메소드는 메소드의 인자로 시장 구분 코드를 문자열로 넘겨주면 메소드의 리턴 값으로 해당 시장에 속해 있는 종목들의 종목 코드 목록을 리턴 //종목 코드로부터 종목한글명을 얻어오는 메소드는 GetMasterCodeName을 사용 //sMarket – 0:장내, 3:ELW, 4:뮤추얼펀드, 5:신주인수권, 6:리츠, 8:ETF, 9:하이일드펀드, 10:코스닥, 30:제3시장 textBoxLoginInfo.Text = "===== 장내, 코스피 리스트 불러오기 시작 =====" + Environment.NewLine; string[] marketList = { "0", "10" }; int InCnt = 0; int OutCnt = 0; int i = 0; foreach (string MNumber in marketList) { string result = axKHOpenAPI1.GetCodeListByMarket(MNumber); string[] stockList = result.Split(';'); if(MNumber == "0") { InCnt = stockList.Count(); } else { OutCnt = stockList.Count(); } foreach (string code in stockList) { if (code != "") { string StockName = axKHOpenAPI1.GetMasterCodeName(code); listBoxStock.Items.Add(StockName + " (" + code + ")"); CodeToStockName[code] = StockName; CodeList.Add(i, code); i++; //axKHOpenAPI1.SetInputValue("종목코드", code); //axKHOpenAPI1.CommRqData(code + "_주식기본정보", "opt10001", 0, "0101"); } } } textBoxLoginInfo.Text = "===== 장내(" + InCnt + "), 코스닥(" + OutCnt + ") 리스트 불러오기 끝 =====" + Environment.NewLine; /* LogBox.Text += "시가총액 정보 시작 =================" + Environment.NewLine; foreach (KeyValuePair<string, string> row in 코드번호_To_시가총액) { LogBox.Text += row.Key + " => " + row.Value + Environment.NewLine; } */ } } private void dataGridView3_CellContentClick(object sender, DataGridViewCellEventArgs e) { } } //public partial class Form1 : Form } //namespace Stock | cs |