| assembler's profileUnknownPhotosBlogLists | Help |
Talking about 太郁闷了SIGH,太可怜了。相比之下我也不算倒霉了,没过QUALIFY,hoho. Quote 太郁闷了 August 18 本周 TRADING 结果周五到周二: 0.61%, -0.28%, 1.86%, 0.80% 总计 2.99%. 星期一因为SHORT一支股票没有借到SHARE,所以没有 Open postion. 运气不错。 July 29 Real Program Trading按捺不住,上星期五,这个星期一给了 Program $3000在IB上Trade,分别挣了$7, $36。这个星期五又有 DayTrade 的quota了,给了$6000挣了$67。不错。开始转钱以便可以每天做 DayTrade。按照我前三个星期在 Equitrader上用 Practice Portfolio的模拟结果,貌似只做一只股票有 14%的 Return。第二只只有 6%,第三只 -5%。所以准备继续只作一只股票。 July 14 A Terrible Week这个星期股票仅在星期二有次小反弹,其余时间都在狂泻不止。我从上周末转为LONG之后,HOLD的AMKR,MRVL,ZRAN都跌了10%,把前几个星期小心翼翼SHORT挣的钱全赔进去了。今天痛下决心CUT LOSS。目前只HOLD short BIDU at 87.5. Program 的运气也不好。这一段跌起来几乎没有反弹。一个星期损失 -7%。好在 Practice portfolio 模拟限制最多HOLD 3个 Position还没赔多少,大概是 -1%,就是如果用真钱的话。希望下个星期能有 Positive return。 另外目前的程序已经具备通过IB Trade real money 的能力。就看到下几个星期做得好不好了。 July 05 Monthly trading 2上个月,主要以 short high/cover low 为主,尽量少hold position,终于以 11.35% 的 return 拿到第一,挣了 $300. 领导继前个星期在weekly胜出之后,又在 monthly 拿到第三,表现神勇。 MTC2 Standings 上个星期的 Weekly trading 我的 Program 第一次挣了 2.7%,趁着星期四的 rally。今天用2004年的数据模拟了一下,发现我最初的追涨杀跌算法一年赔 54%。好在它赔得很 consistent,于是把原来的算法反过来,变成低买高卖,居然能有 100%的 return,而且在2005的数据上run也有100%的 return。有一点问题是我都是用的MARKET price 成交,所以实际 trade 可能有 spread上的损失,但不会很大。还有一个问题就是有时short不一定能成功。Anyway, it looks promising. June 23 Program Trading 第二周上周程序在调试阶段,时好时坏,最后赔了0.93%。这个星期程序运行基本正常,但开头两天的算法不太好,最后赔了 -0.22%。 http://www.equitrader.com/trader/xco/viewLeaderBoard?competitionId=13 自从上个月的惨跌以来,自己的 Portfolio 跌回年初的水平。好在这一两个星期吸取了教训,高涨时SHORT一些基本面不好的股票,跌的时候COVER,终于又挣了5%。Anyway,从头开始吧。 熊市刚来的时候在 Equitrader 的WTC and MTC简直惨不忍睹,一个星期居然 -11%, MTC1 -23%。现在用ROBOT做WTC Trading,自己做的Monthly MTC2还不错,目前有 8%了。希望能保持拿个第二就有 150刀了。目前 jdmetz 排第一。 http://www.equitrader.com/trader/xco/viewLeaderBoard?competitionId=16 May 28 From Compiler to Loader - II继续看看内存管理在Visual C++中是如何实现的. mainCRTStartup的头几步工作是初始化一些预定义的全局变量, _osplatform, _winmajor, _winminor, _osver, _winver等与Windows Version 有关的. 然后很重要的一步就是初始化 Heap. 大多的内存都是 Heap 上分配的, 如 new, malloc. 所以必须要先初始化才能干别的. 这个函数是_heap_init. 以前的Compiler 有些用自己的 Heap 管理, 但是现在我手上的 Visual Studio .NET 2003, 完全是用的 Windows 系统提供的 Heap management. 所以 _heap_init 很简单: int __cdecl _heap_init (int mtflag) { // Initialize the "big-block" heap first. if ( (_crtheap = HeapCreate( mtflag ? 0 : HEAP_NO_SERIALIZE, BYTES_PER_PAGE, 0 )) == NULL ) return 0; ... } 系统默认的 new, malloc 等等的分配都是在这个_crtheap 上进行的. 试试写个简单的程序: int main() { int* p = new int; return 0; } 在int* p = new int; 这一行设个断点, 调试进去. 可以看见new 是这样的: void * operator new( size_t cb ) { void *res = _nh_malloc( cb, 1 ); ... return res; } 下面以Debug version为例, 因为Debug version比较有意思. _nh_malloc 只是简单调用_nh_malloc_dbg, 而malloc 也是调用_nh_malloc_dbg来完成内存分配. _nh_malloc_dbg最终调用_heap_alloc_dbg, 在这里进行真正的分配工作. Debug Version中, 实际分配的是这样一个结构: typedef struct _CrtMemBlockHeader { struct _CrtMemBlockHeader * pBlockHeaderNext; struct _CrtMemBlockHeader * pBlockHeaderPrev; char * szFileName; int nLine; size_t nDataSize; int nBlockUse; long lRequest; unsigned char gap[nNoMansLandSize]; /* followed by: * unsigned char data[nDataSize]; * unsigned char anotherGap[nNoMansLandSize]; */ } _CrtMemBlockHeader; 假如你要分配一个大小为100的块, 则实际分配的块结构如下: _CrtMemBlockHeader + <You Data> (100 bytes) + gap[nNoMansLandSize] _CrtMemBlockHeader最后有个gap[nNoMansLandSize], 这个nNoMansLandSize目前的值是 4, 所以在你的数据前后各有4个字节的 gap. _heap_alloc_dbg会把 <Your Data> 的所有字节置为 0xCD, 前后的gap置成 0xFD. 如果你在自己的Data里写, 不小心越了界(前面或者后面), 系统在delete的时候通过检查 gap 的数据是否已被破坏,就知道你有没有越界. 当然了, 如果你恰好写的都是0xFD, 那就没法知道了. 试试如下程序: int* p = new int; p[1] = 0; delete p; 在Debug 下运行时,delete 时系统会报错: DAMAGE: after normal block (#59) at 0x00375C80. _heap_alloc_dbg调用 Windows System Call HeapAlloc 完成分配. HeapAlloc返回的指针, 要先初始化 _CrtMemBlockHeader. 这个 Header 中有前后两个指针, 事实上所有的内存块连接在一起形成一个双向链表. 在 delete 或者 free 的时候, 链表指针需要调整. 如果没有内存泄漏, 程序结束的时候链表应该为空. 否则说明有内存泄漏. 如下面的程序: #include <stdio.h> #include <stdlib.h> #include <crtdbg.h> int main() { int* p = new int; //delete p; void *px = malloc(100); free(px); _CrtDumpMemoryLeaks(); return 0; } _CrtDumpMemoryLeaks 通过检查分配链表, 来查找是否有泄漏. 在 Debug 下编译并且在 VC 中跟踪运行, 最后在 VC 的 Output 中会有如下输出: Detected memory leaks! Dumping objects -> {58} normal block at 0x00375FC0, 4 bytes long. Data: < > CD CD CD CD Object dump complete. 这里只有分配的序号, 还不能知道到底是哪一行程序产生的泄漏. 但是注意看_CrtMemBlockHeader, 事实上它还能记录源程序文件名和行号. 在 MFC 里就利用了这个技术. 在 afx.h 里, 有如下声明: // Memory tracking allocation void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine); #define DEBUG_NEW new(THIS_FILE, __LINE__) 同时,使用 MFC 时产生的 cpp 文件开始都有如下定义: #ifdef _DEBUG #define new DEBUG_NEW 这个 afx 的 new operator 把 new 时发生的源文件和行号传给 _malloc_dbg .这样在 Dump memory leak 的时候就可以同时知道泄漏的数据最初是在什么地方分配的. delete 和 free 最终都是用的 _free_dbg. _free_dbg 首先检查前后的 gap 有没有被破坏, 然后把该块从链表中去掉, 最后把数据块全部置成 0xDD.这样如果你不小心使用了已经被删除的数据时,通常数据已经被破坏而出错. 以上说的都是 Debug Version. 如果是 Release version, 内存分配更简单, 没有任何 overhead, 系统直接调用 HeapAlloc 分配所需的内存块. 同时分配的内存块也不会被初始化为 0xCD. 基本上VC Runtime Library 的内存分配管理是直接交给了 Windows System, 除了 Debug Version 用了一些技术来检测越界, 泄漏等. 如果要了解 Windows System 的 Heap management , 当然还是得看Microsoft Windows Internals 这本书了. From Compiler to Loader - IBLOG上保存一下,有时间把它写全. 要知道一个程序怎么从编译到执行,首先得了解一下 PE 文件格式,也就是我们常用的 Windows Executable 的格式。(事实上这种格式并不只限于 Windows Exectuable)。关于这个 topic 最好的文章是 Matt Pietrek写的An In-Depth Look into the Win32 Portable Executable File Format,网上 google 一下即得。简单来讲,PE格式的文件 Header里包含下面的结构: IMAGE_DOS_HEADER IMAGE_NT_HEADERS 如果你用Hex editor打开一个executable文件,最前面是IMAGE_DOS_HEADER,这个一般不太重要.紧跟其后的就是IMAGE_NT_HEADERS. 这些结构定义在 <winnt.h>. IMAGE_NT_HEADERS定义如下 (以32bit为例): typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 其中,IMAGE_OPTIONAL_HEADER32定义如下: typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; //Entry Point DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; ... DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; ... IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; IMAGE_OPTIONAL_HEADER32 中, AddressOfEntryPoint定义了程序的入口点, 即当Windows系统完成Loading之后, 从哪个Virtual Address开始把控制转给executable本身. 不过这个入口函数既不是Windows启动一个Process时开始执行的第一个函数, 也不是C++程序里面的main函数. 关于Windows Kernel 如何完成Process loading的, 在Mark E. Russinovich, David A. Solomon的Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server(TM) 2003, Windows XP, and Windows 2000 里面讲得比较清楚. 我们就考虑系统把控制转到EntryPoint之后吧. Visual C++的编译器的executable的入口函数是mainCRTStartup, 或wmainCRTStartup if compiled as UNICODE, 以上是编译Console Executable.如果是Windows程序, 则是 (w)WinMainCRTStartup. 函数定义在 crt0.c 里可以找到. 通常在main函数里设个断点, 停下来后在 Callstack里就可以点到mainCRTStartup里去看看. 你也可以定义自己的入口函数, 然后用Linker选项: /ENTRYR指定自己的入口函数. 但是因为入口函数干了很多初始化 C++ Library之类的工作, 所以如果你自己的入口函数没有做类似的初始化的话, 多半程序没法运行. Linker 编译的时候, 确定了入口函数的地址, 就把这个地址写入PE Header中. May 27 CreateRemoteThread NotesIt's easy to forget. So write it down: 1. Disable Project setting: Linker->General->Enable Incremental Linking. Otherwise the function pointer will only point to a small stub and not the real function body. 2. In Project setting->Code Generation->Basic Runtime Checks, set it to default. Otherwise it will generate stack/cookie checking code before and after function ends, calling functions that don't exist in the remote process. Assembly code is like this: { 00419FB0 push ebp 00419FB1 mov ebp,esp 00419FB3 push ecx 00419FB4 push esi 00419FB5 mov dword ptr [ebp-4],0CCCCCCCCh return 0; } 00419FBC xor eax,eax 00419FBE pop esi 00419FBF add esp,4 00419FC2 cmp ebp,esp 00419FC4 call _RTC_CheckEsp (4B49B0h) 00419FC9 mov esp,ebp 00419FCB pop ebp 00419FCC ret 4 May 17 体验真熊上个星期三开始,坏消息不断.各方面来看,经济在放缓,Inflation在增加.于是市场不断狂泻.可惜我没有及时止损,以为自己手里主要拿的是油股就没事.但真熊来了谁也挡不住,眼睁睁看着每天的LOSS逐渐增大.今天终于忍痛割了.这样今年本来所有帐号总共 20%的gain 只剩下不到 5%.残酷. 教训:cut loss一定要坚决.如果我在个股掉下 2-3%的时候 cut,完全可以守住战略成果.最后基本上都损失了 10-20%左右才cut,极不明智. 准备持币观望一阵,至少不要买什么股票了.等到下星期局势明朗再说. April 29 被程序 Beat 了WTC4, 这个星期自己做的不错,4.8%的 Return。没想到jdmetz,以前一直赔钱倒数的,竟然达到了5.88%。我一奇怪他怎么会突然这么强,原来这个星期他一直是用程序做的交易!看了他在论坛上发表自己程序的算法,简单但是很有意思。据他自己用历史数据测试的结果,基本上从2000年到2005年能达到每年100% - 500%的 Return。很 amazing。我想我也应该试验一下。每天不用操心坐在那就可以自动赚钱,而且风险低,多爽。 这个星期的结果: http://www.equitrader.com/trader/xco/viewLeaderBoard?competitionId=5 周末开始用 Equitrader 的程序接口写程序。第一步先做辅助下单。下个星期同时开始 Weekly and Monthly competition,需要用程序做到两个protfolio 同步管理。以后可以先试试他的算法看看效果如何。 April 22 贪婪对自己很失望。WTC3,这个星期本来不错,Monday 1.72%, Tuesday 4.5%, then 6.8%, 6.5%, 星期四如果把那几只出ER的股票清了,SNDK, VRSN, BRCM,应该就可以稳居第一了,可偏要再赌一把。结果惨了,三只全不中,星期五又是market不好,加上Option Expire,最后只剩下 3.3%,排在第九。教训:第一不可过贪,第二再也不要赌Earning了。 April 18 第一天不错早上很凶险,AAPL看看要往下掉,赶紧66.55卖了,没有赔钱。Today, bought NVDA 29.51 -> 29.68 PTEN 32.00 ->32.82 MOT for tomorrow's ER at 24.1 -> 23.58 比较失败的FLEX,上周五刚卖掉,今天出消息说要卖个部门给KKR, 涨了 4.x%. 另WTC3第一天,1.72%暂时第一。今天 Daytrade 比较有感觉,short/cover/buy的时机把握得不错。 WTC2的comments: assembler continues with hot handCongratulations to assembler for winning the 1st place prize! Glastonbury, Conn (EP) - After coming up just short in WTC1 (view standings), assembler turned in another fine performance in WTC2 (view standings) to claim victory. At the close on Wednesday, assembler's return was a modest 0.81% but it kept him near the top. He added two full points on the last trading day to easily take first place. Rounding out the top three were Mg9H and Digibomb. President, Doug Rivard, had nothing but praise for assembler. According to Rivard, "He's been our best performer over the first two contests. Very consistent. We are looking forward seeing him in future competitions." April 14 WTC2 挣了$50WTC2终于以2.83%结束,挣了$50,第二名只有0.66%。目前等级分2035,暂列第一,呵呵。 http://www.equitrader.com/trader/xco/viewLeaderBoard?competitionId=3 这个礼拜也是败中求胜,争取下个礼拜稳妥地挣钱。 另外自己的帐户,卖了AMKR at 9.1, FLEX at 10.79。FLEX太没劲了,一点不涨还跌。进了 AAPL at 66.6, FTO at 57.1, NVDA at 29.6。如果AMKR下跌下周再买进。 April 10 方向今天比较倒霉。早起时纳指还没跌,long了AAPL, SNDK,MRVL, 中午时发现势头不好才开始
short。但是已经损失了很多。亏损的时候又short了GOOG, 结果它收盘时开始跑,幸好COVER得早,损失不太大。早上另进了AMKR
at
8.93,结果它一直往下掉,8.71出局,丢了2500。另外一直SHORT的RIMM还比较成功。这样WTC2第一天以-0.95%结束,排在倒数第
六。 总结:AAPL,SNDK, MRVL,这三只股最近基本一起动,如果看准方向一起操作会很挣钱;反了的话赔钱也很快。GOOG, NVDA没事不要随便 short。 DayTrade和平常Trade很不一样。一旦有Loss很容易慌张,导致随意操作。要成为一个好的Trader,还要经过长期的训练才行。Equitrader正好可以作为一个练手的平台。 收盘前进了N多股;今天盘后发布的ALCOA的ER很好,希望明天是个牛市。 下面是 WTC1 Summary by Equitrader kkitchen1 Holds Off assembler to Take First PlaceCongratulations to kkitchen1 for winning the 1st place prize! Glastonbury, CT (EP) - In a battle for the ages, kkitchen1 withstood a frenzied late afternoon rush by assembler to hold on and claim first prize in the inaugural trading competition held by Equitrader, Inc. kkitchen1 held a seemingly insurmountable lead at the market close on Thursday. By early Friday afternoon it looked like kkitchen1 would cruise to victory lane. So confident was he that he had no trading activity on Friday. That confidence only seemed to spur on the second place trader, assembler. As the trading hours ebbed away on Friday, assembler continued his systematic trading and closed the gap to about $1K. That was as close as he would get. As the closing bell tolled on Friday, it was kkitchen1 left standing with the first place trophy. Rounding out the top five were assembler, utkarsh_prateek, MadBull and ricemutt. The complete standings can be found here: (view standings). President, Doug Rivard, was upbeat when discussing the initial contest and the results. Said Rivard, "Overall, I am pleased with the results. I am impressed with the number and quality of the participants. I would like to congratulate kkitchen1 on the victory and thank everyone for participating. This was a good start for us but there is much more to come." April 07 WTC1 结束今天employment
data比较好,股市大跌。早起时只剩1%,排在第十。我努力追赶,最多的时候也就达到2.8%。收盘时2.49%的return,排名第二。第一
名2.89%,早在星期三就清仓了。最大的失误还是在星期一星期二,众人皆涨唯我独跌。下个礼拜再战吧。 Review: On Monday and Tuesday I was pretty bearish and longed several stocks that are supposed to be independant of market, and shorted several. Then while everybody's portfolio advanced mine lost a lot and ranked near the last. I think my return was about -1.3%. On Wednesday I realized my mistake and started buying with full margin with all the hot stocks, AAPL, MRVL, NVDA, AMKR, NTES, ATYT etc. Then it goes back to 0.3%. I leave them overnight with expectation that Thursday would be good (I was desparate). Thursday turns out to be good. With the employment data coming on Friday (big risk like today) I sold half of them. Then I had 2.25% This morning I got up at 9am (PST) and see mine has only about 1.1%. Notificing the market is moving up I immediately bought pretty much the same stocks as Wednesday with margins. It reached as high as 2.8%, close to the first place. However, the market lost strength before the final two hours. I sold everything when I reached 2.4%, then started shorting. It's a little bit late, so I finally end up with only 2.52%. Looking back, the biggest mistake was in the first 2 days. Should I buy instead of short, it would turn out be much better. I am glad I corrected my mistake later anyway. |
|
|