Cross Domain Ajax Request is something that is prohibited by the browser becomes it violates the Same Origin Policy. According to wikipedia, the term “origin” is defined using the domain name, protocol, port number. Two resources are considered to be the same origin if and only if all these values are exactly the same. This also implies that even if the two resources are in different subdomains, it is not allowed as well.

In order to do cross domain ajax request, there is one way to do it using JSONP. JSONP, which is short for “JSON with padding” is a complement to the base JSON data format. It provides a method to request data from a server in a different domain. This is viable because there is no restriction on including third party javascript files in the website. So here is how it works. E.g. you are requesting a server http://sampleserver.com/sampledata.json to return the following json

{ "name" : "Shanison" }

Instead of directly requesting this using XMLHttprequest, you use javascript to insert a script tag in the html,

Now the browser would send the requests and download the response, but the problem is that the response is JSON instead of javascript. So the trick here is that for server instead of returning JSON, it returns a function call with the JSON:

callBack({ "name" : "Shanison" })

After the javascript is downloaded, it will call the method callBack, which will takes the JSON as a parameter. Inside this callBack method, you can get the response of the JSON and do what ever you want.

So if you are using RAILS and JQuery, here is what you can do. Jquery provides a way to directly call ajax with JSONP as requested dataType and you don’t have to do the things as create a call back methods and create the script tag and inserted into the html. If you use jQuery, this is what you normally do ajax Request:

    $.ajax({
      url     : 'http://sampleserver.com/sampledata.json',
      type    : 'GET',
      dataType:  'json',
      success : function (response) {
        if (response['success'])
        {
          loadData(response['html']);
        }
      }
    })

To change it to use jsonp, you just need to change the dataType to ‘jsonp’, everything else remains the same. Jquery will do the magic I described for you. At the same time, it will send a parameter ‘callback’ to the server, which is the call back methods name that is generated by jQuery, it is a random name.

    $.ajax({
      url     : 'http://sampleserver.com/sampledata.json',
      type    : 'GET',
      dataType:  'jsonp',
      success : function (response) {
        if (response['success'])
        {
          loadData(response['html']);
        }
      }
    })

Now the only thing needs to be changed is on the application server. The application needs to make sure the response can return JSONP instead of JSON. If you are using Rails, to render the response in JSON, you usually do:

render :json => {:success => true, :html => prices_html}

To render the response with JSONP, which would wrap the JSON with the callback method submitted by the javascript:

render :json => {:success => true, :html => prices_html}, :callback => params[:callback]

With all this, you should be able to do Cross Domain Ajax Request using jQuery.

If you need to backup your database, you can use mysqldump command.

mysqldump -uuser -ppassword > backup.sql

If you need to dump a single table, you can do the following:

mysqldump -uuser -ppassword table_name > backup.sql

This should generate a bunch of Create Table and Insert Sql statements in the .sql files.

So how do you import the database from your sql dump files. Let’s say you have the backup.sql in your computer now. First thing you need to do is upload this dump to the database server. To do this, you can use scp command to copy the files and do a secure file transfer.

scp -rP port_num backup.sql root@server_name:/root/backup

After that you have to go to the mysql command tools by :

mysql -uroot -ppassword database_name

After authenticated, you run the following again to import:

source /root/backup/backup.sql

Read the rest of this entry »

I love Rails Console. If there is anything wrong with my Rails application, I can simply fire the console, and debug from there. Rails makes the query to db very simple and elegant by providing us the ActiveRecord. However, sometimes you may want to know the underlying raw sql statement being sent to the database to see if there is any problem. Especially your rails app is being quite slow, you may want to check if this could be the problem.


So you know that under development mode, the log would print out the raw sql statements executed. What about Rails Console. By default, if you typed in any code that queries the database, it would simply return the objects back to you. You can do the following in order to show the raw sql statements:


Immediately after you have entered Rails Console, typed in the following code in console:


ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)

