Permalink
Browse files

start the move th GUI version

  • Loading branch information...
1 parent 7f2b87c commit 0f20044c006e103bc8adb8c621247eb7d3f66f56 @terryh committed Dec 17, 2012
Showing with 1,030 additions and 1,023 deletions.
  1. +16 −24 README
  2. +0 −601 TFX.csv
  3. +980 −369 autotrader.py
  4. +9 −6 csvloader.py
  5. +22 −21 ddeclient.py
  6. +1 −0 function/General.py
  7. +2 −2 order.py
View
40 README
@@ -1,49 +1,41 @@
+DECLARATION
+============
+
+This package is not fullly functional. We are not responsible for any LOSS via using this software.
+
WHAT'S IT
==========
-LALA
-
-A set of script for you to trade any financial product in market, for now I only test on future index product.
+A set of script with a GUI interface for you to trade any financial product in market, for now I only test on future index product.
we follow kiss(Keep It Simple & Stupid) rule.
-We try to have an Easy Language like trading environment (Trade Station),
-
-that let people don't have to learn too much.
+We try to have an Easy Language like trading environment (Trade Station).
Keeping every function tiny, easy, and small not easy to break down the trading system, and easy to understand.
-
Just for you to test or some other developer interested in this field.
-
-
-
HOW-TO
==========
-For developer you should have Python environment, most Linux distribution had installed, on Windows you can download it at http://www.python.org/ , pywin32 http://sourceforge.net/projects/pywin32/files/
-
-
-In the near future we release the windows executable binary(.exe file) for download.
-
-autotrader.py -m TFX.csv strategy.py
-
- this will fire you strategy to test the default period of market data
+In the near future we'll release the windows executable binary(.exe file) for download.
+main GUI frontend autotrader.exe
-autotrader.py --pov=200 --tax=1000 --start=2009-09-01 -m TFX.csv strategy.py
+DEVELOPER
+===========
- this will fire you strategy to test from 2009-09-01 of market data to end,
-
- pov mean Point of Value, tax mean, how much will cost per trade, you must have pov and tax at the same time
+For developer you should have Python environment on version 2.7, most Linux distribution had installed, on Windows you can download it from http://www.python.org/,
+take a look at requirements.txt.
FIXME
=======
You are welcome to send any patches.
-
-License: BSD
+License: MIT for individual, GPL for none individual.
Author: TerryH, email: terryh.tp at gmail.com,
+
+Windows ICON from http://www.softicons.com/free-icons/toolbar-icons/fatcow-hosting-extra-icons-2-by-fatcow/
View
601 TFX.csv
@@ -1,601 +0,0 @@
-2010/01/04,13:45,8176,8180,8166,8166,2204
-2010/01/05,08:50,8212,8218,8207,8213,3175
-2010/01/05,08:55,8213,8232,8212,8221,2812
-2010/01/05,09:00,8222,8241,8220,8231,2084
-2010/01/05,09:05,8231,8235,8221,8221,1935
-2010/01/05,09:10,8222,8231,8220,8229,1346
-2010/01/05,09:15,8229,8252,8227,8245,3761
-2010/01/05,09:20,8245,8260,8238,8247,2744
-2010/01/05,09:25,8247,8250,8240,8244,1343
-2010/01/05,09:30,8245,8247,8233,8236,1812
-2010/01/05,09:35,8236,8237,8200,8202,5824
-2010/01/05,09:40,8202,8205,8181,8200,5015
-2010/01/05,09:45,8199,8209,8193,8203,2125
-2010/01/05,09:50,8204,8205,8195,8199,1172
-2010/01/05,09:55,8198,8208,8192,8202,1399
-2010/01/05,10:00,8202,8202,8175,8185,2658
-2010/01/05,10:05,8185,8186,8154,8158,4859
-2010/01/05,10:10,8158,8159,8125,8141,5772
-2010/01/05,10:15,8143,8157,8136,8148,2646
-2010/01/05,10:20,8148,8174,8136,8173,3052
-2010/01/05,10:25,8171,8179,8160,8165,1674
-2010/01/05,10:30,8164,8173,8163,8167,1049
-2010/01/05,10:35,8167,8171,8153,8157,1334
-2010/01/05,10:40,8157,8160,8152,8152,905
-2010/01/05,10:45,8152,8161,8148,8160,1203
-2010/01/05,10:50,8159,8168,8157,8168,1098
-2010/01/05,10:55,8168,8183,8167,8177,2258
-2010/01/05,11:00,8177,8182,8171,8175,1285
-2010/01/05,11:05,8177,8180,8174,8178,706
-2010/01/05,11:10,8178,8188,8177,8182,1625
-2010/01/05,11:15,8182,8196,8182,8194,1759
-2010/01/05,11:20,8194,8196,8183,8186,1129
-2010/01/05,11:25,8185,8190,8179,8180,932
-2010/01/05,11:30,8180,8187,8179,8186,643
-2010/01/05,11:35,8186,8189,8184,8185,678
-2010/01/05,11:40,8185,8198,8185,8196,1430
-2010/01/05,11:45,8196,8201,8196,8200,1740
-2010/01/05,11:50,8201,8204,8195,8198,1198
-2010/01/05,11:55,8199,8209,8196,8203,1180
-2010/01/05,12:00,8204,8208,8186,8190,1950
-2010/01/05,12:05,8188,8192,8183,8187,1330
-2010/01/05,12:10,8186,8187,8183,8185,606
-2010/01/05,12:15,8186,8188,8178,8188,1387
-2010/01/05,12:20,8188,8188,8184,8187,408
-2010/01/05,12:25,8188,8193,8187,8188,538
-2010/01/05,12:30,8189,8192,8186,8188,352
-2010/01/05,12:35,8189,8189,8170,8170,1707
-2010/01/05,12:40,8170,8175,8166,8175,1503
-2010/01/05,12:45,8175,8177,8162,8164,1436
-2010/01/05,12:50,8164,8165,8152,8155,2636
-2010/01/05,12:55,8155,8171,8148,8169,2336
-2010/01/05,13:00,8170,8174,8165,8174,1055
-2010/01/05,13:05,8173,8176,8165,8170,1130
-2010/01/05,13:10,8170,8183,8169,8177,1367
-2010/01/05,13:15,8178,8179,8174,8175,569
-2010/01/05,13:20,8175,8177,8167,8168,1311
-2010/01/05,13:25,8169,8174,8168,8172,621
-2010/01/05,13:30,8172,8176,8169,8172,1000
-2010/01/05,13:35,8171,8183,8169,8180,2018
-2010/01/05,13:40,8180,8183,8176,8180,1227
-2010/01/05,13:45,8180,8182,8176,8178,1736
-2010/01/06,08:50,8197,8210,8193,8210,1874
-2010/01/06,08:55,8210,8211,8205,8210,1232
-2010/01/06,09:00,8211,8212,8198,8205,1236
-2010/01/06,09:05,8205,8210,8195,8198,1895
-2010/01/06,09:10,8199,8200,8185,8195,1917
-2010/01/06,09:15,8195,8238,8194,8237,6811
-2010/01/06,09:20,8237,8246,8225,8225,4060
-2010/01/06,09:25,8226,8235,8222,8228,1765
-2010/01/06,09:30,8227,8236,8224,8232,1494
-2010/01/06,09:35,8232,8236,8191,8201,4355
-2010/01/06,09:40,8202,8208,8181,8181,3917
-2010/01/06,09:45,8184,8196,8179,8192,2406
-2010/01/06,09:50,8193,8213,8190,8208,2150
-2010/01/06,09:55,8209,8215,8204,8205,1104
-2010/01/06,10:00,8206,8207,8201,8204,642
-2010/01/06,10:05,8205,8214,8204,8212,1094
-2010/01/06,10:10,8211,8228,8211,8224,2455
-2010/01/06,10:15,8224,8230,8220,8225,1500
-2010/01/06,10:20,8225,8232,8221,8230,1724
-2010/01/06,10:25,8229,8231,8215,8215,1600
-2010/01/06,10:30,8215,8225,8214,8224,1042
-2010/01/06,10:35,8224,8238,8224,8237,1750
-2010/01/06,10:40,8237,8240,8229,8232,1944
-2010/01/06,10:45,8233,8252,8231,8247,3912
-2010/01/06,10:50,8247,8256,8239,8254,3172
-2010/01/06,10:55,8253,8275,8247,8274,3971
-2010/01/06,11:00,8270,8283,8260,8265,3945
-2010/01/06,11:05,8265,8269,8257,8264,1524
-2010/01/06,11:10,8264,8266,8261,8266,833
-2010/01/06,11:15,8265,8274,8264,8269,1249
-2010/01/06,11:20,8270,8280,8265,8270,2180
-2010/01/06,11:25,8272,8285,8270,8277,2622
-2010/01/06,11:30,8277,8284,8268,8278,2228
-2010/01/06,11:35,8278,8281,8265,8269,1623
-2010/01/06,11:40,8268,8274,8262,8272,1347
-2010/01/06,11:45,8272,8283,8272,8282,1750
-2010/01/06,11:50,8282,8287,8277,8282,1195
-2010/01/06,11:55,8281,8285,8270,8273,1321
-2010/01/06,12:00,8273,8282,8273,8279,590
-2010/01/06,12:05,8281,8288,8279,8286,1133
-2010/01/06,12:10,8286,8288,8268,8272,2115
-2010/01/06,12:15,8271,8275,8268,8269,1441
-2010/01/06,12:20,8270,8280,8265,8277,1022
-2010/01/06,12:25,8277,8284,8277,8283,1169
-2010/01/06,12:30,8283,8287,8279,8287,805
-2010/01/06,12:35,8287,8289,8281,8285,678
-2010/01/06,12:40,8285,8285,8278,8284,668
-2010/01/06,12:45,8284,8296,8284,8296,1705
-2010/01/06,12:50,8295,8298,8288,8293,1122
-2010/01/06,12:55,8293,8300,8293,8297,1323
-2010/01/06,13:00,8297,8305,8292,8304,2068
-2010/01/06,13:05,8304,8317,8303,8311,3064
-2010/01/06,13:10,8311,8314,8306,8313,1356
-2010/01/06,13:15,8313,8322,8312,8322,1868
-2010/01/06,13:20,8322,8336,8319,8329,3176
-2010/01/06,13:25,8329,8331,8316,8321,2296
-2010/01/06,13:30,8321,8324,8316,8322,1867
-2010/01/06,13:35,8320,8330,8318,8328,1884
-2010/01/06,13:40,8327,8334,8324,8330,1951
-2010/01/06,13:45,8329,8329,8318,8320,3795
-2010/01/07,08:50,8335,8339,8325,8337,2037
-2010/01/07,08:55,8335,8339,8328,8332,1149
-2010/01/07,09:00,8332,8349,8330,8340,1974
-2010/01/07,09:05,8340,8342,8303,8306,4037
-2010/01/07,09:10,8308,8333,8303,8329,3079
-2010/01/07,09:15,8330,8342,8326,8332,1981
-2010/01/07,09:20,8332,8355,8328,8345,2573
-2010/01/07,09:25,8344,8346,8329,8330,2043
-2010/01/07,09:30,8330,8339,8307,8313,3586
-2010/01/07,09:35,8313,8325,8308,8324,2036
-2010/01/07,09:40,8324,8326,8316,8320,1052
-2010/01/07,09:45,8322,8322,8298,8311,3536
-2010/01/07,09:50,8310,8328,8309,8321,2630
-2010/01/07,09:55,8321,8324,8310,8315,872
-2010/01/07,10:00,8316,8317,8301,8304,2564
-2010/01/07,10:05,8303,8307,8288,8291,5138
-2010/01/07,10:10,8292,8318,8289,8315,2939
-2010/01/07,10:15,8317,8320,8305,8312,1525
-2010/01/07,10:20,8311,8316,8302,8309,947
-2010/01/07,10:25,8309,8311,8298,8302,1107
-2010/01/07,10:30,8301,8309,8300,8306,909
-2010/01/07,10:35,8306,8315,8305,8313,1002
-2010/01/07,10:40,8313,8316,8308,8313,624
-2010/01/07,10:45,8312,8317,8310,8314,562
-2010/01/07,10:50,8314,8324,8313,8321,1628
-2010/01/07,10:55,8321,8331,8320,8330,1857
-2010/01/07,11:00,8330,8334,8325,8327,1177
-2010/01/07,11:05,8325,8332,8324,8325,941
-2010/01/07,11:10,8325,8328,8323,8326,539
-2010/01/07,11:15,8326,8337,8325,8337,868
-2010/01/07,11:20,8335,8348,8335,8345,2121
-2010/01/07,11:25,8345,8348,8336,8340,1229
-2010/01/07,11:30,8340,8344,8334,8338,862
-2010/01/07,11:35,8338,8339,8333,8337,665
-2010/01/07,11:40,8337,8338,8330,8332,601
-2010/01/07,11:45,8332,8332,8321,8322,1123
-2010/01/07,11:50,8322,8322,8312,8318,1340
-2010/01/07,11:55,8318,8318,8305,8310,1585
-2010/01/07,12:00,8312,8312,8303,8308,1390
-2010/01/07,12:05,8308,8321,8303,8319,1765
-2010/01/07,12:10,8320,8321,8315,8317,696
-2010/01/07,12:15,8316,8317,8306,8307,769
-2010/01/07,12:20,8306,8314,8298,8303,1950
-2010/01/07,12:25,8302,8310,8298,8307,1378
-2010/01/07,12:30,8308,8308,8276,8276,5543
-2010/01/07,12:35,8276,8280,8258,8262,6042
-2010/01/07,12:40,8263,8285,8259,8280,3925
-2010/01/07,12:45,8280,8283,8277,8279,1273
-2010/01/07,12:50,8279,8280,8259,8263,2182
-2010/01/07,12:55,8263,8269,8232,8244,5000
-2010/01/07,13:00,8244,8255,8237,8248,3405
-2010/01/07,13:05,8247,8275,8244,8272,3681
-2010/01/07,13:10,8272,8272,8247,8249,2020
-2010/01/07,13:15,8250,8264,8248,8253,1620
-2010/01/07,13:20,8253,8257,8246,8255,1312
-2010/01/07,13:25,8254,8262,8252,8254,1295
-2010/01/07,13:30,8254,8258,8248,8252,1319
-2010/01/07,13:35,8252,8257,8230,8238,3331
-2010/01/07,13:40,8239,8249,8238,8249,1375
-2010/01/07,13:45,8249,8267,8246,8259,2781
-2010/01/08,08:50,8287,8288,8274,8278,2028
-2010/01/08,08:55,8279,8279,8271,8274,876
-2010/01/08,09:00,8275,8276,8271,8274,549
-2010/01/08,09:05,8273,8284,8267,8282,2026
-2010/01/08,09:10,8282,8284,8265,8265,1697
-2010/01/08,09:15,8266,8276,8263,8272,1596
-2010/01/08,09:20,8273,8274,8253,8255,1570
-2010/01/08,09:25,8255,8257,8208,8208,5177
-2010/01/08,09:30,8208,8230,8194,8199,6066
-2010/01/08,09:35,8200,8220,8183,8211,5744
-2010/01/08,09:40,8212,8229,8211,8228,3241
-2010/01/08,09:45,8229,8244,8228,8240,3345
-2010/01/08,09:50,8240,8255,8239,8246,2877
-2010/01/08,09:55,8247,8253,8240,8244,1511
-2010/01/08,10:00,8244,8248,8231,8236,1837
-2010/01/08,10:05,8236,8245,8228,8238,1332
-2010/01/08,10:10,8237,8243,8233,8238,1195
-2010/01/08,10:15,8238,8248,8232,8248,1093
-2010/01/08,10:20,8247,8275,8247,8270,4626
-2010/01/08,10:25,8269,8274,8263,8266,1774
-2010/01/08,10:30,8266,8267,8258,8265,1046
-2010/01/08,10:35,8264,8279,8264,8272,2606
-2010/01/08,10:40,8272,8275,8258,8262,1657
-2010/01/08,10:45,8261,8270,8261,8270,645
-2010/01/08,10:50,8270,8279,8267,8270,1739
-2010/01/08,10:55,8270,8276,8263,8272,925
-2010/01/08,11:00,8271,8284,8268,8276,1863
-2010/01/08,11:05,8276,8283,8272,8279,1082
-2010/01/08,11:10,8279,8293,8275,8288,2588
-2010/01/08,11:15,8289,8295,8284,8293,1325
-2010/01/08,11:20,8294,8297,8284,8287,1072
-2010/01/08,11:25,8287,8290,8279,8279,1279
-2010/01/08,11:30,8279,8283,8268,8268,1508
-2010/01/08,11:35,8268,8274,8265,8271,1325
-2010/01/08,11:40,8271,8273,8258,8260,1530
-2010/01/08,11:45,8260,8265,8251,8263,2310
-2010/01/08,11:50,8262,8263,8242,8249,2214
-2010/01/08,11:55,8248,8262,8242,8261,1574
-2010/01/08,12:00,8261,8274,8259,8268,2080
-2010/01/08,12:05,8268,8270,8263,8269,661
-2010/01/08,12:10,8269,8270,8251,8254,1261
-2010/01/08,12:15,8253,8264,8252,8263,895
-2010/01/08,12:20,8263,8266,8256,8266,662
-2010/01/08,12:25,8266,8277,8265,8274,1028
-2010/01/08,12:30,8276,8278,8271,8271,724
-2010/01/08,12:35,8272,8277,8271,8276,563
-2010/01/08,12:40,8276,8282,8269,8274,962
-2010/01/08,12:45,8275,8277,8272,8274,399
-2010/01/08,12:50,8274,8284,8267,8272,1221
-2010/01/08,12:55,8273,8273,8263,8271,842
-2010/01/08,13:00,8270,8283,8264,8283,1259
-2010/01/08,13:05,8283,8292,8280,8288,2425
-2010/01/08,13:10,8289,8290,8283,8285,828
-2010/01/08,13:15,8286,8293,8285,8289,1218
-2010/01/08,13:20,8290,8295,8286,8288,1289
-2010/01/08,13:25,8288,8292,8284,8288,855
-2010/01/08,13:30,8288,8296,8286,8296,1570
-2010/01/08,13:35,8295,8296,8283,8288,1942
-2010/01/08,13:40,8288,8288,8283,8283,1125
-2010/01/08,13:45,8283,8286,8276,8278,2513
-2010/01/11,08:50,8278,8291,8272,8288,2120
-2010/01/11,08:55,8288,8290,8278,8283,807
-2010/01/11,09:00,8282,8282,8259,8266,2069
-2010/01/11,09:05,8266,8300,8251,8281,4447
-2010/01/11,09:10,8283,8296,8270,8296,1649
-2010/01/11,09:15,8296,8309,8286,8309,3369
-2010/01/11,09:20,8309,8311,8290,8293,2292
-2010/01/11,09:25,8293,8299,8286,8298,1166
-2010/01/11,09:30,8298,8322,8295,8320,3504
-2010/01/11,09:35,8322,8322,8310,8317,2149
-2010/01/11,09:40,8319,8330,8316,8328,2753
-2010/01/11,09:45,8327,8330,8317,8321,1722
-2010/01/11,09:50,8321,8323,8312,8320,1458
-2010/01/11,09:55,8320,8325,8315,8320,913
-2010/01/11,10:00,8319,8338,8318,8338,2677
-2010/01/11,10:05,8338,8347,8330,8335,3466
-2010/01/11,10:10,8335,8337,8326,8330,1448
-2010/01/11,10:15,8330,8332,8320,8326,1270
-2010/01/11,10:20,8325,8329,8318,8325,1039
-2010/01/11,10:25,8326,8332,8323,8323,833
-2010/01/11,10:30,8323,8326,8316,8324,1013
-2010/01/11,10:35,8322,8330,8322,8329,603
-2010/01/11,10:40,8328,8335,8326,8331,992
-2010/01/11,10:45,8330,8334,8323,8333,900
-2010/01/11,10:50,8334,8336,8327,8333,786
-2010/01/11,10:55,8332,8342,8327,8339,1311
-2010/01/11,11:00,8339,8344,8335,8337,1081
-2010/01/11,11:05,8337,8341,8331,8334,690
-2010/01/11,11:10,8335,8345,8334,8344,1008
-2010/01/11,11:15,8345,8350,8337,8349,1925
-2010/01/11,11:20,8348,8353,8333,8336,2414
-2010/01/11,11:25,8338,8339,8328,8337,1441
-2010/01/11,11:30,8336,8337,8331,8334,615
-2010/01/11,11:35,8335,8342,8330,8337,742
-2010/01/11,11:40,8338,8343,8337,8341,480
-2010/01/11,11:45,8340,8348,8340,8343,893
-2010/01/11,11:50,8342,8352,8342,8347,999
-2010/01/11,11:55,8348,8348,8320,8322,3633
-2010/01/11,12:00,8322,8332,8321,8329,1175
-2010/01/11,12:05,8329,8329,8322,8328,682
-2010/01/11,12:10,8327,8333,8320,8328,1161
-2010/01/11,12:15,8328,8329,8324,8325,665
-2010/01/11,12:20,8325,8336,8322,8331,1076
-2010/01/11,12:25,8331,8335,8328,8333,554
-2010/01/11,12:30,8334,8339,8333,8335,691
-2010/01/11,12:35,8336,8337,8333,8335,295
-2010/01/11,12:40,8335,8345,8335,8344,1090
-2010/01/11,12:45,8343,8345,8331,8333,1019
-2010/01/11,12:50,8332,8337,8324,8335,1051
-2010/01/11,12:55,8334,8336,8325,8327,610
-2010/01/11,13:00,8327,8328,8312,8317,2906
-2010/01/11,13:05,8316,8324,8313,8323,1386
-2010/01/11,13:10,8323,8324,8319,8322,632
-2010/01/11,13:15,8322,8323,8316,8317,871
-2010/01/11,13:20,8318,8318,8306,8313,1992
-2010/01/11,13:25,8314,8318,8311,8318,751
-2010/01/11,13:30,8318,8321,8314,8318,1001
-2010/01/11,13:35,8317,8323,8314,8323,1676
-2010/01/11,13:40,8323,8323,8317,8317,1098
-2010/01/11,13:45,8318,8325,8315,8325,2422
-2010/01/12,08:50,8318,8331,8315,8318,1905
-2010/01/12,08:55,8318,8320,8311,8317,994
-2010/01/12,09:00,8317,8324,8316,8321,853
-2010/01/12,09:05,8319,8337,8317,8323,2458
-2010/01/12,09:10,8322,8329,8318,8324,1286
-2010/01/12,09:15,8326,8326,8318,8323,1056
-2010/01/12,09:20,8324,8324,8290,8290,4282
-2010/01/12,09:25,8292,8300,8281,8290,3429
-2010/01/12,09:30,8291,8305,8291,8303,1876
-2010/01/12,09:35,8301,8306,8300,8306,1014
-2010/01/12,09:40,8305,8306,8298,8300,1254
-2010/01/12,09:45,8300,8303,8289,8292,1353
-2010/01/12,09:50,8292,8293,8262,8269,5830
-2010/01/12,09:55,8267,8284,8263,8278,2780
-2010/01/12,10:00,8279,8286,8272,8272,1499
-2010/01/12,10:05,8272,8288,8267,8281,2002
-2010/01/12,10:10,8281,8287,8273,8280,1235
-2010/01/12,10:15,8280,8283,8271,8279,1241
-2010/01/12,10:20,8278,8307,8273,8299,3258
-2010/01/12,10:25,8298,8309,8295,8305,2380
-2010/01/12,10:30,8305,8309,8297,8299,1238
-2010/01/12,10:35,8298,8303,8295,8297,832
-2010/01/12,10:40,8297,8300,8292,8297,811
-2010/01/12,10:45,8297,8300,8280,8285,1446
-2010/01/12,10:50,8285,8294,8283,8287,972
-2010/01/12,10:55,8289,8298,8288,8293,945
-2010/01/12,11:00,8293,8296,8286,8288,770
-2010/01/12,11:05,8288,8290,8273,8280,2101
-2010/01/12,11:10,8282,8283,8246,8250,6560
-2010/01/12,11:15,8251,8267,8248,8264,2721
-2010/01/12,11:20,8264,8274,8262,8271,1780
-2010/01/12,11:25,8272,8287,8271,8283,2137
-2010/01/12,11:30,8283,8284,8278,8281,988
-2010/01/12,11:35,8280,8295,8278,8290,2130
-2010/01/12,11:40,8291,8305,8290,8299,3188
-2010/01/12,11:45,8299,8305,8298,8301,1398
-2010/01/12,11:50,8301,8305,8295,8296,1383
-2010/01/12,11:55,8296,8301,8294,8300,702
-2010/01/12,12:00,8301,8302,8296,8300,616
-2010/01/12,12:05,8301,8312,8300,8311,2829
-2010/01/12,12:10,8311,8319,8309,8310,2176
-2010/01/12,12:15,8311,8312,8303,8307,921
-2010/01/12,12:20,8304,8311,8304,8307,494
-2010/01/12,12:25,8307,8317,8305,8314,1067
-2010/01/12,12:30,8313,8314,8301,8302,874
-2010/01/12,12:35,8302,8309,8301,8307,523
-2010/01/12,12:40,8307,8314,8305,8313,664
-2010/01/12,12:45,8314,8319,8311,8317,1226
-2010/01/12,12:50,8317,8325,8316,8318,2012
-2010/01/12,12:55,8318,8323,8317,8322,617
-2010/01/12,13:00,8322,8324,8309,8312,1396
-2010/01/12,13:05,8312,8315,8306,8308,863
-2010/01/12,13:10,8308,8314,8304,8305,1223
-2010/01/12,13:15,8305,8308,8302,8308,1175
-2010/01/12,13:20,8307,8310,8303,8310,814
-2010/01/12,13:25,8310,8315,8309,8313,859
-2010/01/12,13:30,8311,8315,8311,8315,843
-2010/01/12,13:35,8314,8317,8311,8315,1051
-2010/01/12,13:40,8313,8317,8311,8313,1360
-2010/01/12,13:45,8313,8314,8308,8308,1767
-2010/01/13,08:50,8259,8275,8253,8261,3239
-2010/01/13,08:55,8261,8267,8245,8247,3203
-2010/01/13,09:00,8247,8255,8240,8250,1960
-2010/01/13,09:05,8248,8250,8225,8239,5250
-2010/01/13,09:10,8240,8249,8236,8246,2789
-2010/01/13,09:15,8245,8247,8236,8239,1952
-2010/01/13,09:20,8238,8252,8228,8252,3528
-2010/01/13,09:25,8252,8256,8247,8255,1702
-2010/01/13,09:30,8255,8258,8249,8249,1981
-2010/01/13,09:35,8250,8254,8243,8254,1660
-2010/01/13,09:40,8254,8255,8245,8250,641
-2010/01/13,09:45,8250,8250,8237,8240,1401
-2010/01/13,09:50,8240,8241,8208,8218,7653
-2010/01/13,09:55,8220,8232,8214,8224,2353
-2010/01/13,10:00,8223,8233,8220,8230,1533
-2010/01/13,10:05,8229,8233,8226,8229,963
-2010/01/13,10:10,8228,8230,8223,8225,958
-2010/01/13,10:15,8225,8225,8205,8206,3291
-2010/01/13,10:20,8205,8224,8201,8219,3570
-2010/01/13,10:25,8219,8227,8217,8219,1563
-2010/01/13,10:30,8220,8232,8218,8229,1788
-2010/01/13,10:35,8228,8232,8227,8229,931
-2010/01/13,10:40,8230,8230,8222,8224,791
-2010/01/13,10:45,8224,8226,8220,8220,888
-2010/01/13,10:50,8221,8221,8198,8213,3775
-2010/01/13,10:55,8212,8223,8199,8203,2663
-2010/01/13,11:00,8201,8213,8197,8210,2779
-2010/01/13,11:05,8209,8217,8206,8210,1705
-2010/01/13,11:10,8210,8211,8200,8203,1910
-2010/01/13,11:15,8202,8211,8198,8208,1481
-2010/01/13,11:20,8209,8222,8208,8220,1859
-2010/01/13,11:25,8220,8222,8208,8213,1276
-2010/01/13,11:30,8213,8217,8205,8206,1000
-2010/01/13,11:35,8206,8217,8206,8217,945
-2010/01/13,11:40,8217,8223,8215,8219,1369
-2010/01/13,11:45,8218,8222,8216,8220,694
-2010/01/13,11:50,8220,8228,8220,8222,1628
-2010/01/13,11:55,8224,8225,8216,8217,680
-2010/01/13,12:00,8218,8221,8215,8215,620
-2010/01/13,12:05,8215,8219,8208,8209,1240
-2010/01/13,12:10,8210,8214,8207,8209,986
-2010/01/13,12:15,8209,8212,8193,8194,2985
-2010/01/13,12:20,8194,8211,8191,8208,1863
-2010/01/13,12:25,8210,8210,8200,8204,728
-2010/01/13,12:30,8204,8214,8203,8212,895
-2010/01/13,12:35,8212,8216,8209,8211,772
-2010/01/13,12:40,8211,8212,8201,8206,1046
-2010/01/13,12:45,8206,8208,8201,8201,646
-2010/01/13,12:50,8202,8206,8195,8202,1408
-2010/01/13,12:55,8203,8207,8201,8204,643
-2010/01/13,13:00,8204,8210,8203,8208,995
-2010/01/13,13:05,8208,8222,8208,8220,2416
-2010/01/13,13:10,8220,8221,8211,8213,1125
-2010/01/13,13:15,8213,8214,8204,8206,1189
-2010/01/13,13:20,8206,8212,8203,8206,1201
-2010/01/13,13:25,8206,8211,8204,8211,1142
-2010/01/13,13:30,8211,8218,8208,8213,1499
-2010/01/13,13:35,8213,8214,8204,8208,1517
-2010/01/13,13:40,8207,8212,8205,8207,1061
-2010/01/13,13:45,8207,8218,8206,8215,3071
-2010/01/14,08:50,8246,8249,8236,8249,2737
-2010/01/14,08:55,8248,8253,8246,8248,1459
-2010/01/14,09:00,8247,8248,8244,8245,615
-2010/01/14,09:05,8246,8257,8245,8253,2260
-2010/01/14,09:10,8252,8255,8243,8248,1345
-2010/01/14,09:15,8249,8252,8244,8251,1099
-2010/01/14,09:20,8252,8255,8244,8246,987
-2010/01/14,09:25,8246,8249,8240,8242,1088
-2010/01/14,09:30,8242,8243,8236,8242,1223
-2010/01/14,09:35,8241,8248,8240,8244,991
-2010/01/14,09:40,8244,8247,8242,8246,735
-2010/01/14,09:45,8246,8255,8246,8252,1596
-2010/01/14,09:50,8253,8254,8249,8251,679
-2010/01/14,09:55,8250,8261,8249,8259,2289
-2010/01/14,10:00,8259,8268,8259,8264,2839
-2010/01/14,10:05,8263,8272,8263,8268,2411
-2010/01/14,10:10,8270,8274,8265,8267,1532
-2010/01/14,10:15,8267,8268,8264,8265,829
-2010/01/14,10:20,8266,8269,8262,8264,818
-2010/01/14,10:25,8264,8265,8259,8260,846
-2010/01/14,10:30,8260,8260,8255,8260,1033
-2010/01/14,10:35,8260,8260,8253,8258,755
-2010/01/14,10:40,8258,8264,8257,8264,772
-2010/01/14,10:45,8263,8265,8261,8262,602
-2010/01/14,10:50,8262,8264,8259,8262,441
-2010/01/14,10:55,8263,8266,8261,8265,591
-2010/01/14,11:00,8266,8268,8263,8267,723
-2010/01/14,11:05,8267,8269,8261,8262,887
-2010/01/14,11:10,8262,8267,8261,8265,368
-2010/01/14,11:15,8265,8265,8254,8258,1131
-2010/01/14,11:20,8258,8267,8255,8266,771
-2010/01/14,11:25,8266,8268,8264,8264,672
-2010/01/14,11:30,8265,8278,8263,8276,2281
-2010/01/14,11:35,8276,8279,8273,8274,1369
-2010/01/14,11:40,8275,8278,8273,8275,699
-2010/01/14,11:45,8276,8278,8271,8272,823
-2010/01/14,11:50,8272,8275,8270,8273,587
-2010/01/14,11:55,8273,8285,8273,8283,1878
-2010/01/14,12:00,8283,8287,8281,8284,1045
-2010/01/14,12:05,8284,8290,8283,8290,1076
-2010/01/14,12:10,8290,8300,8289,8294,3069
-2010/01/14,12:15,8295,8304,8292,8303,2052
-2010/01/14,12:20,8303,8315,8302,8311,3443
-2010/01/14,12:25,8310,8314,8306,8307,1194
-2010/01/14,12:30,8308,8318,8307,8315,1637
-2010/01/14,12:35,8315,8328,8312,8326,2518
-2010/01/14,12:40,8326,8328,8321,8322,1399
-2010/01/14,12:45,8322,8328,8321,8326,1257
-2010/01/14,12:50,8326,8326,8311,8317,1782
-2010/01/14,12:55,8316,8317,8313,8314,579
-2010/01/14,13:00,8315,8323,8314,8316,974
-2010/01/14,13:05,8316,8317,8308,8311,1584
-2010/01/14,13:10,8311,8314,8308,8312,1132
-2010/01/14,13:15,8312,8314,8305,8307,1082
-2010/01/14,13:20,8307,8311,8304,8310,1089
-2010/01/14,13:25,8311,8314,8307,8307,1118
-2010/01/14,13:30,8307,8308,8302,8305,1641
-2010/01/14,13:35,8305,8308,8298,8301,2350
-2010/01/14,13:40,8301,8301,8296,8299,1707
-2010/01/14,13:45,8299,8302,8297,8301,2168
-2010/01/15,08:50,8310,8324,8307,8323,2013
-2010/01/15,08:55,8324,8324,8319,8323,734
-2010/01/15,09:00,8323,8335,8322,8328,2053
-2010/01/15,09:05,8328,8336,8319,8323,2477
-2010/01/15,09:10,8323,8347,8321,8345,2616
-2010/01/15,09:15,8345,8348,8333,8339,1891
-2010/01/15,09:20,8339,8343,8334,8340,1247
-2010/01/15,09:25,8341,8351,8337,8349,2295
-2010/01/15,09:30,8349,8359,8345,8350,3626
-2010/01/15,09:35,8350,8363,8348,8360,2649
-2010/01/15,09:40,8360,8368,8342,8347,3827
-2010/01/15,09:45,8346,8348,8340,8345,2052
-2010/01/15,09:50,8343,8350,8341,8348,1371
-2010/01/15,09:55,8348,8348,8323,8325,4042
-2010/01/15,10:00,8325,8332,8313,8319,3935
-2010/01/15,10:05,8318,8330,8312,8327,2511
-2010/01/15,10:10,8325,8328,8321,8324,842
-2010/01/15,10:15,8325,8337,8322,8335,1746
-2010/01/15,10:20,8334,8338,8333,8333,967
-2010/01/15,10:25,8333,8334,8326,8332,974
-2010/01/15,10:30,8332,8338,8329,8337,832
-2010/01/15,10:35,8338,8340,8334,8336,722
-2010/01/15,10:40,8337,8338,8328,8330,743
-2010/01/15,10:45,8328,8333,8328,8330,511
-2010/01/15,10:50,8329,8330,8321,8327,1210
-2010/01/15,10:55,8327,8339,8326,8339,892
-2010/01/15,11:00,8339,8345,8338,8341,1429
-2010/01/15,11:05,8342,8347,8339,8344,985
-2010/01/15,11:10,8344,8348,8341,8342,864
-2010/01/15,11:15,8342,8344,8337,8344,795
-2010/01/15,11:20,8344,8345,8338,8341,632
-2010/01/15,11:25,8341,8355,8341,8355,1833
-2010/01/15,11:30,8355,8362,8352,8357,1937
-2010/01/15,11:35,8357,8373,8355,8367,4047
-2010/01/15,11:40,8366,8377,8362,8377,2685
-2010/01/15,11:45,8376,8383,8375,8379,3343
-2010/01/15,11:50,8379,8385,8362,8368,3058
-2010/01/15,11:55,8366,8368,8360,8364,1079
-2010/01/15,12:00,8363,8365,8358,8361,1140
-2010/01/15,12:05,8361,8368,8360,8364,732
-2010/01/15,12:10,8364,8373,8362,8362,929
-2010/01/15,12:15,8363,8370,8362,8367,507
-2010/01/15,12:20,8367,8370,8364,8364,270
-2010/01/15,12:25,8364,8365,8342,8346,3463
-2010/01/15,12:30,8347,8356,8344,8352,1192
-2010/01/15,12:35,8353,8359,8351,8357,733
-2010/01/15,12:40,8357,8364,8353,8361,917
-2010/01/15,12:45,8360,8371,8360,8367,977
-2010/01/15,12:50,8366,8368,8361,8364,656
-2010/01/15,12:55,8364,8367,8362,8365,426
-2010/01/15,13:00,8366,8367,8362,8363,235
-2010/01/15,13:05,8363,8364,8355,8359,918
-2010/01/15,13:10,8359,8360,8354,8359,637
-2010/01/15,13:15,8359,8373,8357,8370,1541
-2010/01/15,13:20,8371,8373,8366,8371,990
-2010/01/15,13:25,8371,8371,8363,8363,1038
-2010/01/15,13:30,8363,8364,8360,8361,1046
-2010/01/15,13:35,8361,8364,8358,8359,1818
-2010/01/15,13:40,8359,8364,8358,8362,1114
-2010/01/15,13:45,8362,8369,8360,8369,2641
-2010/01/18,08:50,8300,8307,8286,8306,3531
-2010/01/18,08:55,8306,8313,8304,8308,1375
-2010/01/18,09:00,8308,8310,8298,8302,1472
-2010/01/18,09:05,8303,8322,8300,8314,2828
-2010/01/18,09:10,8313,8324,8311,8320,1801
-2010/01/18,09:15,8320,8338,8319,8333,3128
-2010/01/18,09:20,8333,8338,8327,8336,1817
-2010/01/18,09:25,8336,8343,8327,8330,2045
-2010/01/18,09:30,8330,8334,8324,8330,1170
-2010/01/18,09:35,8330,8331,8322,8324,1033
-2010/01/18,09:40,8326,8335,8324,8335,1005
-2010/01/18,09:45,8335,8339,8330,8332,1160
-2010/01/18,09:50,8331,8337,8328,8337,892
-2010/01/18,09:55,8335,8341,8325,8328,1579
-2010/01/18,10:00,8329,8331,8323,8325,918
-2010/01/18,10:05,8325,8330,8317,8320,1541
-2010/01/18,10:10,8320,8329,8318,8326,833
-2010/01/18,10:15,8327,8331,8320,8329,980
-2010/01/18,10:20,8329,8331,8324,8330,658
-2010/01/18,10:25,8330,8331,8323,8327,468
-2010/01/18,10:30,8327,8333,8325,8327,702
-2010/01/18,10:35,8328,8328,8318,8325,983
-2010/01/18,10:40,8325,8330,8323,8327,539
-2010/01/18,10:45,8328,8336,8328,8330,1160
-2010/01/18,10:50,8330,8333,8326,8329,531
-2010/01/18,10:55,8329,8335,8328,8332,554
-2010/01/18,11:00,8333,8347,8331,8342,2513
-2010/01/18,11:05,8342,8345,8339,8344,1165
-2010/01/18,11:10,8344,8349,8341,8342,1448
-2010/01/18,11:15,8343,8347,8342,8343,811
-2010/01/18,11:20,8344,8346,8341,8342,654
-2010/01/18,11:25,8342,8353,8339,8349,1591
-2010/01/18,11:30,8347,8351,8343,8344,1077
-2010/01/18,11:35,8345,8353,8345,8353,672
-2010/01/18,11:40,8353,8355,8348,8350,866
-2010/01/18,11:45,8350,8359,8350,8357,1106
-2010/01/18,11:50,8357,8361,8355,8360,1227
-2010/01/18,11:55,8360,8363,8355,8362,899
-2010/01/18,12:00,8363,8365,8359,8360,1127
-2010/01/18,12:05,8360,8363,8358,8361,556
-2010/01/18,12:10,8361,8364,8351,8353,1115
-2010/01/18,12:15,8354,8360,8352,8359,476
-2010/01/18,12:20,8359,8365,8356,8363,768
-2010/01/18,12:25,8363,8366,8361,8361,539
-2010/01/18,12:30,8361,8361,8352,8358,835
-2010/01/18,12:35,8359,8361,8356,8360,451
-2010/01/18,12:40,8361,8375,8359,8375,2211
-2010/01/18,12:45,8374,8382,8371,8381,1686
-2010/01/18,12:50,8381,8383,8375,8379,1008
-2010/01/18,12:55,8378,8379,8372,8373,842
-2010/01/18,13:00,8374,8375,8369,8370,767
-2010/01/18,13:05,8369,8375,8362,8362,1548
-2010/01/18,13:10,8364,8367,8356,8358,1998
-2010/01/18,13:15,8358,8363,8354,8362,1469
-2010/01/18,13:20,8362,8362,8355,8360,1030
-2010/01/18,13:25,8361,8362,8357,8358,717
-2010/01/18,13:30,8357,8359,8351,8351,2095
-2010/01/18,13:35,8352,8353,8347,8348,1910
-2010/01/18,13:40,8349,8352,8347,8350,1073
-2010/01/18,13:45,8350,8353,8349,8353,2272
View
1,349 autotrader.py
@@ -1,400 +1,1011 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# Author: terryh.tp at gmail.com
-"""
-A set of script for you to trade any financial product in market
-Author: TerryH, email: terryh.tp at gmail.com,
-License: BSD
-"""
+# wxPython
+import wx
+from wx.lib.wordwrap import wordwrap
+from wxobject import MyFrame, M, C, D, S
-import datetime
-import time
+import os
import sys
-import getopt
-import types
-import pprint
+import logging
import re
-import types
-import threading
-
-try:
- import cPickle as pickle
-except:
- import pickle
-
-
-# our own function
-from csvloader import csvtolist
-from order import Order
-from function import *
-
-
-
-# parameters
-re_paras = re.compile("PARAS.?=.?{.*?}",re.DOTALL)
-# variables must have default value
-re_vars = re.compile("VARS.?=.?{.*?}",re.DOTALL)
-
-
-def checktimeframe(dataset=[],backbars=300):
- """look for more than two day, find the time frame for trade,
- at lease have more thant 2 day item in dataset
- """
- timeframe_list = []
- tl = timeframe_list
- timedelta = 0 # seconds
- initday = 0
-
- for i in range(len(dataset[-backbars:])):
- dt = dataset[i][0]
- if i<2:
- initday = dt.date()
- elif initday and dt.date()>initday:
- if dt.time() not in tl:
- tl.append(dt.time())
-
- if tl:
- tl.sort()
- day = datetime.date.today()
- t1 = tl[0]
- t2 = tl[1]
-
- timedelta = datetime.datetime.combine(day,t2)-datetime.datetime.combine(day,t1)
-
- return tl,timedelta
-
-def find_ticket(timeframe_list=[],delta="", now=""):
- """find the right index for current ticket
- """
- # FIXME leter, we should think about different time zone for trading
- if not now:
- now = datetime.datetime.now()
-
- if timeframe_list and delta:
- tt = now.time()
- i = 0
- market_open = 0
- for i in range(len(timeframe_list)):
- #print i,timeframe_list[i]
- if tt<=timeframe_list[i]:
- market_open = 1
-
- break
- return i,market_open
-
-
+import datetime
+import subprocess
+import multiprocessing
+import multiprocessing.forking
+
+# help pyinstaller, cx_Freeze to include
+from ctypes import POINTER, WINFUNCTYPE, c_char_p, c_void_p, c_int, c_ulong
+from ctypes.wintypes import BOOL, DWORD, BYTE, INT, LPCWSTR, UINT, ULONG
+
+#import calendar
+#from shutil import copyfile
+
+# locale
+#import gettext
+#_ = gettext.ugettext
+
+# third party module
+from configobj import ConfigObj
+
+#help pyinstaller to find
+import pytz
+
+#------------------------------------------
+from tz import timezones
+from wxutils import wxd_to_python, python_to_wxd, showMsg, ShowBusyCursor
+from quote.utils import get_now, get_tz_hhmm
+
+# Process
+from quote.quoteworker import QuoteWriter
+
+__version__ = u'0.1.1'
+__appname__ = u'AutoTrader'
+__author__ = u'TerryH'
+
+app_realpath = os.path.realpath(sys.argv[0])
+app_dir = os.path.dirname(app_realpath)
+
+market_ini = os.path.join(app_dir, 'config','market.ini')
+commodity_ini = os.path.join(app_dir, 'config', 'commodity.ini')
+strategy_ini = os.path.join(app_dir, 'config', 'strategy.ini')
+data_dir = os.path.join(app_dir, 'data')
+
+if not os.path.exists(data_dir):
+ os.makedirs(data_dir)
+
+re_alphanumeric = re.compile(r'^\w+$')
+re_date = re.compile(r'^\d{4}-\d{2}-\d{2}$')
+
+quote_module_dir = 'quote'
+
+QUOTE_SOURCE = [u"",u'DDE']
+
+QUOTE_WRITER_EXE = 'quoteworker.exe'
+
+# support tracking trade time
+SUPPORT_TIME = ['min1', 'min2', 'min3', 'min5', 'min15', 'min30', 'hour1', 'day1']
+SUPPORT_TIME_NAME = ['1 Min', '2 Min', '3 Min', '5 Min', '15 Min', '30 Min', '1 Hour', '1 Day' ]
+#SUPPORT_TIME_NAME = ['1 Min':'min1',
+# '2 Min':'min2',
+# '3 Min':'min3',
+# '5 Min':'min5',
+# '15 Min':'min15',
+# '30 Min':'min30',
+# '1 Hour':'hour1',
+# '1 Day':'day1'
+# }
+
+######################################################
+# work around for pyinstaller one file execuable pack
+# but now we use cx_Freeze
+class _Popen(multiprocessing.forking.Popen):
+ def __init__(self, *args, **kw):
+ if hasattr(sys, 'frozen'):
+ # We have to set original _MEIPASS2 value from sys._MEIPASS
+ # to get --onefile mode working.
+ # Last character is stripped in C-loader. We have to add
+ # '/' or '\\' at the end.
+ os.putenv('_MEIPASS2', sys._MEIPASS + os.sep)
+ try:
+ super(_Popen, self).__init__(*args, **kw)
+ finally:
+ if hasattr(sys, 'frozen'):
+ # On some platforms (e.g. AIX) 'os.unsetenv()' is not
+ # available. In those cases we cannot delete the variable
+ # but only set it to the empty string. The bootloader
+ # can handle this case.
+ if hasattr(os, 'unsetenv'):
+ os.unsetenv('_MEIPASS2')
+ else:
+ os.putenv('_MEIPASS2', '')
+
+class Process(multiprocessing.Process):
+ _Popen = _Popen
+
+################################################################################
+# start multiprocessing.Process outside wxApp main loop
+def start_quote_process(quote_method, commodity='',commodity_ini=''):
+ quote_module = __import__("quote.%s" % quote_method, fromlist=[quote_method])
+ # try until success via main wx.Timer
+ p = multiprocessing.Process(target=quote_module.main, args=(commodity,commodity_ini))
+ #p = Process(target=quote_module.main, args=(commodity,commodity_ini))
+ p.start()
+ return p
+
+def start_quote_workers(market_ini, commodity_ini, ccode ):
+ p = QuoteWriter(market_ini, commodity_ini, ccode)
+ p.start()
+ return p
+################################################################################
+
+################################################################################
+# start subprocess.Popen outside wxApp main loop
+def sub_quote_process(quote_exe, commodity='',commodity_ini=''):
+ # try until success via main wx.Timer
+ final_command = "%s --config=%s --commodity=%s" % (quote_exe, commodity_ini, commodity)
+ print final_command
+ p = subprocess.Popen( final_command.split())
+ return p
+
+def sub_quote_writer(market_ini, commodity_ini, ccode ):
+ final_command = "%s --mini=%s --cini=%s --commodity=%s" % ( QUOTE_WRITER_EXE, market_ini, commodity_ini, ccode)
+ print final_command
+ p = subprocess.Popen( final_command.split())
+ return p
+################################################################################
+
+#------------------------------------------
+class Mixin(object):
+ def collect_data(self):
+ raw_dict = {}
+ for k in self.field_keys:
+ if getattr(self.__dict__[k],'GetValue', False):
+ raw_dict[k] = self.__dict__[k].GetValue()
+ elif getattr(self.__dict__[k],'GetStringSelection', False):
+ raw_dict[k] = self.__dict__[k].GetStringSelection()
+ elif getattr(self.__dict__[k],'GetPath', False):
+ raw_dict[k] = self.__dict__[k].GetPath()
+ return raw_dict
+
+ def loaditem(self,code=''):
+ if self.configobj and code in self.configobj:
+ for k in self.field_keys:
+ #print k
+ if self.configobj[code].get(k):
+ setvalue = self.configobj[code].get(k)
+ # casting
+ if setvalue == u'True':
+ setvalue = True
+ if setvalue == u'False':
+ setvalue = False
+
+ # datetime date to wx.DateTime
+ if ( isinstance(setvalue, str) or isinstance(setvalue, unicode) ) and re_date.search(setvalue):
+ setvalue = python_to_wxd(setvalue)
+
+ if getattr(self.__dict__[k],'SetValue', False):
+ self.__dict__[k].SetValue(setvalue)
+ elif getattr(self.__dict__[k],'SetStringSelection', False):
+ self.__dict__[k].SetStringSelection(setvalue)
+ elif getattr(self.__dict__[k],'SetPath', False):
+ self.__dict__[k].SetPath(setvalue)
+
+#------------------------------------------
+class Strategy(S, Mixin):
+ def __init__(self, *args, **kwds):
+ S.__init__(self, *args, **kwds)
+ wx.EVT_CHAR_HOOK(self, self.onKey)
+ self.configobj = {}
+ self.inifile = strategy_ini
+ self.configobj = {}
+ self.c_obj = ConfigObj( commodity_ini, encoding='utf-8')
+ self.field_keys = [ 'strategyfile', 'ccode',
+ 'period', 'num', 'cost',
+ 'start', 'end', 'sid', 'run'
+ ]
+ self.require_fields = ['strategyfile', 'ccode', 'period', 'num']
+ self.ccode.SetItems( [ v.get('ccode') for k, v in self.c_obj.items() ] )
+ self.period.SetItems( SUPPORT_TIME_NAME )
+ self.loaddata()
+
+ def validate(self, raw_dict={}):
+ for key in self.require_fields:
+ if not raw_dict.get(key, False):
+ return False
+ # extra validate
+ if not raw_dict.get('num').isdigit(): return False
+ if raw_dict.get('cost', False) and not raw_dict.get('cost').isdigit(): return False
+ return True
+
+ def get_data_dir(self):
+ if self.ccode.GetValue():
+ ccode = self.ccode.GetValue()
+ dir_name = "%s_%s" % ( self.c_obj[ccode].get('mcode'), self.c_obj[ccode].get('ccode') )
+ history_dir = os.path.join(data_dir, dir_name)
+ if history_dir and not os.path.exists(history_dir):
+ os.makedirs(history_dir)
+ return history_dir
+ return ''
+
+ def onSubmit(self,event):
+ raw_dict = self.collect_data()
-
-def autotrader(strategy_file="", market_file="",backbars=300, interval=0.5,
- quote=False,maxbars=False, start="",end="",pov=0,tax=0):
- """ autotrader(strategy_file,market_data,backbars)
- A set of script for you to trade any financial product in market
- this is the main script
+ if not self.validate(raw_dict):
+ dlg = wx.MessageDialog(self,
+ _("You must at least have strategy file, commodity code, trading time period and max number of bars will use in strategy."),
+ _("Strategy"),
+ wx.OK | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ else:
+ dlg = wx.MessageDialog(self,
+ _("Are you sure want to update?"),
+ _("Strategy"),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ sid = self.sid.GetValue()
+
+ if not sid:
+ # let's find a new sid, forget about race, lock, and looping
+ start_id = 1
+ if not sid:
+ sid = self.get_new_id()
+ raw_dict['sid'] = sid
+ # wx.DateTime
+ if raw_dict.get('start'): raw_dict['start'] = wxd_to_python(raw_dict.get('start')).strftime('%Y-%m-%d')
+ if raw_dict.get('end'): raw_dict['end'] = wxd_to_python(raw_dict.get('end')).strftime('%Y-%m-%d')
- autotrader [options] your_strategy_file.py
+
+ if sid not in self.configobj:
+ # insert
+ self.configobj[sid] = {}
+
+ for key in self.field_keys:
+ self.configobj[sid][key] = raw_dict.get(key,'')
+
+ self.configobj.write() # write ini file
+ self.Destroy()
- OPTIONS:
+ def onValidate(self,event):
+ self.Close()
+
+ def onDelete(self,event):
+ if self.configobj and self.sid.GetValue():
+ sid = self.sid.GetValue()
+ dlg = wx.MessageDialog(self,
+ _('Are you sure?'),
+ _('Delete'),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+
+ del self.configobj[sid] # delete & write back
+ self.configobj.write()
+ self.Destroy()
- -m, -market=your_market_file
- the incoming market data stream, now we only work on text file,
- you have to implement this by yourself
+ self.Destroy()
+
+ def onKey(self,event):
+ keycode = event.GetKeyCode()
+ if keycode == wx.WXK_ESCAPE:
+ self.Close()
+ event.Skip()
+
+ def get_new_id(self):
+ start_id = 1
+ sid = 0
+ while not sid:
+ if not str(start_id) in self.configobj:
+ sid = str(start_id)
+ return sid
+ start_id += 1
+
+ def loaddata(self):
+ self.configobj = ConfigObj(self.inifile, encoding='utf-8')
+
+#------------------------------------------
+class DDEWIN(D, Mixin):
+ def __init__(self, *args, **kwds):
+ D.__init__(self, *args, **kwds)
+ wx.EVT_CHAR_HOOK(self, self.onKey)
+ self.configobj = {}
+ self.field_keys = [ 'mcode', 'ccode',
+ 'dde1_server', 'dde1_topic','dde1_time', 'dde1_price', 'dde1_volume',
+ 'dde2_server', 'dde2_topic','dde2_time', 'dde2_price', 'dde2_volume'
+ ] + SUPPORT_TIME
+ self.require_fields = ['dde1_server', 'dde1_topic','dde1_time', 'dde1_price', 'dde1_volume']
+
+ def validate(self, raw_dict={}):
+ for key in self.require_fields:
+ if not raw_dict.get(key, False):
+ return False
+ return True
+
+ def onSubmit(self,event):
+ raw_dict = self.collect_data()
+
+ if not self.validate(raw_dict):
+ dlg = wx.MessageDialog(self,
+ _("You must at least input DD1, time, price and volume, can refer from Excel."),
+ _("DDE"),
+ wx.OK | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ else:
+ dlg = wx.MessageDialog(self,
+ _("Are you sure want to update?"),
+ _("DDE"),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ # TODO
+ self.GetParent().update_quote(raw_dict, self.field_keys)
+ self.Destroy()
+
+ def onCancel(self,event):
+ self.Close()
+
+ def onDelete(self,event):
+ if self.configobj:
+ dlg = wx.MessageDialog(self,
+ _('Are you sure?'),
+ _('Delete'),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ self.GetParent().delete_quote()
+ self.Destroy()
+
+ self.Destroy()
+
+ def onKey(self,event):
+ keycode = event.GetKeyCode()
+ if keycode == wx.WXK_ESCAPE:
+ self.Close()
+ event.Skip()
+
+#------------------------------------------
+class Commodity(C, Mixin):
+ def __init__(self, *args, **kwds):
+ C.__init__(self, *args, **kwds)
+ wx.EVT_CHAR_HOOK(self, self.onKey)
+ self.field_keys = ['cname', 'ccode', 'mcode', 'cpov', 'csource', 'cdir']
+ self.require_fields = ['cname', 'ccode', 'mcode']
+ self.inifile = commodity_ini
+ self.configobj = {}
+ self.m_obj = ConfigObj( market_ini, encoding='utf-8')
+ self.markets = [ ( v.get('mname'), v.get('mcode') ) for k, v in self.m_obj.items() ]
+ self.loaddata()
+ self.csource.SetItems( QUOTE_SOURCE )
+ self.mcode.SetItems( [ mcode for mname, mcode in self.markets ] )
+
+ def validate(self, raw_dict={}):
+ for key in self.require_fields:
+ if not raw_dict.get(key, False):
+ return False
+ if not re_alphanumeric.search(raw_dict.get('ccode')): return False
+ return True
+
+ def onSubmit(self,event):
+ raw_dict = self.collect_data()
+ if not self.validate(raw_dict):
+ dlg = wx.MessageDialog(self,
+ _("You must at least input Commodity Name, Commodity Code (alphanumeric), and Quote Folder for real time data processing, better at a ram disk folder."),
+ _("Market"),
+ wx.OK | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ else:
+ dlg = wx.MessageDialog(self,
+ _("Are you sure want to update?") + ' ' + _("Remember to restart to ative changes."),
+ _("Market"),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ ccode = raw_dict['ccode'].upper()
+ raw_dict['ccode'] = ccode
+
+ if ccode not in self.configobj:
+ self.configobj[ccode] = {}
+ print raw_dict
+
+ for key in self.field_keys:
+ self.configobj[ccode][key] = raw_dict.get(key,'')
+ self.configobj.write() # write ini file
+ self.Close()
+
+ def onSource(self,event):
+ if self.csource.GetStringSelection():
+ self.config.Enable()
+ else:
+ self.config.Enable(False)
+
+ def onConfig(self,event):
+ raw_dict = self.collect_data()
+ source = raw_dict.get('csource')
+ mcode = raw_dict.get('mcode')
+ ccode = raw_dict.get('ccode')
+
+ if source and source in QUOTE_SOURCE:
+ support_time = SUPPORT_TIME # FIXME, check this value
+ try:
+ exec('support_time = %s_SUPPORT_TIME' % source)
+ except:
+ pass # FIXME, better chance to load support field
- -b, -backbars
- how many back bars you take to caculate, the small the better depend on your strategy
- , impact on performance
+ try:
+ __import__("quote.%s" % (source), fromlist=[source])
+
+ dlg = DDEWIN(self) #FIXME, add more config
+ dlg.mcode.SetValue(mcode)
+ dlg.ccode.SetValue(ccode)
+ self.loaddata() # reload data again to make sure
+ if self.configobj.get(ccode):
+ dlg.configobj = self.configobj.get(ccode)
+ dlg.loaditem('quote')
+
+ dlg.ShowModal()
+ dlg.Destroy()
+ except ImportError:
+ self.GetParent().loginfo(_('No support quote module found.'))
+
+ def onHistory(self,event):
+ history_dir = self.check_history()
+ if history_dir:
+ if os.name == 'nt':
+ os.startfile(history_dir)
+ elif os.name == 'posix':
+ try:
+ os.system('xdg-open %s' % history_dir ) # try open histtory folder on linux
+ except:
+ pass # TODO
+
+ def check_history(self):
+ dir_name = ''
+ history_dir = ''
+ if self.ccode.GetValue() and self.mcode.GetStringSelection():
+ self.history.Enable()
+ dir_name = "%s_%s" % ( self.mcode.GetStringSelection(), self.ccode.GetValue().upper() )
+ history_dir = os.path.join(data_dir, dir_name)
+ if history_dir and not os.path.exists(history_dir):
+ os.makedirs(history_dir)
+ return history_dir
+ else:
+ self.history.Enable(False)
- -h --help read the help
+ return
+
+ def onMcode(self,event):
+ self.check_history()
+
+ def onDelete(self,event):
+ ccode = self.ccode.GetValue().upper()
+ if ccode and ccode in self.configobj:
+ dlg = wx.MessageDialog(self,
+ _('Are you sure?'),
+ _('Delete'),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ del self.configobj[ccode]
+ self.configobj.write()
+ self.Destroy()
+
+ def onKey(self,event):
+ keycode = event.GetKeyCode()
+ if keycode == wx.WXK_ESCAPE:
+ self.Close()
+ event.Skip()
+
+ def loaddata(self, m_obj={}):
+ self.configobj = ConfigObj(self.inifile, encoding='utf-8')
+ if m_obj:
+ self.m_obj = m_obj
+
+ def set_market_obj(self, m_obj={}):
+ if m_obj:
+ self.m_obj = m_obj
+
+ def update_quote(self, quote_obj={}, field_keys=[]):
+ if self.configobj and self.ccode.GetValue() and self.configobj.get(self.ccode.GetValue()):
+ cid = self.ccode.GetValue()
+ if not self.configobj[cid].get('quote', False):
+ self.configobj[cid]['quote']= {}
+
+ for k in field_keys:
+ self.configobj[cid]['quote'][k] = quote_obj.get(k,'')
+ self.configobj.write()
+
+ def delete_quote(self):
+ if self.configobj and self.ccode.GetValue() and self.configobj.get(self.ccode.GetValue()):
+ del self.configobj[self.ccode.GetValue()]['quote']
+ self.configobj.write()
+
+ def loaditem(self,ccode=''):
+ super(Commodity, self).loaditem(ccode)
+ if self.csource.GetStringSelection(): self.config.Enable()
+ if self.ccode.GetValue() and self.mcode.GetStringSelection(): self.history.Enable()
+
+#------------------------------------------
+class Market(M, Mixin):
+ def __init__(self, *args, **kwds):
+ M.__init__(self, *args, **kwds)
+ wx.EVT_CHAR_HOOK(self, self.onKey)
+ self.field_keys = [ 'mname', 'mcode', 'mtimezone', 'mclear',
+ 's1_start', 's1_end', 's2_start', 's2_end',
+ 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6'
+ ]
+ self.require_fields = ['mname', 'mcode', 'mtimezone', 'mclear', 's1_start','s1_end']
+ self.inifile = market_ini
+ self.configobj = {}
+ self.loaddata()
+ self.mtimezone.SetItems(timezones)
+
+ def validate(self, raw_dict={}):
+ for key in self.require_fields:
+ if not raw_dict.get(key, False):
+ return False
+ if not re_alphanumeric.search(raw_dict.get('mcode')): return False
+ # special check for time 24HHMM
+ if raw_dict['mclear'] == u'00:00' or raw_dict['s1_end'] == u'00:00': return False
+
+ return True
+ def onSubmit(self,event):
+ raw_dict = self.collect_data()
+ if not self.validate(raw_dict):
+ dlg = wx.MessageDialog(self,
+ _("You must at least input Market Name, Market Code (alphanumeric), Session Clear Time and Session 1 Time"),
+ _("Market"),
+ wx.OK | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ else:
+ dlg = wx.MessageDialog(self,
+ _("Are you sure want to update?"),
+ _("Market"),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ mcode = raw_dict['mcode'].upper()
+ raw_dict['mcode'] = mcode
+ if raw_dict['mcode'] not in self.configobj:
+ self.configobj[mcode] = {}
+ for key in self.field_keys:
+ self.configobj[mcode][key] = raw_dict.get(key,'')
+ self.configobj.write() # write ini file
+ self.Close()
+
+ def onCancel(self,event):
+ self.Close()
+
+ def onDelete(self,event):
+ mcode = self.mcode.GetValue().upper()
+ if mcode and mcode in self.configobj:
+ dlg = wx.MessageDialog(self,
+ _('Are you sure?'),
+ _('Delete'),
+ wx.YES_NO | wx.YES_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ del self.configobj[mcode]
+ self.configobj.write()
+ self.Destroy()
+
+ def onKey(self,event):
+ keycode = event.GetKeyCode()
+ if keycode == wx.WXK_ESCAPE:
+ self.Close()
+ event.Skip()
+
+ def loaddata(self):
+ self.configobj = ConfigObj(self.inifile, encoding='utf-8')
+
+#------------------------------------------
+class FF(MyFrame):
+ def __init__(self, *args, **kwds):
+ MyFrame.__init__(self, *args, **kwds)
+ # art work
+ #self.quit = wx.MenuItem( self.menumain, wx.ID_ANY, u"離開"+ u"\t" + u"CTRL+X", wx.EmptyString, wx.ITEM_NORMAL )
+
+ #self.quit.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_QUIT,wx.ART_MENU,(16,16)))
+ #self.menumain.AppendItem( self.quit )
- -i interval the timer for check the strategy, default 0.5 second
-
- --start=YYYY-MM-DD tell where to start
+ self.quote_process = {}
+ self.quote_workers = {}
+ self.strategy_process = {}
-
- --end=YYYY-MM-DD tell where to end
- the following is market file format
- read thhe csv file last few lines to process look back data
+ self.timer = wx.Timer(self)
+ self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
+ self.timer.Start(1000*10) # main application timer
- marrket file format
+ self.m_obj = {} # market
+ self.c_obj = {} # commodity
+ self.s_obj = {} # strategy
+
+ self.market_ini = market_ini
+ self.commodity_ini = commodity_ini
+ self.strategy_ini = strategy_ini
+
+ self.data_ids = ['username','password','cert','certpass','autostart',]#'sctrl','actrl']
+
+ self.logfilename = os.path.join(app_dir, "autotrader.log")
+ logging.basicConfig(
+ level=logging.INFO,
+ format='%(asctime)s %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S',
+ filename=self.logfilename,
+ )
+ self.logger = logging.getLogger('')
+
+ # Market
+ self.mctrl.InsertColumn(0, _("Market Name"))
+ self.mctrl.InsertColumn(1, _("Market Code"))
+ self.mctrl.InsertColumn(2, _("Market Time Zone"))
- YYYY/MM/DD,HH:MM,OPEN,HIGH,LOW,CLOSE,VOLUMN
- YYYY/MM/DD,OPEN,HIGH,LOW,CLOSE,VOLUMN
+ # Commodity
+ self.cctrl.InsertColumn(0, _("Commodity Name"))
+ self.cctrl.InsertColumn(1, _("Commodity Code"))
+ self.cctrl.InsertColumn(2, _("Market Code"))
+ self.cctrl.InsertColumn(3, _("Quote Source"))
+ self.cctrl.InsertColumn(4, _("Quote Folder"))
- or
+ # Strategy
+ self.sctrl.InsertColumn(0, _("Id"))
+ self.sctrl.InsertColumn(1, _("Commodity Code"))
+ self.sctrl.InsertColumn(2, _("Program File"))
+ self.sctrl.InsertColumn(3, _("Time Period"))
+ print _
+ print _("Delete")
+ self.loaddata()
+ self.render_all()
+
+ # test
+ self.test = None
+
+ def onMarket(self,event):
+ dlg = Market(self)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.load_market()
+ self.render_market()
+
+ def onMarketActive(self,event):
+ item_index = event.m_itemIndex
+ mcode = self.mctrl.GetItem(item_index, 1).GetText()
+ dlg = Market(self)
+ dlg.loaditem(mcode)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.load_market()
+ self.render_market()
+
+ def onCommodity(self,event):
+ dlg = Commodity(self)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.loaddata()
+ self.render_commodity()
+
+ def onCommodityActive(self,event):
+ item_index = event.m_itemIndex
+ ccode = self.cctrl.GetItem(item_index, 1).GetText()
+ dlg = Commodity(self)
+ dlg.loaditem(ccode)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.load_commodity()
+ self.render_commodity()
+
+ def onStrategy(self,event):
+ dlg = Strategy(self)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.load_strategy()
+ self.render_strategy()
+
+ def onStrategyActive(self,event):
+ item_index = event.m_itemIndex
+ sid = self.sctrl.GetItem(item_index, 0).GetText()
+ dlg = Strategy(self)
+ dlg.loaditem(sid)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.load_strategy()
+ self.render_strategy()
+
+ def OnCheckItem(self,index, flag):
+ sid = self.sctrl.GetItem(index, 0).GetText()
+ #print index, flag, sid
+ if self.s_obj.get(sid, False):
+ # toggle run key value
+ if flag:
+ self.s_obj[sid]['run'] = True
+ else:
+ self.s_obj[sid]['run'] = ""
+ self.s_obj.write()
+
+ def onSave(self,event):
+ dd = {}
+ for k in self.data_ids:
+ item = getattr(self,k)
+ if hasattr(item,'GetValue'):
+ if k == 'username':
+ dd[k] = item.GetValue().upper()
+ else:
+ dd[k] = item.GetValue()
+ elif hasattr(item,'GetPath'):
+ dd[k] = item.GetPath()
- YYYY-MM-DD,OPEN,HIGH,LOW,CLOSE,VOLUMN
- """
- global AUTOTRADER_RUN,NOW,CURRENT_BAR,RUNDATA,DATASET,OO,HH,LL,CC,VV,dl,tl,ol,hl,ll,cl,vl
+ self.data = dd
+
+ def onStart(self,event):
+ # FIXME, clean up this def
+ start = self.start.GetValue()
+ if start:
+
+ self.start.SetLabel(u"停止下單")
+ self.sctrl.Enable(False)
+ #self.actrl.Enable(False)
+ self.saveall.Enable(False)
+ # disable menu
+ self.news.Enable(False)
+ self.newa.Enable(False)
- if strategy_file:
-
- print "Exec Strategy File-> ", strategy_file
-
- strategy_source = open(strategy_file).read()
-
- # bind order function
- ORDER = Order()
- BUY = Buy = buy = ORDER.BUY
- SELL = Sell = sell = ORDER.SELL
- EXITLONG = ExitLong = exitlong = ORDER.EXITLONG
- EXITSHORT = ExitShort = exitshort = ORDER.EXITSHORT
- if pov:
- ORDER.pov=pov
- if tax:
- ORDER.tax=tax
+ else:
+ self.start.SetLabel(u"開始下單")
+ self.sctrl.Enable()
+ #self.actrl.Enable()
+ self.saveall.Enable()
+ # enable menu
+ self.news.Enable()
+ self.newa.Enable()
+ self.loginfo(u"停止下單")
+
+ def onAbout(self, event):
+ info = wx.AboutDialogInfo()
+ info.Name = __appname__
+ info.Version = __version__
+ info.Copyright = __author__
+ info.Description = wordwrap(
+u"""An easy tool for you to trade any commodity you like.\n
+License: MIT for individual, GPL for none individual.\n
+Author: TerryH""",
+ 350, wx.ClientDC(self))
+ info.WebSite = (u"http://terryh.tp.blogspot.com/", u"TerryH's Blog")
+ wx.AboutBox(info)
+
+ def onQuit(self,event):
+ dlg = wx.MessageDialog(self,
+ u'Are you sure?',
+ u'Close',
+ wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION
+ )
+ val = dlg.ShowModal()
+ dlg.Destroy()
+ if val == wx.ID_YES:
+ # close all process
+ self.stop_process()
+ self.Destroy()
+
+ def onTimer(self,event):
+ """
+ create process for quote service, strategy start or stop
+ """
+ #if self.test == None:
+ ##self.loginfo('onTimer start TEST')
+ #proc = subprocess.Popen(sys.executable + " pp.py")
+ #self.test = proc
+ #self.loginfo(sys.executable)
- if re_paras.search(strategy_source):
- dd = re_paras.search(strategy_source).group()
- exec(dd)
- for k,v in PARAS.items():
- # FIXME it's not secure, but we exec strategy file anyway
- vars()[k]=v
+ # TODO, clean up
+ #self.loginfo('onTimer')
+ for k, v in self.c_obj.items():
+ if v.get('csource'):
+ ccode = v['ccode'] # commodity code
+ mcode = v['mcode'] # market code
+ source = v['csource']
+ mtimezone = self.m_obj[mcode]['mtimezone']
+
+ session_start = ''
+ session_end = ''
-
- if re_vars.search(strategy_source):
- dd = re_vars.search(strategy_source).group()
- exec(dd)
- for k,v in VARS.items():
- vars()[k]=v
-
- # set time frame
-
- dl,tl,ol,hl,ll,cl,vl = [],[],[],[],[],[],[]
-
- num = len(RUNDATA)
- for i in range(num):
- # bind order variable
- ORDER.dt = RUNDATA[i][0]
- DATASET = RUNDATA[:i+1]
- MARKETPOSITION=MarketPosition=marketposition=MKS = ORDER.market_position
- ENTRYPRICE=EntryPrice=entryprice = ORDER.entry_price
- # load record
- dl,tl,ol,hl,ll,cl,vl = General_Row(dl,tl,ol,hl,ll,cl,vl,RUNDATA[i],length=backbars)
- DATE = Date=dl
- TIME = Time=tl
- OPEN = Open = O =ol
- HIGH = High = H =hl
- LOW = Low = L =ll
- CLOSE= Close= C =cl
- VOLUME=Volume=V = vl
- OO = ol[0]
- HH = hl[0]
- LL = ll[0]
- CC = cl[0]
- VV = vl[0]
- exec(strategy_source)
-
- # after looping all history we taken,
- if start or end:
- ORDER.REPORT()
- # clear instance data
- OO = HH = LL = CC = 0
- while AUTOTRADER_RUN and quote:
- #print datetime.datetime.now(),ORDER,ORDER.market_position, ORDER.dt
- ORDER.dt = RUNDATA[-1][0]
- MARKETPOSITION=MarketPosition=marketposition=MKS = ORDER.market_position
- ENTRYPRICE=EntryPrice=entryprice = ORDER.entry_price
- DATE = Date=dl
- TIME = Time=tl
- OPEN = Open = O =ol
- HIGH = High = H =hl
- LOW = Low = L =ll
- CLOSE= Close= C =cl
- VOLUME=Volume=V = vl
- if CURRENT_BAR:
- ORDER.current_dt = CURRENT_BAR
-
- exec(strategy_source)
-
- time.sleep(interval)
-
-def quote_update(market="",quote=""):
- """We have file quote support only, quote_file format , python pickled list,[datetime.time,price,volume]
- HH:MM:SS,price,totalvolume
- """
- q_l = []
- try:
- return pickle.load(open(quote))
- except:
- return q_l
+
+ mclear = self.m_obj[mcode]['mclear']
+ s1_start = self.m_obj[mcode]['s1_start']
+ s1_end = self.m_obj[mcode]['s1_end']
+ s2_end = self.m_obj[mcode]['s2_end']
+
+ if mclear and mclear != '00:00':
+ session_start = mclear
+ elif s1_start and s1_start != '00:00':
+ session_start = mclear
+
+ if s2_end and s2_end != '00:00':
+ session_end = s2_end
+ elif s1_end and s1_end != '00:00':
+ session_end = s1_end
+
+ key = "%s_%s" % (mcode, ccode)
+ #self.loginfo(str(self.quote_process))
+
+ if self.should_running(session_start, session_end, mtimezone):
+ # check this quote should running
+ if key not in self.quote_process:
+ # not running quote process
+ s_hour, s_minute = map(int, session_start.split(':',1))
+ now = get_now(mtimezone)
+
+ market_start_time = get_tz_hhmm(s_hour, s_minute, mtimezone)
+ self.loginfo(mtimezone)
+ self.loginfo(str(now))
+ self.loginfo(str(market_start_time))
+ self.loginfo(str((market_start_time-now).seconds))
+ # we must start app 1 minute before market open
+ #if (market_start_time-now).seconds < 60:
+ quote_module = __import__("quote.%s" % source , fromlist=[source])
+ quote_exe = source + ".exe"
+
+ self.loginfo(str(quote_module))
+ self.loginfo(quote_exe)
+ self.loginfo(ccode )
+ self.loginfo(self.commodity_ini)
+
+ #--------------------------------------------------
+ # start_quote_process and start_quote_workers
+ #t = start_quote_process( source, ccode, self.commodity_ini )
+ #self.quote_process[key] = t
+ #w = start_quote_workers(self.market_ini, self.commodity_ini, ccode)
+ #self.quote_workers[key] = w
+ #--------------------------------------------------
+
+ #--------------------------------------------------
+ # sub_quote_process and sub_quote_workers
+ t = sub_quote_process( quote_exe, ccode, self.commodity_ini )
+ self.quote_process[key] = t
+
+ w = sub_quote_writer(self.market_ini, self.commodity_ini, ccode)
+ self.quote_workers[key] = w
+ #--------------------------------------------------
+
+ def should_running(self, start, end, timezone):
+ if (start and end and timezone):
+ now = get_now(timezone)
+ hh, mm = map(int , start.split(':',1))
+ tzstart = get_tz_hhmm(hh, mm, timezone)
+ hh, mm = map(int , end.split(':',1))
+ tzend = get_tz_hhmm(hh, mm, timezone)
+ if end < start:
+ # trading time cross midnight
+ return now >= tzstart or now <= tzend
+ else:
+ return now >= tzstart and now <= tzend
+ return now >= tzstart
+ return False
+
+ def stop_process(self):
-
-def main(strategies=[],market="",backbars=300,interval=0.5, \
- quote="",maxbars=False,start="",end="",pov=0,tax=0):
- """If we are going to keep update the market file, and scanning for buy or sell signal
- could have many strategy for one market file
- """
- # share data, only read
- global AUTOTRADER_RUN,NOW,CURRENT_BAR,RUNDATA,DATASET,OO,HH,LL,CC,VV,dl,tl,ol,hl,ll,cl,vl
- # init instance data
- OO = HH = LL = CC = CURRENT_BAR = 0
- AUTOTRADER_RUN = True
- thread_list = [] # threading list
- NOW = now = datetime.datetime.now()
- # load dataset
- if market:
- if start or end:
- RUNDATA = csvtolist(market,start=start,end=end)
- else:
- RUNDATA = csvtolist(market,backbars=backbars)
+ # wait for close multiprocessing.Process
+ #--------------------------------------------------
+ for k in self.quote_process.keys():
+ self.quote_process[k].terminate()
- if type(strategies) == types.ListType and len(strategies)>0:
- if quote:
- # only have quote input, we use threading
- for s in strategies:
- t = threading.Thread(target=autotrader,args=(s,market,backbars,interval,True))
- t.start()
- thread_list.append(t)
- elif start or end:
- # only parse first strategy , quote = False
- autotrader(strategies[0],market,backbars,interval,False,maxbars,start,end,pov,tax)
- else:
- autotrader(strategies[0],market,backbars,interval,False,maxbars)
+ for k in self.quote_workers.keys():
+ self.quote_workers[k].terminate()
+
+ #isalive = 1
+ #while isalive:
+ #isalive = 0
+ #for k in self.quote_process.keys():
+ #isalive = isalive + self.quote_process[k].is_alive()
+ #isalive = 1
+ #while isalive:
+ #isalive = 0
+ #for k in self.quote_workers.keys():
+ #isalive = isalive + self.quote_workers[k].is_alive()
+ #--------------------------------------------------
- if quote:
- # if have quote let's start our MAIN LOOOP
-
- #print quote
- timeframe_list,delta = checktimeframe(RUNDATA)
- NOW = now = datetime.datetime.now()
- ti,market_open = find_ticket(timeframe_list,delta, now)
- if not market_open and ti==len(timeframe_list)-1:
- # market not start yet, start from ti = 0, else condition just use the found ti (ticket index)
- ti = 0
-
- ww = 0 # for test
- pc = 0 # previous close price
- pt = datetime.datetime(1900,1,1) # previous time
- pv = 0 # previous bar total volume
- tip = 0 # previous ticket index
- # in case our time is slow that market, plus 5 seconds
- lastticket_end = datetime.datetime.combine(now.date(),timeframe_list[-1]) + datetime.timedelta(seconds=5)
- #print ti,market_open
- #print timeframe_list,delta
- try:
-
- while ti<len(timeframe_list) and now <lastticket_end:
- now = datetime.datetime.now()
- # start ticket
- ticket_time = timeframe_list[ti]
- ticket_end = datetime.datetime.combine(now.date(),ticket_time)
- ticket_start = ticket_end-delta
- # if our time is slow or fast for few seconds, let's say 5 seonds
- if ti == 0:
- ticket_start = ticket_start-datetime.timedelta(seconds=5)
-
- quote_list = quote_update(quote=quote)
- #print quote_list
- # start a ticket
- if quote_list:
- ql = quote_list
- # convert ticket time to datetime
- qt = datetime.datetime.combine(now.date(),ql[0])
- if (pt<ticket_start and qt>=ticket_start) or tip !=ti:
- # this bar first ticket
- tip = ti # record the ticket index, until exit this ticket, we will enter again
- OO = ql[1]
- HH = ql[1]
- LL = ql[1]
- CC = ql[1]
- VV = ql[2]-pv
-
- elif qt>=ticket_start and qt< ticket_end:
- CURRENT_BAR = ticket_time
- if not OO:
- # first time, qmpty value
- OO = HH = LL = CC = ql[1]
- # change HH, LL
- if ql[1]>HH: HH = ql[1]
- if ql[1]<LL: LL = ql[1]
- CC = ql[1]
- VV = ql[2]-pv
- print ql[0],OO,HH,LL,CC,VV,
- print "\r",# a trick to keep cursor at same line
-
-
- if now>=ticket_end:
- # close a ticket
- line = ticket_end.strftime("%Y/%m/%d,%H:%M")
- pv = ql[2]
- qline= "%s,%s,%s,%s,%s" % (str(OO),str(HH),str(LL),str(CC),str(VV))
- fp = file(market,"a")
- fp.write(line+','+qline+"\n")
- fp.close()
- print line+','+qline
- # increse ti ticket index
- ti = ti+1
- # after new ticket, read it again
- RUNDATA = csvtolist(market,backbars=backbars)
- dl,tl,ol,hl,ll,cl,vl = General(RUNDATA,length=backbars)
-
- pt = qt #remember as previous ticket time
- time.sleep(interval)
-
- except KeyboardInterrupt:
+ #if hasattr(sys, 'frozen'):
+ ## We need to wait for all child processes otherwise
+ ## --onefile mode won't work.
+ #while multiprocessing.active_children():
+ #multiprocessing.active_children()[0].terminate()
+ #time.sleep(3) # wait for kill all, FIXME better way for waitting
- AUTOTRADER_RUN = False
- for t in thread_list:
- t.join()
- print "Finishing all job"
+ print "All close"
+
+ def render_all(self):
+ self.render_market()
+
+ self.render_commodity()
+ self.render_strategy()
+
+ def render_market(self):
+ self.mctrl.DeleteAllItems()
+ for k,v in self.m_obj.items():
+ index = self.mctrl.InsertStringItem(sys.maxint, v.get('mname'))
+ self.mctrl.SetStringItem(index, 1, v.get('mcode'))
+ self.mctrl.SetStringItem(index, 2, v.get('mtimezone'))
+ self.mctrl.SetColumnWidth(2, 100)
+ self.mctrl.SetItemBackgroundColour(index, wx.Color(229,229,229))
- # join all thread, if we have
- if thread_list:
- AUTOTRADER_RUN = False # stop all thread
- for t in thread_list:
- t.join()
- print "Finishing all job"
-
+ def render_commodity(self):
+ self.cctrl.DeleteAllItems()
+ for k,v in self.c_obj.items():
+ index = self.cctrl.InsertStringItem(sys.maxint, v.get('cname'))
+ self.cctrl.SetStringItem(index, 1, v.get('ccode'))
+ self.cctrl.SetStringItem(index, 2, v.get('mcode'))
+ self.cctrl.SetStringItem(index, 3, v.get('csource'))
+ self.cctrl.SetStringItem(index, 4, v.get('cdir'))
+ self.cctrl.SetItemBackgroundColour(index, wx.Color(229,229,229))
+
+ def render_strategy(self):
+ self.sctrl.DeleteAllItems()
+ for k,v in self.s_obj.items():
+ index = self.sctrl.InsertStringItem(sys.maxint, k)
+ self.sctrl.SetStringItem(index, 1, v.get('ccode'))
+ self.sctrl.SetStringItem(index, 2, v.get('strategyfile'))
+ self.sctrl.SetStringItem(index, 3, v.get('period'))
+ self.sctrl.SetItemBackgroundColour(index, wx.Color(229,229,229))
+ if v.get('run') == u"True":
+ self.sctrl.CheckItem(index)
+
+ def load_market(self):
+ self.m_obj = ConfigObj(self.market_ini, encoding='utf-8')
+
+ def load_commodity(self):
+ self.c_obj = ConfigObj(self.commodity_ini, encoding='utf-8')
+
+ def load_strategy(self):
+ self.s_obj = ConfigObj(self.strategy_ini, encoding='utf-8')
+
+ def loaddata(self):
+ self.load_market()
+ self.load_commodity()
+ self.load_strategy()
+
+ def loginfo(self,text=u""):
+ if text:
+ self.log.AppendText(datetime.datetime.now().strftime("%m-%d %H:%M:%S")+u" "+text+u"\n")
+ self.logger.info(text)
+
if __name__ == '__main__':
+ if sys.platform.startswith('win'):
+ multiprocessing.freeze_support() # multiprcessing workaround
+
+ app = wx.PySimpleApp(False)
+
+ #---------------------------------------------
+ # locale
+ #basepath = os.path.abspath(os.path.dirname(sys.argv[0]))
+ #localedir = os.path.join(basepath, "locale")
+ langid = wx.LANGUAGE_DEFAULT
+ mylocale = wx.Locale(langid)
+ mylocale.AddCatalogLookupPathPrefix('./locale')
+ mylocale.AddCatalog('messages')
+ _ = wx.GetTranslation
+
+ # override
+ import __builtin__
+ __builtin__._ = wx.GetTranslation
+
+ # override wxobject
+ import wxobject
+ wxobject._ = wx.GetTranslation
+
+ #---------------------------------------------
- opts, args = getopt.getopt(sys.argv[1:], "ahq:ti:m:b:",
- ["all","help","quote=","market=","back=","start=","end=","pov=","tax="])
-
- if len(args) > 0:
- strategy = args[0:]
- market = ""
- backbars = 300
- maxbars=False
- interval = 0.5
- start = 0
- end = 0
- pov = 0
- tax = 0
- quote = 0
- for o, a in opts:
- if o in ("-h", "--help"):
- print autotrader.__doc__
- sys.exit()
- elif o in ("-b", "--backbars"):
- backbars=int(a)
- elif o in ("-a", "--all"):
- maxbars= True
- elif o in ("-m", "--market"):
- market = a
- elif o in ("-i"):
- interval = int(a)
- elif o in ("--start"):
- start = a
- elif o in ("--end"):
- end =a
- elif o in ("--pov"):
- pov = float(a)
- elif o in ("--tax"):
- tax =float(a)
- elif o in ("-q","--quote"):
- quote = a
-
- if (start or end) and strategy and market:
- # have start or end, will generate report
- main(strategy,market,backbars,interval,quote,maxbars,start,end,pov,tax)
-
- elif strategy and market and quote:
- main(strategy,market,backbars,interval,quote,maxbars)
- elif strategy and market:
- main(strategy,market,backbars,interval,quote,maxbars)
-
- else:
- print autotrader.__doc__
- sys.exit()
+ frm = FF(None)
+ frm.Show()
+
+ # DEBUG comment out following two line
+ import wx.lib.inspection
+ wx.lib.inspection.InspectionTool().Show()
+
+ app.MainLoop()
View
15 csvloader.py
@@ -11,7 +11,7 @@
import sys
import getopt
import string
-#import os
+import os
#import mmap
def csvtolist(filename="",backbars=300,maxbars=False,start="",end=""):
@@ -40,7 +40,8 @@ def csvtolist(filename="",backbars=300,maxbars=False,start="",end=""):
YYYY-MM-DD,OPEN,HIGH,LOW,CLOSE,VOLUMN
"""
- if filename:
+ dl = []
+ if filename and os.path.isfile(filename):
fp = open(filename,"rb")
#fsize = os.path.getsize(filename)
content = fp.read()
@@ -61,10 +62,9 @@ def csvtolist(filename="",backbars=300,maxbars=False,start="",end=""):
si = content.find(start)
if end:
- ei = content.find(end)
+ ei = content.rfind(end) # look up from end of file
# prepare the return list
- dl = []
if si >0 and ei>0:
lines = content[si:ei].splitlines() # this will strip \r or \n
@@ -75,7 +75,10 @@ def csvtolist(filename="",backbars=300,maxbars=False,start="",end=""):
else:
lines = content.splitlines()[-backbars:]
-
+
+ # empty file
+ if not lines: return dl
+
# check datetime combination in last line
lastline = lines[-1]
ll= lastline.split(',')
@@ -143,7 +146,7 @@ def csvtolist(filename="",backbars=300,maxbars=False,start="",end=""):
dl.append([dt,o,h,l,c,v])
- return dl
+ return dl
if __name__ == '__main__':
opts, args = getopt.getopt(sys.argv[1:], "ahb:", ["all","help", "backbars=","start=","end="])
View
43 ddeclient.py
@@ -165,28 +165,29 @@ def dde_query(dde_list=[],out=""):
vv = int(float(dd.request(dd.configdict['total'])))
except:
vv = 0
- if tt.find(":")>0:
- # like HH:MM:SS
- m1 = tt.find(":")
- m2 = tt.rfind(":")
- HH = int(tt[m1-2:m1])
- MM = int(tt[m1+1:m2])
- SS = int(tt[m2+1:m2+3])
- elif len(tt)>=5 and len(tt)<=6:
- SS=int(tt[-2:])
- MM=int(tt[-4:-2])
- HH=int(tt[-6:-4])
-
- tt = datetime.time(HH,MM,SS)
- nl = [tt,pp,vv]
- #print nl
- if vv != dde_volume :
- # volume bigger than update
- fp = open(out,"w")
- pickle.dump(nl,fp)
- fp.close()
+ if tt:
+ if tt.find(":")>0:
+ # like HH:MM:SS
+ m1 = tt.find(":")
+ m2 = tt.rfind(":")
+ HH = int(tt[m1-2:m1])
+ MM = int(tt[m1+1:m2])
+ SS = int(tt[m2+1:m2+3])
+ elif len(tt)>=5 and len(tt)<=6:
+ SS=int(tt[-2:])
+ MM=int(tt[-4:-2])
+ HH=int(tt[-6:-4])
- dde_volume = vv
+ tt = datetime.time(HH,MM,SS)
+ nl = [tt,pp,vv]
+ #print nl
+ if vv != dde_volume :
+ # volume bigger than update
+ fp = open(out,"w")
+ pickle.dump(nl,fp)
+ fp.close()
+
+ dde_volume = vv
if __name__ == '__main__':
# take from HTS for example
View
1 function/General.py
@@ -108,6 +108,7 @@ def Highest(price=0,length=10):
"""price is a list
"""
return max(price[:length])
+
def Lowest(price=0,length=10):
"""price is a list
"""
View
4 order.py
@@ -90,8 +90,8 @@ def REPORT(self):
cn = self.orders[i][1]
mk = self.orders[i][2]
price = self.orders[i][3]
-
- print dt.strftime("%Y/%m/%d, %H:%M:%S,")+" %10.5f"%(price)+"%15s,"%(cn)+"%5d, "%(mk)
+ #print dt.strftime("%Y/%m/%d, %H:%M:%S,")+" %10.5f"%(price)+"%15s,"%(cn)+"%5d, "%(mk)
+ print "%s, %10.5f, %15s, %5d" % ( dt.strftime("%Y/%m/%d, %H:%M:%S"), price, cn, mk )
if mk<0:
net = net-mk*price

0 comments on commit 0f20044

Please sign in to comment.