<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: LittleLittleDream</title>
    <description>The latest articles on DEV Community by LittleLittleDream (@littlelittledream).</description>
    <link>https://dev.to/littlelittledream</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F40408%2F12b94850-a21f-4b49-b50d-7ec5addc1cdd.png</url>
      <title>DEV Community: LittleLittleDream</title>
      <link>https://dev.to/littlelittledream</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/littlelittledream"/>
    <language>en</language>
    <item>
      <title>A JavaScript program to used trade bitcoin</title>
      <dc:creator>LittleLittleDream</dc:creator>
      <pubDate>Tue, 07 Nov 2017 08:33:33 +0000</pubDate>
      <link>https://dev.to/littlelittledream/a-javascript-program-to-used-trade-bitcoin-bg4</link>
      <guid>https://dev.to/littlelittledream/a-javascript-program-to-used-trade-bitcoin-bg4</guid>
      <description>&lt;p&gt;At the close of the day, calculate two values: the highest price - the closing price, and the closing price - the lowest price. Then take the two larger ones, multiply the k values, and the results are called trigger values.&lt;/p&gt;

&lt;p&gt;On the second day, the opening price is recorded, and then immediately after the price exceeds (opening + trigger value), or the price is lower than the (opening - trigger value), the short selling immediately.&lt;/p&gt;

&lt;p&gt;The system is an inversion system without a single stop. That is to say, the reverse signal is also the unwinding signal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I drew a diagramï¼š&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DQZVDa_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9vslzknoc69zo3m4ou3h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DQZVDa_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9vslzknoc69zo3m4ou3h.jpg" alt="Dual Thrust diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source code :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.botvs.com/strategy/12101"&gt;https://www.botvs.com/strategy/12101&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because I have a little programming based, feeling strategy should be easy to write , try to write a few strategies, that is not so simple. Sometimes, a very simple logic actually has a lot of problems, and needs to be repeated, structured, and written. Look at the amount of this strategy code is not great, thanks to BotVS . Dual Thrust is a classic strategy, the idea is also very direct. It is suitable for beginners to learn, learning new classmates often confused, I hope the following code can help you to master the development of program trading strategies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var ChartCfg = {
    __isStock: true,
    title: {
        text: 'Dual Thrust ä¸Šä¸‹è½¨å›¾'
    },
    yAxis: {
        plotLines: [{
            value: 0,
            color: 'red',
            width: 2,
            label: {
                text: 'ä¸Šè½¨',
                align: 'center'
            },
        }, {
            value: 0,
            color: 'green',
            width: 2,
            label: {
                text: 'ä¸‹è½¨',
                align: 'center'
            },
        }]
    },
    series: [{
        type: 'candlestick',
        name: 'å½“å‰å‘¨æœŸ',
        id: 'primary',
        data: []
    }, {
        type: 'flags',
        onSeries: 'primary',
        data: [],
    }]
};

var STATE_IDLE = 0;
var STATE_LONG = 1;
var STATE_SHORT = 2;
var State = STATE_IDLE;

var LastBarTime = 0;
var UpTrack = 0;
var BottomTrack = 0;
var chart = null;
var InitAccount = null;
var LastAccount = null;
var Counter = {
    w: 0,
    l: 0
};

function _N(v) {
    return Decimal(v).toSD(4, 1).toNumber();
}

function GetPosition(posType) {
    var positions = exchange.GetPosition();
    for (var i = 0; i &amp;lt; positions.length; i++) {
        if (positions[i].Type === posType) {
            return [positions[i].Price, positions[i].Amount];
        }
    }
    return [0, 0];
}

function CancelPendingOrders() {
    while (true) {
        var orders = exchange.GetOrders();
        for (var i = 0; i &amp;lt; orders.length; i++) {
            exchange.CancelOrder(orders[i].Id);
            Sleep(Interval);
        }
        if (orders.length === 0) {
            break;
        }
    }
}