After that, it should print out the sql queries.

Apple Store is about to hit 25 billion downloads, and it has launched a campaign that if you download the 25 billionth app, you could win a US$10,000 App Store Gift Card. You could find more information at “iTunes 25 billion App Countdown”. This is a very interesting campaign. Apple had similar campaign for 10th billion app download last year Jan. Within short span of 1 year, apple managed to hit another  15 billion app downloads. This is really amazing.



However, I am not interested in being the lucky person who download the 25th billion app. I always knew that I cannot be this lucky. Tried TOTO a few times, but end up all donating to the government.=) The only thing that attracts me a lot is the pretty cool flashing counter that it shows on the website that keep updating the total number of app store downloads. This could not be flash as this is Apple! Without investigating on anything, I guess this could be done by Comet that constantly pushing the total downloads to the website. However, after I investigate on this, I realized that this is not true, and you may be cheated by Apple, the Number You Saw on the Website is not the Actual Download on App Store. Let’s investigate on this.


First of all, this is not flash. If you ‘Inspect Element with Firebug’, you will know that this animation is done purely using javascript. One more thing, to my surprise, apple is still using prototype!


Secondly, let’s look at how this animation is done.



Look at the screenshot of the firebug inspection on the above. You can see that the numbers on the flashing counter is from the div element ‘digitImageElement’, but there is no text of numbers in the inner HTML. You should notice there is a css rule for the background image of this div. It is an image link to http://images.apple.com/itunes/25-billion-app-countdown/images/filmstrip.png This image contains some possible frame of every numbers and the frame of transition to next number. With the top position changing in the style, it is able to change the text. This is done using the following draw function in the script download counter.js. With the help of prototype effect, the animation is pretty smooth.

draw: function() {
        window.clearTimeout(this._drawTimeout);
        this._drawTimeout = null;
        var h = this._drawRefreshRate,
        e,
        j,
        k,
        c,
        a,
        l,
        o,
        b,
        n,
        d,
        m,
        p = this._digitImageHeight * this._digitImageAnimationCount,
        g,
        f = this._digitElements,
        q;
        if (this._element) {
            m = String(this._currentCount);
            this._currentCount = this._currentCount + Math.floor(this._rate * h);
            if (this._delegate && typeof this._delegate.counterDidReachValue === "function") {
                this._delegate.counterDidReachValue(this, this._currentCount)
            }
            if (this._maxCount && this._currentCount >= this._maxCount) {
                this._isCounting = false
            }
            if (!this._isCounting) {
                return
            }
            e = (this._maxCount && this._currentCount >= this._maxCount) ? String(this._maxCount) : String(this._currentCount);
            j = e.length;
            k = j - 1;
            for (c = k; c >= 0; c--) {
                l = parseInt(e.charAt(c));
                o = parseInt(m.charAt(c));
                if (l !== o) {
                    if (! ((k - c) < f.length)) {
                     this._createDigitElements()
                    }
                    a = f[k - c].lastChild;
                   if (a.___animating !== true) {
                        n = o * p;
                        if (l > o) {
                            b = l * p
                        } else {
                            b = (o + (10 - o) + l) * p
                        }
                        if (a.style.top !== (d = "-" + n + "px")) {
                            a.style.top = d
                        }
                        g = 1 + ((b - n) / this._digitImageHeight);
                        a.___animating = true;
                        q = new Effect.Move(a, {
                            x: 0,
                            y: ( - 1 * b),
                            duration: 0.4,
                            mode: "absolute",
                            transition: StepTimingFunction.timingFunctionForStepCount(g)
                        });
                        q.__element = a;
                        q.finish = function(i) {
                            if (window.removeEventListener) {
                                window.removeEventListener("unload", arguments.callee, false)
                            }
                            if (this.__element !== undefined) {
                                this.__element.___animating = false
                            }
                        };
                        if (window.addEventListener) {
                            window.addEventListener("unload", q.finish, false)
                        }
                    }
                }
            }
        }
        this._lastReferenceTime = (this._lastReferenceTime + h);
        this.setNeedsDisplayIfNeeded()
    }

