Simulate Manual Trading in Data Playback mode  [SOLVED]

User avatar
orad
Posts: 121
Joined: 14 Nov 2012
Has thanked: 50 times
Been thanked: 20 times

Simulate Manual Trading in Data Playback mode  [SOLVED]

Postby orad » 31 Jan 2016

This study is a modified version of _ChartToolBar_Trading_ that sends orders as IOrderMarket orders similar to backtest orders. When you apply it on your chart, this allows you to simulate manual trading in Data Playback mode. You can then see the results in the Strategy Performance Report. This is useful for testing your strategy ideas before starting to write code for them.

Image

Note: Just like any other strategies, orders in this strategy are applied on the chart only after MaxBarsBack. So if you try to trade on bars before MaxBarsBack then your orders are ignored.

This strategy provides only market orders in Data Playback mode. There is a feature request here to support simulated manual trading in MultiCharts the same way we do for live trading. Please vote it up if you like this.

_ChartToolBar_PlaybackTrading_.Strategy.CS

Code: Select all

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace PowerLanguage.Strategy
{
[IOGMode(IOGMode.Enabled)]
public class _ChartToolBar_PlaybackTrading_ : SignalObject
{
public _ChartToolBar_PlaybackTrading_(object _ctx) : base(_ctx)
{
}

private ToolStripButton _infoPanel;
private ToolStripLabel _pnlLabel;
private volatile int _trackedMarketPosition;
private bool _isToolbarInitiated;

private IOrderMarket _marketLE;
private IOrderMarket _marketLX;
private IOrderMarket _marketSE;
private IOrderMarket _marketSX;

protected override void Create()
{
_marketLE = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, "LE", EOrderAction.Buy));
_marketLX = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, "LX", EOrderAction.Sell, OrderExit.Total));

_marketSE = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, "SE", EOrderAction.SellShort));
_marketSX = OrderCreator.MarketThisBar(new SOrderParameters(Contracts.UserSpecified, "SX", EOrderAction.BuyToCover, OrderExit.Total));
}

protected override void StartCalc()
{
RunOnce(ref _isToolbarInitiated, () =>
{
CreateToolStrip();
MessageBox.Show("Playback Trading is enabled. You can now simulate manual trading in Data Playback mode.",
this.Name, MessageBoxButtons.OK, MessageBoxIcon.Information);
});
}

protected override void CalcBar()
{
if (Bars.CurrentBarAbsolute() > ExecInfo.MaxBarsBack &&
Bars.Status == EBarState.Close)
{
SetMarketPosition(_trackedMarketPosition);
}
UpdatePanelInfo();
}

private void CreateToolStrip()
{
ChartToolBar.AccessToolBar(tb =>
{
var lotNumControl = new NumericUpDown
{
Minimum = 1,
Maximum = 100
};
AddItemToToolStrip(tb, new ToolStripControlHost(lotNumControl));

var tsiBuy = new ToolStripButton
{
Text = "Buy Market",
BackColor = Color.DeepSkyBlue,
ToolTipText = "Click to send Buy Market or reduce Short position"
};
tsiBuy.Click += (obj, args) => _trackedMarketPosition += (int)lotNumControl.Value;
AddItemToToolStrip(tb, tsiBuy);

_infoPanel = new ToolStripButton
{
ToolTipText = "Click to Close Position"
};
_infoPanel.Click += (obj, args) => _trackedMarketPosition = 0;
AddItemToToolStrip(tb, _infoPanel);

var tsiSell = new ToolStripButton
{
Text = "Sell Market",
BackColor = Color.LightCoral,
ToolTipText = "Click to send Sell Market or reduce Long position"
};
tsiSell.Click += (obj, args) => _trackedMarketPosition -= (int)lotNumControl.Value;
AddItemToToolStrip(tb, tsiSell);

AddItemToToolStrip(tb, new ToolStripSeparator());

var tsiPnlLabel = new ToolStripLabel
{
Text = "Profit/Loss:",
};
AddItemToToolStrip(tb, tsiPnlLabel);
AddItemToToolStrip(tb, _pnlLabel = new ToolStripLabel());

AddItemToToolStrip(tb, new ToolStripSeparator());

UpdatePanelInfo();
});
}

