Check the url below to learn abount Dual Thrust Strategy.
https://www.quantconnect.com/tutorials/strategy-library/dual-thrust-trading-algorithm
var ChartCfg = { __isStock: true, title: { text: 'Dual Thrust Up-Down Track' }, yAxis: { plotLines: [{ value: 0, color: 'red', width: 2, label: { text: 'Up Track', align: 'center' }, }, { value: 0, color: 'green', width: 2, label: { text: 'Down Track', align: 'center' }, }] }, series: [{ type: 'candlestick', name: 'current cycle', 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 < 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 < 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); pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount); Sleep(Interval); CancelPendingOrders(); } var account = exchange.GetAccount(); if (account.Stocks > LastAccount.Stocks) { Counter.w++; } else { Counter.l++; } LogProfit(_N(account.Stocks - InitAccount.Stocks), "Profit rate:", _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] >= AmountOP) { Log("Average Price", pos[0], "amount:", pos[1]); break; } // pfn(AmountOP-pos[1]); pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]); Sleep(Interval); CancelPendingOrders(); } } function onTick(exchange) { var records = exchange.GetRecords(); if (!records || records.length <= 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 > 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 > 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: 'Up Track: ' + UpTrack + ' Down Track: ' + 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 >= UpTrack) { msg = 'Long Price: ' + Bar.Close + ' Up Track:' + UpTrack; Log(msg); Trade(State, STATE_LONG); State = STATE_LONG; chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: 'Long', text: msg}); } } if (State === STATE_IDLE || State === STATE_LONG) { if (Bar.Close <= DownTrack) { msg = 'Short Price: ' + Bar.Close + ' Down Track:' + DownTrack; Log(msg); Trade(State, STATE_SHORT); chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: 'Short', text: msg}); State = STATE_SHORT; } } } function onexit() { var pos = exchange.GetPosition(); if (pos.length > 0) { Log("Warning, has positions when exiting", pos); } } function main() { if (exchange.GetName() !== 'Futures_OKCoin') { throw "Only support OKEX features"; } exchange.SetRate(1); exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]); exchange.SetMarginLevel([10, 20][MarginLevelIdx]); if (exchange.GetPosition().length > 0) { throw "Can't have Positions when start.";} CancelPendingOrders(); InitAccount = LastAccount = exchange.GetAccount(); LoopInterval = Math.min(1, LoopInterval); Log('Exchange Name:', exchange.GetName(), InitAccount); LogStatus("Ready..."); LogProfitReset(); chart = Chart(ChartCfg); chart.reset(); LoopInterval = Math.max(LoopInterval, 1); while (true) { onTick(exchange); Sleep(LoopInterval * 1000); } }template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6