function Trade(currentState, nextState) {
    var pfn = nextState === STATE_LONG ? exchange.Buy : exchange.Sell;
    if (currentState !== STATE_IDLE) {
        exchange.SetDirection(currentState === STATE_LONG ? "closebuy" : "closesell");
        while (true) {
            var amount = GetPosition(currentState === STATE_LONG ? PD_LONG : PD_SHORT)[1];
            if (amount === 0) {
                break;
            }
            pfn(amount);
            Sleep(Interval);
            CancelPendingOrders();
        };
        var account = exchange.GetAccount();

        if (account.Stocks &amp;gt; LastAccount.Stocks) {
            Counter.w++;
        } else {
            Counter.l++;
        }

        LogProfit(_N(account.Stocks - InitAccount.Stocks), "æ”¶ç›ŠçŽ‡:", _N((account.Stocks - InitAccount.Stocks) * 100 / InitAccount.Stocks) + '%');
        LastAccount = account;
    }
    exchange.SetDirection(nextState === STATE_LONG ? "buy" : "sell");
    while (true) {
        var pos = GetPosition(nextState === STATE_LONG ? PD_LONG : PD_SHORT);
        if (pos[1] &amp;gt;= AmountOP) {
            Log("æŒä»“å‡ä»·", pos[0], "æ•°é‡:", pos[1]);
            break;
        }
        pfn(AmountOP-pos[1]);
        Sleep(Interval);
        CancelPendingOrders();
    }
}

function onTick(exchange) {
    var records = exchange.GetRecords();
    if (!records || records.length &amp;lt;= NPeriod) {
        return;
    }
    var Bar = records[records.length - 1];
    if (LastBarTime !== Bar.Time) {
        var HH = TA.Highest(records, NPeriod, 'High');
        var HC = TA.Highest(records, NPeriod, 'Close');
        var LL = TA.Lowest(records, NPeriod, 'Low');
        var LC = TA.Lowest(records, NPeriod, 'Close');

        var Range = Math.max(HH - LC, HC - LL);

        UpTrack = _N(Bar.Open + (Ks * Range));
        DownTrack = _N(Bar.Open - (Kx * Range));
        if (LastBarTime &amp;gt; 0) {
            var PreBar = records[records.length - 2];
            chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1);
        } else {
            for (var i = Math.min(records.length, NPeriod * 3); i &amp;gt; 1; i--) {
                var b = records[records.length - i];
                chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]);
            }
        }
        chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]);
        ChartCfg.yAxis.plotLines[0].value = UpTrack;
        ChartCfg.yAxis.plotLines[1].value = DownTrack;
        ChartCfg.subtitle = {
            text: 'ä¸Šè½¨: ' + UpTrack + '  ä¸‹è½¨: ' + DownTrack
        };
        chart.update(ChartCfg);
        chart.reset(PeriodShow);

        LastBarTime = Bar.Time;
    } else {
        chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1);
    }

    LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date());
    var msg;
    if (State === STATE_IDLE || State === STATE_SHORT) {
        if (Bar.Close &amp;gt;= UpTrack) {
            msg  = 'åšå¤š è§¦å‘ä»·: ' + Bar.Close + ' ä¸Šè½¨:' + UpTrack;
            Log(msg);
            Trade(State, STATE_LONG);
            State = STATE_LONG;
            chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: 'å¤š', text: msg});
        }
    }

    if (State === STATE_IDLE || State === STATE_LONG) {
        if (Bar.Close &amp;lt;= DownTrack) {
            msg = 'åšç©º è§¦å‘ä»·: ' + Bar.Close + ' ä¸‹è½¨:' + DownTrack;
            Log(msg);
            Trade(State, STATE_SHORT);
            chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: 'ç©º', text: msg});
            State = STATE_SHORT;
        }
    }
}

function onexit() {
    var pos = exchange.GetPosition();
    if (pos.length &amp;gt; 0) {
        Log("è­¦å‘Š, é€€å‡ºæ—¶æœ‰æŒä»“", pos);
    }
}

function main() {
    if (exchange.GetName() !== 'Futures_OKCoin') {
        throw "åªæ”¯æŒOKCoinæœŸè´§";
    }
    exchange.SetRate(1);
    exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]);
    exchange.SetMarginLevel([10, 20][MarginLevelIdx]);

    if (exchange.GetPosition().length &amp;gt; 0) {
        throw "ç­–ç•¥å¯åŠ¨å‰ä¸èƒ½æœ‰æŒä»“.";
    }

    CancelPendingOrders();

    InitAccount = LastAccount = exchange.GetAccount();
    LoopInterval = Math.min(1, LoopInterval);
    Log('äº¤æ˜“å¹³å°:', exchange.GetName(), InitAccount);
    LogStatus("Ready...");

    LogProfitReset();
    chart = Chart(ChartCfg);
    chart.reset();

    LoopInterval = Math.max(LoopInterval, 1);
    while (true) {
        onTick(exchange);
        Sleep(LoopInterval * 1000);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This strategy is running on exchange named OKEX,&lt;/p&gt;

&lt;p&gt;if the proper adjustment of parameters, the effect can also be, the strategy is the daily cycle strategy (K cycle effect other relatively poor), in summary, strategy is a tool, a caution.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>bitcoin</category>
    </item>
  </channel>
</rss>