private void UpdatePanelInfo()
{
var mp = 0; // market position
var opl = 0.0; // open profit and loss
var tpl = 0.0; // total profit and loss
if (_isToolbarInitiated)
{
mp = CurrentPosition.Value;
opl = CurrentPosition.OpenProfit;
tpl = NetProfit + opl;
}

ChartToolBar.AccessToolBarAsync(tb =>
{
_infoPanel.Enabled = (0 != mp);
_infoPanel.Text = GetOpenPnlString(mp, opl);
_infoPanel.BackColor = GetBgColor(opl);

_pnlLabel.Text = tpl.ToString("C");
_pnlLabel.ForeColor = GetColor(tpl);
});
}

private void SetMarketPosition(int targetPosition)
{
IOrderMarket entryOrder;
IOrderMarket exitOrder;
int adjust;
var pos = CurrentPosition.Value;
var count = Math.Abs(targetPosition);
var isLong = targetPosition > 0;
string dirstr;
if (isLong)
{
entryOrder = _marketLE;
exitOrder = _marketLX;
adjust = count - pos;
dirstr = "Long";
}
else
{
entryOrder = _marketSE;
exitOrder = _marketSX;
adjust = count + pos;
dirstr = "Short";
}

if (adjust == 0)
{
//Output.WriteLine("{0}\t Pos: {1}\t Target: {2}\t HOLD", Bars.TimeValue, pos, targetPosition);
}
else if (adjust > 0)
{
if ((isLong && pos < 0) || (!isLong && pos > 0)) adjust = count;
Output.WriteLine("{0}\t Pos: {1}\t Target: {2}\t {3} Entry: {4}", Bars.TimeValue, pos, targetPosition, dirstr, adjust);
dirstr = dirstr[0] + "E" + adjust;
entryOrder.Send(dirstr, adjust);
}
else // adjust < 0
{
adjust = -adjust;
Output.WriteLine("{0}\t Pos: {1}\t Target: {2}\t {3} Exit: {4}", Bars.TimeValue, pos, targetPosition, dirstr, adjust);
dirstr = dirstr[0] + "X" + adjust;
exitOrder.Send(dirstr, adjust);
}
}

protected override void Destroy()
{
if (_isToolbarInitiated)
{
ChartToolBar.AccessToolBar(tb =>
{
var itemsToErase = new List<ToolStripItem>();

foreach (ToolStripItem item in tb.Items)
if (ReferenceEquals(this, item.Tag))
itemsToErase.Add(item);

foreach (var item in itemsToErase)
tb.Items.Remove(item);
});
}
}

#region Helpers
private void RunOnce(ref bool flag, Action action)
{
if (!flag)
{
action();
flag = true;
};
}

private void AddItemToToolStrip(ToolStrip tb, ToolStripItem item)
{
item.Tag = this;
tb.Items.Add(item);
}

private static string GetOpenPnlString(int mp, double opl)
{
var str = (mp > 0) ? mp + " Long"
: (mp < 0) ? -mp + " Short"
: "Flat";

return String.Format("{0} {1}", str, opl.ToString("C"));
}

private static Color GetBgColor(double opl)
{
return opl > 0 ? Color.LawnGreen
: opl < 0 ? Color.OrangeRed
: Color.FromKnownColor(KnownColor.Control);
}

private static Color GetColor(double opl)
{
return opl > 0 ? Color.Green
: opl < 0 ? Color.Red
: Color.FromKnownColor(KnownColor.Control);
}
#endregion

}

}
Attachments
Playback Trading ToolStrip.png
(2.59 KiB) Downloaded 2271 times

robinheck
Posts: 3
Joined: 15 Dec 2017
Has thanked: 3 times

Re: Simulate Manual Trading in Data Playback mode

Postby robinheck » 02 Jan 2018

I like this idea.
Is that only MC.NET can do this?
Can MC do this too?

lordongi
Posts: 29
Joined: 18 Dec 2017
Has thanked: 10 times
Been thanked: 3 times

Re: Simulate Manual Trading in Data Playback mode

Postby lordongi » 13 Mar 2018

Thanks a lot!

webcharacter
Posts: 1
Joined: 06 Oct 2017

Re: Simulate Manual Trading in Data Playback mode

Postby webcharacter » 11 Jun 2019

Thank you, Orad, this is very useful. However, one problem I'm having is that the entry time and price that I'd like to execute on the close of the current bar, executes on the close of the following bar instead. The same thing happens with the exits. Essentially, I'm always one bar late on both entries and exits. I've worked with the code and the signal properties a little, but no success yet. Have you seen this behavior?

Thank you, Brian Warren

User avatar
orad
Posts: 121
Joined: 14 Nov 2012
Has thanked: 50 times
Been thanked: 20 times

Re: Simulate Manual Trading in Data Playback mode

Postby orad » 13 Jun 2019