Thirdly, how the counter is incremented. This is not done by comet! It download the initial app store download counts from this link http://www.apple.com/autopush/us/itunes/includes/countdown.inc. You should see something like this in the response.

26-Feb-2012 06:00:00|24734848066|2569693

Each component is seperated by  | . The first component 26-Feb-2012 06:00:00 is the last update time  of the total download in GMT-0700, which is the  US Mountain Time Zone time. The second component 24734848066 is the actual total apple store download count on the time 26-Feb-2012 06:00:00. The last component 2569693 means the total download in one hour, this is the rate that would be used in the javascript to calculate the speed of download in mini seconds. If you refresh the link of countdown.inc, the data is not really refreshed. I observed that this data is actually only updated every one hour.


I summary how apple is updating the download count you saw on the website in the following formula:

Total Download up to Last Hour +
 (Current Time - Last Download Update Time) * (Hourly Download Count / 3600000 )


Instead of using new Date() to get the current time, it is using localServerBasedReferenceTime, which is the ‘Date’ attribute on the Response Header for the request for countdown.inc. This makes sense, as time on the user’s computer may not be correct and the time on their own server is always more trustable. So now you know that What You See on Screen is Not The Actual Download on Apple Store.


If you read the following code snippets, you will understand better all what I said

dataRequestDidFinishLoading: function(o) {
        var k = o.responseText.split("|"),
        n,
        d,
        j,
        g,
        l,
        h,
        b,
        f,
        e,
        m,
        a,
        i,
        c;
        localServerBasedReferenceTime = Date.parse(o.getResponseHeader("Date"));
        if (k.length === 3) {
            n = k[0].split(" ");
            d = n[1];
            date = n[0].split("-");
            this.setRate(parseInt(k[2]) / 3600000);
            l = date[0];
            g = date[1];
            j = date[2];
            a = Date.parse(g + " " + l + ", " + j + " " + d + " GMT-0700");
            e = new Date(a + 3600000);
            m = e.getTime() - a + 1000;
            this._nextUpdateTimeout = setTimeout(this.loadData.bind(this), m);
            if (localServerBasedReferenceTime) {
                this._lastReferenceTime = localServerBasedReferenceTime
            } else {
                b = new Date();
                this._lastReferenceTime = b.getTime()
            }
            f = this._lastReferenceTime - a;
            i = Math.floor(parseInt(k[1]) + f * (this._rate));
            this.setCurrentCount(i);
            this.setNeedsDisplayIfNeeded();
            if (this._delegate && typeof this._delegate.didLoadData === "function") {
                this._delegate.didLoadData.call(this)
            }
        }
    },

I guess when the actual download is approaching 25th billion, apple would update the countdown.inc file more often in order to make it more accurate to show the total downloads.

不管是在股市还是在外汇交易中,最简单的方法就是找出当前的趋势线,并且跟随当前的趋势进行交易。趋势线在技术分析中是很简单的一个概念。“在一个价格运动当中,如果其包含的波峰和波谷都相应的高于前一个波峰和波谷,那么就称为上涨趋势;相反的,如果其包含的波峰和波谷都低于前一个波峰和波谷,那么就称为下跌趋势;如果后面的波峰与波谷都基本与前面的波峰和波谷持平的话,那么成为振荡趋势,或者横盘趋势,或者无趋势。”

欧元美元15分钟走势图2012年2月16日

欧元美元15分钟走势图2012年2月16日

以上图表是欧元美元的在2月16号的15分钟走势图。在上图中你可以看到一个很明显的下行的通道。在这种下行的通道下最好的做法是当它碰触到此通道的顶部的时候你去卖空如图中A点所示,然后在碰触到底部的时候买回来如图中B点所示。每次上升和下降不是都能碰触到这个通道的顶部和底部,例如D点。它还未碰触到底部就反弹了,形成了下一个波浪。所以要想玩这种通道,有几点是可以借鉴的。

 