Thank you, Orad, this is very useful. However, one problem I'm having is that the entry time and price that I'd like to execute on the close of the current bar, executes on the close of the following bar instead. The same thing happens with the exits. Essentially, I'm always one bar late on both entries and exits. I've worked with the code and the signal properties a little, but no success yet. Have you seen this behavior?
Hi webcharacter, I don't remember but try playback by ticks, or enable bar magnifier and see if that will correct it.

bomberone1
Posts: 310
Joined: 02 Nov 2010
Has thanked: 26 times
Been thanked: 23 times

Re: Simulate Manual Trading in Data Playback mode

Postby bomberone1 » 20 Oct 2019

Is there the code to Simulate Manual Trading in Data Playback mode also in multicharts easylanguge?

User avatar
dataheck
Posts: 30
Joined: 19 Nov 2019
Location: Amherst, Nova Scotia
Been thanked: 5 times
Contact:

Re: Simulate Manual Trading in Data Playback mode

Postby dataheck » 22 Jul 2021

Thanks for sharing! This is almost perfect for me, unfortunately it seems like the Paper Trader requires a live connection to the data provider for this to work. I have a large database of historical data but no active data provider account. The orders stay "Submitted" but never get filled. The wiki page on Paper Trader indicates that it only works if your data provider provides bid and ask prices, maybe related. Frustrating to be blocked by what seems to be so small a problem; I don't need live data to simulate trading on old data. I'll happily accept daily close prices as fill prices, I'm not looking for a flawless simulation here.

I've tried to be clever by exporting my data to .CSV and importing it under the ASCII provider. I imported trade data into bid, ask, and trade fields, but trading on this new virtual symbol still doesn't get filled orders. Shame :(

I've upvoted the playback trading project management issue, would love to see this implemented.

e:

My issue seems to be that CalcBar doesn't get executed on playback steps, so the market position doesn't get updated. Maybe I could use a timer to execute this instead or something.

User avatar
orad
Posts: 121
Joined: 14 Nov 2012
Has thanked: 50 times
Been thanked: 20 times

Re: Simulate Manual Trading in Data Playback mode

Postby orad » 05 Aug 2021

...unfortunately it seems like the Paper Trader requires a live connection to the data provider for this to work.
Hi, I wrote this a long time ago and I don't remember much, but as long as you can run your chart in Data Playback mode with your offline data, you should be able to use this tool.

et1hugo
Posts: 9
Joined: 25 Oct 2017
Has thanked: 5 times
Been thanked: 1 time

Re: Simulate Manual Trading in Data Playback mode

Postby et1hugo » 12 Feb 2023

Hi all,

I hope MC adds this functionality for an extendible chart trader that works with the playback. Anyway, I wrote this strategy that seems to work well with the playback, it supports the following functions:
  • Absolute size entries
  • Percentage of account risk based entries based off a planned stop loss
  • Entry condition based off the volume traded, uses average and standard deviation to determine this
  • Breakout and fade entries
  • Exit whole position or partial positions
  • Exit position using a bracket exit
  • Renders the orders on the chart to give you a visual indication of where your orders are
The attached pln file contains the .Net strategy, volume with SD (standard deviation) and volume with SD function.

I tried to test it as best I could and it seems to be working pretty well, here's a screenshot of what it looks like, it uses a few lines on the toolbar but it should not be an issue if you have a fairly good screen size to work with.

Image

PS. The only pain with the toolbar is that the chart seems to capture the keyboard input focus so I had to make all the input boxes used for price entries read-only (keyboard does not work with them) and you can only edit them using the up/down arrows. The PriceIncrement parameter can be used to control by how much the price increases in these input boxes.

There's a handful of "TODO's" in the comment at the top of the strategy, these would be nice-to-haves feel free to edit/extend it and share updates, there's a Debug parameter that when enabled would output debug messages in the Power Language Editor.

Good luck
Attachments
Advanced Trade Toolbar.png
(63.99 KiB) Not downloaded yet
ChartTrader_Advanced20230212.pln
Advanced chart trader
(15.59 KiB) Downloaded 81 times

User avatar
Kate MultiCharts
Posts: 575
Joined: 21 Oct 2020
Has thanked: 7 times
Been thanked: 144 times

Re: Simulate Manual Trading in Data Playback mode

Postby Kate MultiCharts » 19 Mar 2024

Dear Users!

Simulated trading is now available in MultiCharts 15.
Please see our blog and the How to Use Simulated Trading Wiki for more info.


Return to “User Contributed Studies”