第一,不要贪婪。贪婪是人性最大的弱点。做人要有欲望,如果无欲,那就无任何追求可言,那你就没有这个动力去在大千的市场中进行交易寻找利润,最终你就只有平平淡淡的过完一生。然而有欲望还是不够的,要有足够的行动力。不要妄想,把想法变成行动,你才能证明自己的想法,证明自己的能力。欲望很容易拥有,但是一定不要有急于求成的心态。世界没有免费的午餐,那些买彩票中了大奖的人可能上辈子或者下辈子很苦的才换来了今世的幸福。这种幸福追求不得。一旦你有了这种寻找快钱,急于求成的心态,当你看到利润的时候,你就会露出贪婪的一面。但是很多人美好的梦想都是因为这样成为泡影。就如上图来讲,当欧元从A点跌倒B点的时候,你看着你的利润一分一秒的增加,心中窃喜,开始觉得自己就是神,自己永远不会错。当它跌倒B点的时候,你犹豫了,你觉得它还会继续跌。你会说“你看,在B点的前两三分钟它下滑的多快,这种趋势还会继续的,还是不要买回来吧,它会继续跌的。都说了cut loss shot, let profit run,奔跑吧!“当你开始说这话的时候,你已经开始为自己找理由了。殊不知,没过多久它就开始反弹了。贪婪让你的利益无法最大化,而且更可怕的是会让你从收益变成亏损,从而打击了你的斗志,你的信心。。。

 

第二,要勇于承认自己的错误。刘邦虽然武不如韩信,谋不如张良,但是他敢勇于承认自己的错误,即使当他当上了皇帝。这是他很了不起的一点。投资也是这样的。正如上面一点所讲的,你在B点的时候没有买回,你以为他会继续跌,但是你错了,它开始回弹。你不敢承认自己的错误,你觉得这只是短暂的回弹,它还是会跌回去的。这种心态要不得!正确的做法是在你错误的时候,你要敢于承认,当它回弹的时候,你应该迅速的买回来,别让你的利润萎缩了。

 

第三,适当的休息反思。特别是当你连续出现几次亏损的时候,一定要退出市场。理清自己的头绪。可能之前的策略现在已经不适用了,或者这个趋势已经变了。不要在去硬碰硬,不要和自己说”我就不信这个邪“,因为事实上它就是这么邪。但你连续几次亏损之后,你还不停的进场,你会死的更惨。原因很简单,因为在你失败多次后,你的信心开始动摇,当你买的股票稍微出现点亏损的时候,你就怕了,你会迅速的卖出,因为你不想你的亏损拉大。但是如果在正常情况下,你不会这么干。你已经失去了正确的判断能力。停止交易,平掉所有头寸是你最正确的做法!

 

股市汇市是一个充满了机遇,挑战和风险的地方。在这里赚钱很容易,但是亏钱更很容易。我觉得在 这里赚钱一次,两次不难,难的是怎样让自己持之以恒的赚钱。如果没有找到这个方法,现在赚的钱,只要你一天还在这里混,那就是一定要还回去的!所以最重要的是怎样”出来混,迟早都不用还“!如果你没有一个固定的交易方式和根据,你每次进场就真的象赌博一般,在加上人性格上的弱点,足以让你亏个精光。但是当你有一套自己固定的模式,而这个模式能让你每次进场胜出的概率超过50%以上,长久以往,你就能有一定的收益。如果有人开赌场,你知道你赢的概率是60%,如果你一次把你的钱丢进去,那你就有很大的可能输光光。但是如果你把你的钱分成几个部分,几次下来,你就能有一定的收益。同样的道理,在投资上,不要一次投入太多,它可能让你在也 没有能力入场,同时要努力学习积累经验,提高你每次入场的获胜概率