image3979.png In this paper, I will show how to use graphic components included in S#.API, in order to create a fully-featured application of the S#.Shell: You will learn how to make a professional-level program with connection settings, output of securities, prices, and charts (and all this is saved and loaded upon restart). And the complexity of creating such an application is not a few months, but just a few hours (it is no joke! read to the end). This is the main advantage of the graphic framework, which I called by analogy S#.UI (this name is unofficial, I think it up myself). I will not use complex constructs and design patterns that are understandable only to professional programmers. On the contrary, the paper\u0027s purpose is to show that the learning curve on creating your trading applications using S#.API is very short. You will also be interested if you work in a company and make your own unique software (for example, you work in proprietary trading or a brokerage company). In this paper, you will be able to learn the practice of creating such systems (especially if you have just taken up your duties). What You Need 1) Visual Studio 2017 (Community, free version), in which we will program. 2) Free connection to test exchange trading, I will use QUIK. Creating Project We create a new WPF application in Visual Studio. image5545.png After that we need to add the S#.API libraries, and how to do this is described here. I prefer installing with Nuget. Since all S#.API graphic elements are based on DevExpress, and DevExpress libraries are included in S#.API, it would be foolish not to use them. All information about DevExpress graphic elements can be found in Google. Let\u0027s go to the MainWindow.xaml window editor. image4259.png We replace Window with DXWindow, we will need it to use different color schemes. image4329.png Visual Studio will prompt us to add the necessary libraries. We split the window into three parts, there will be a bar with buttons of connection setting and connection at the top. The window with logs will be below. All other panels are in the middle. The easiest way is to split the window in this way using LayoutControl from DevExpress. We will add the elements we need to the resulting three parts. image2275.png Configuring Connection to Connector We add two buttons, one button to configure connection and the second button to connect. To do this, we use the SimpleButton button from DevExpress. The buttons will be located at the top of application. We will place pictures familiar with Terminal and Designer on each button. image9977.png We will see such an image in the upper right corner of the screen form. image1157.png We double-click each button to create button click event handlers. In MainWindow code it is necessary to declare the connector, as well as the file location and name where the connector settings will be stored. image836.png We will open the connector configuration window in the connector settings button click event handler and save it to a file. image1289.png We will check in the constructor whether there is a directory and a file with the connector settings and, if there is one, we will load it into the connector. image3497.png Most S#.API objects have Save and Load methods, with which it is possible to save and load this object from an XML file. We connect the connector in the connection button click event handler method. image6463.png Now we can run the program and test it. Setting Dark Theme I prefer a dark theme. Therefore, we make the program theme dark at once. To do this in the App.xaml file image1012.png We replace Application with charting:ExtendedBaseApplication. Visual Studio will prompt us to add the necessary libraries. And in the file App.xaml.cs delete \": Application\". The code will be the following. image4777.png image9701.png We write ApplicationThemeHelper.ApplicationThemeName = Theme.VS2017DarkName in the MainWindow constructor; Full code at the moment: image8484.png Run to check the dark theme. image1199.png Creating Security Panel We add the XAML folder where we will store all the created controls. We add our first UserControll to the folder, let\u0027s call it SecurityGridControl. image5159.png We add one SecurityPicker element to it. In which the available securities will be displayed. Similar to the main window, we will use LayoutControl from DevExpress. image2385.png We go to the main window constructor and change the central part to the tab view. We place created control with SecurityPicker in one of the tabs. image5375.png Now we have the security panel, we need to set it a data source, in our case it is a connector. It was possible to write SecurityPanel.SecPicker.SecurityProvider = Connector in MainWindow constructor. But we will not place code in the MainWindow that is not related to it. Therefore, I will create the Instance static variable, and assign it the MainWindow value in the MainWindow constructor. image1508.png Now we can call the MainWindow properties anywhere in our program using MainWindow.Instance.XXX code. In the SecurityGridControl constructor, we specify Connector as a data source. image6003.png We run the program to check. image8483.png Adding Logging The operation of the program, connector or robot must be monitored. For this purpose, S#.API has a special LogManager class. This class receives messages from sources and sends them to listeners. In our case, the sources will be Connector, strategies, etc., and listeners will be a file and log panel. In the MainWindow code, we declare the LogManager object and the location where it will be stored. image3414.png In the MainWindow constructor, we create LogManager, set in it Connector as the source, and a file as the listener. image5931.png Similar to the security panel, we create a log panel, add another UserControl to the XAML folder. We call it MonitorControl. We add the Monitor element to it. image4717.png In the MonitorControl constructor, we set Monitor as a listener in LogManager. image8141.png We add the created MonitorControl to the bottom of MainWindow. image5572.png We run the program to check. image6299.png Creating Portfolio Panel Similar to the security panel, we create a log panel, add another UserControl to the XAML folder. We call it PortfolioGridControl. We add the PortfolioGrid element to it. image68.png In PortfolioGridControl constructor, we need to subscribe to new portfolio appearance events and event of new position appearance at Connector. image1333.png Thus, when a new portfolio appears, it will be displayed in the portfolio panel, and when a new position appears in the portfolio panel, the portfolio will update the position. We add the created PortfolioGridControl panel to the central part of MainWindow. image127.png We run the program to check. image3862.png We have a tab with portfolios. Creating Order Panel The order panel in S#.API has the ability to register orders, cancel orders and reregister them. Similar to the security panel, we create an order panel, add another UserControl to the XAML folder. We call it OrderGridControl. We add the OrderGrid element to it. image4502.png OrderGrid has the OrderRegistering event, the OrderReRegistering event, and the OrderCanceling event. Let\u0027s create their handlers. image6128.png In the order registration event handler, we create an OrderWindow window where we need to specify data sources for securities, portfolios, and market data. For all cases, this will be the Connector. After that, we call OrderWindow using ShowModal method, if the OK button was clicked in this window, we register the order via the connector using the RegisterOrder method. image4848.png We do the same in the order reregistration event handler. Only in this case the event receives the Order object - this is the order that needs to be reregistered. Therefore, in OrderWindow, we specify Order = order.ReRegisterClone(newVolume: order.Balance) to fill in the fields of the OrderWindow window. After that, we call OrderWindow using ShowModal method, if the OK button was clicked in this window, we will reregister the order via connector using the ReRegisterClone method. We pass to it old order, which should be cancelled, and the new one, which should be registered. image1314.png In the order canceling event handler, it is enough to call the CancelOrder method and pass to it the order that need to be canceled. image2355.png In order for Orders to be displayed in the OrderGrid, it is necessary in the OrderGridControl constructor to subscribe to new order appearance events and to a registration error event and pass these events to the OrderGrid. image9790.png We add the created OrderGridControl panel to the central part of MainWindow. image4806.png We run the program to check. image7488.png Creating Panel of Own Trades Similar to the security panel, we create a panel of own trades, add another UserControl to the XAML folder. We call it MyTradeGridControl. We add the MyTradeGrid element to it. image3653.png In the MyTradeGridControl constructor, we need to subscribe to the new own trade appearance events and pass it to MyTradeGrid. image7227.png We add the created OrderGridControl panel to the central part of MainWindow. image3738.png We run the program to check. image514.png Creating Order Book Panel Similar to the previous panels, we create an order book panel, add another UserControl to the XAML folder. We call it MarketDepthControl. In MainWindow we have already used LayoutControl, in this control we will also use LayoutControl. We split the panel into two parts horizontally. image1678.png We add SecurityPicker to the left side, we use it when we created the security panel. image7627.png Let\u0027s split the right part into vertical parts. There will be an order book on the top right. image1159.png In MarketDepthControl, we need to set some MaxHeight value, otherwise the application will not start. Below the order book we will place the elements of specifying a portfolio, price, and order volume. image8282.png Here it is worth noting the Label property of LayoutItem, it allows to set the text over the element. And also the SpinEdit element from DevExpress, in which it is convenient to set numerical values. These elements look like this. image4967.png Even below, we will place the buttons to buy, sell. image62.png Full code. image9810.png In the MarketDepthControl constructor, we set the security source for SecurityPicker and the portfolio source for PortfolioComboBox, in our case it will be Connector. image651.png We create a security selection event handler in SecurityPicker. We check in it whether the selected security is not equal to zero. If it is not equal to zero, we save the received security to a local variable, we will need it when updating the order book. After that, we clear and register the received security in Connector to receive an order book using the RegisterMarketDepth method. Using the GetMarketDepth method, we get the current order book on security to update the MarketDepthControl. image3667.png To keep the order book updated in the MarketDepthControl constructor, we will subscribe to the MarketDepthChanged order book change event at the connector. In the handler of this event, we will check which security the received order book belongs to, and if it belongs to the security selected in SecurityPicker, we update MarketDepthControl with it. image4084.png We add the created MarketDepthControl panel to the central part of MainWindow. image7347.png At this stage, we can run the program and check the order book update operation. We create a buy and sell buttons click event handler. In each handler we create an Order, in which we specify the security selected in SecurityPicker, the portfolio selected in PortfolioComboBox, the volume and price from the corresponding SpinEdit. We register the order in Connector using the RegisterOrder method. image7717.png Both handlers differ only by the order direction. Let\u0027s make that the SpinEditPrice value is changed to the selected quote price when selecting a quote in the order book. To do this, we will create a handler for the SelectionChanged event at MarketDepthControl. In which we will update SpinEditPrice value by the price of the selected quote if the selected quote is not equal to zero image90.png We run the program to check. image8902.png Saving Market Data To save portfolios, securities, platforms, we need the CsvEntityRegistry class. We need to pass the entities storage location to it and call the Init method to load them. image7322.png To save candles, trades, etc., we will need StorageRegistry. image809.png We will also need the SnapshotRegistry snapshot storages registry. image4003.png All this we pass to Connector when it is created. image6704.png Here I also specified that Connector will reconnect when the connection is broken, and also specified how many history days should be downloaded. The Connector.LookupAll(); string queries the available data. image6016.png After starting the application, we will see that new folders have appeared in the Date folder. image7577.png And when reconnecting the security and portfolio panels will already be filled. Creating Strategy Panel I will create the strategy panel just like all previous panels. We add another UserControl to the XAML folder. We call it StrategyControl. We split the screen form into two parts using the LayoutControl. There will be a tab with a candle chart on the left side. image344.png As well as a tab with strategy statistics, image4907.png Here I use StatisticParameterGrid to display strategy statistics and EquityCurveChart to display profit and loss chart. In StatisticParameterGrid, we need to set some MaxHeight value, otherwise the application will not start. The strategy properties in PropertyGridEx will be configured on the right side. image721.png As well as strategy start and stop buttons. image1047.png Full code. image2510.png In the StrategyControl constructor, we set Connector as a data source for PropertyGridEx, we carried out similar actions in almost every control. image8773.png We need to somehow pass the strategy to our control. To do this, in StrategyControl I will create a BindStraregy method that will receive a strategy, save a link to it in the local variable, and also set a strategy in PropertyGridEx and StatisticParameterGrid. Using the SetChart method, we pass the Chart candle chart to the strategy, after that, the Chart can be obtained in the strategy using the GetChart method. We also set the Connector for the strategy. image8230.png When working with the profit and loss chart, it is necessary to take into account that the strategy may start and stop several times, so every time the strategy starts, the chart should be cleared. To do this, let\u0027s create the ResetEquityCurveChart method, in which we will first clear EquityCurveChart. After that we need to create graphic elements for EquityCurveChart, for them we can set a name, color and line type. image6360.png Then, we subscribe to the PnL change event of the strategy and in this event handler we draw a new value on the EquityCurveChart profit loss chart. image3106.png Full method code. image2024.png We will call this method in the Start button click event handler. And also we will reset the strategy state and run it. image3375.png We will stop the strategy in the Stop button click event handler. image3399.png We add the created StrategyControl panel to the central part of MainWindow. image8678.png Creating Strategy For example, let\u0027s consider creating a simple strategy with candles. Which will buy if the candle is growing (green), and sell if the candle is falling (red). Let\u0027s create another folder in the project and store all our strategies in it. We create a new class in this folder and call it SimpleStrategy. All S# strategies must be inherited from the base class Strategy. image1577.png Since our strategy uses candles, we will create a public property CandleSeries, and set its default value in our strategy constructor. image442.png Here I specified that candles in CandleSeries will be TimeFrameCandle with time span of 15 seconds (TimeSpan.FromSeconds(15)). We can specify the candle creating mode for CandleSeries - BuildCandlesMode. I specified that candles will be built (MarketDataBuildModes.Build), by default they will be built from ticks, but we can specify other data types as well. Since we made the CandleSeries a public property, the CandleSeries can be additionally configured from the PropertyGridEx described in the previous paragraph. All strategies have methods that can be overridden, we will need to override the OnStarted method. Which is called before the launch of the strategy and allows to preset its starting state. image6026.png Here we set the security for CandleSeries, which is specified in the PropertyGridEx. After that, we create a rule for processing the completed candle. See the documentation for details on working with rules. In the rule we specify the method that will process each completed candle, in our case it is the ProcessCandle method, it will be described later. After everything is set, we subscribe to the appearance of candles on the CandleSeries in connector using the SubscribeCandles method. In our case, the ProcessCandle method contains the main strategy logic. image3324.png First of all, we need to determine whether the candle is real-time or historical, if the candle is historical, we ignore it. Not all strategies require this, for example, for strategies based on order books, this is not required, since order books are always real-time. There is no general way to determine whether a candle is real-time or historical, and in each strategy this problem will have to be solved independently depending on the strategy requirements. In this case, I will simply compare the candle closing time with the connector time, and if it does not exceed a certain lag, then I consider the candle real-time. image2732.png Next, we consider what candle it is and what the strategy current position. If the candle is growing, then at a position equal to 0, we will open a position with a market order for the volume set by us in PropertyGridEx. If the candle is growing and the position is less than 0, we reverse the position. image4474.png We do opposite actions for a falling candle. image5127.png At the moment, our strategy is ready to work. It should be passed to SimpleStrategyControl, which we created in the previous paragraph using the BindStraregy method. We do this in the MainWindow constructor immediately after the MainWindow components are initialized. image374.png We run the program to check. image9399.png image5010.png The strategy works, trades are made, but there are no candles and trades on the chart yet. Adding Candles and Trades to Chart from Strategy In the paragraph about the strategy panel, we passed the Chart candle chart to the strategy using the SetChart method. In the OnStarted strategy method, we check whether the strategy has a chart set, and if it is set, then we initialize the chart, as well as subscribe to the events of new own trade appearance and candle change. image5547.png InitChart chart initialization method. image977.png Here we save the link to Chart in a local variable. We clear the chart. We also create chart elements for candles and trades and pass them to the chart. The chart.GuiSync(()=\u003e{ ... }); construct is necessary in order to initialize the chart in the main thread. CandleSeriesProcessing is a method for drawing candles on a chart. image9921.png Here we get a candle from the CandleSeriesProcessing event of the connector, create ChartDrawData to display it on the chart. We specify the time data.Group(candle.OpenTime), specify that the candle should be added to the candle element of the chart .Add(_chartCandleElement, candle);. And we specify that the chart should draw new data. We perform similar actions for trades. image4611.png We run the program to check. image944.png Short conclusion It is not necessary to spend a lot of time to create a complex and professional-looking application. In a few hours we created the fully-featured application with the ability to configure, display and trade directly. Do not be afraid to try and create your own programs. I hope this paper will help you get used to this business.
Hello, dear friend! As you already know, we launched the second stage of crowdfunding for the crypto connectors on March 1st. This time, we did everything in a new way, including with regard to algorithms. We will now provide algorithms without black boxes. All participants will be given strategies with source codes. To be the best in the market, unique settings are required for algorithms. Sometimes this is not possible without changing the code. We will be fully open to the supplied automation. In this article, we describe the algorithms set up especially for you. This is our technical assignment. We specifically provide complete information BEFORE you choose to participate. Synthetic arbitrage This idea is similar to our main crypto robot, Edward. Synthetic arbitrage is built on a long combination of BTC/ETH/LTC//ETH/BTC. Connectors to exchanges, where there are similar coins, are set for the strategy, and then it independently chooses the convergence-divergence on the found pairs to track the arbitrage situation. Edward-Crypto News For those who use Edward-Crypto (напиши нам по указанным ниже контактам, если хочешь получить и эту стратегию). За счет значительно продвинутой модели торговли у существующего Эдварда, для него синтетический арбитраж будет возможен с опцией автопоиска нужных пар. Н(write to us at the contacts specified below if you want to get this strategy). Due to the significantly advanced trade model of the existing Edward, synthetic arbitrage will be possible for it with the option of auto-searching for the necessary pairs. For example, BTC/*/LTC/*/LTC/ETH/BTС. The program will automatically select an effective coin as pairs to search for arbitrage divergence. This option will be available only to users of Edward-Crypto! Pump detector This is a special automation, tracking the growth of cheap coins with cosmic returns in a few hours. The robot can either monitor and generate a signal or actively enter the position and exit it after a certain movement to take profit. The robot will track all coins on all available connections. Of course, we are talking about very cheap alts, where you can increase your deposits 10 times a day. The main advantage of the algorithm is to get out in time, but the robot, of course, will be faster than our hands. Carrier It\u0027s very simple - the transfer of money from one exchange to another by the robot. Auto selection of the cheapest coin for transferring, for example, BTC positions through intermediate conversion to cheaper cryptocurrency, i.e. Vertcoin, Ripple, etc. Modularity The key point behind all of the strategies being developed is modularity! All of our strategies are run in unlimited quantities within the same program. Edward-Crypto will also act with new strategies, all in one bundle. The Converter will work, for example, in a pair with arbitrage strategies, watching for an increase in positions on certain exchanges. We hope that this ambitious change in the second round will be even more interesting for you! Have any questions? E-mail us at info@stocksharp.com and we will be happy to answer any of your questions. Do not put off the decision, just now one algorithm can be obtained for only 1000$, then the minimum investment will be doubled!!! Are you ready?
Recently, interest in crypto currencies has grown in leaps and bounds. New exchanges have opened, hard forks, ICO, new crypto-currencies are being created and this whole movement generates a huge sea of opportunities. One of these opportunities will be discussed in this short article. Not so long ago, we launched the crowdfunding project to create new connectors to 10 crypto-exchanges (Bitfinex, Coinbase, Kraken, Poloniex, GDAX, Bittrex, Bithumb, HitBTC, OKCoin, Coincheck), while the two connectors to Wex.nz and Bitstamp are already implemented in our platform. This project would not be needed if the currencies were traded more centrally, but the number of exchanges already exceeded a few dozen. More connectors, more stable trading, and more entry points for arbitrage bitcoins and other popular crypto currency. The target function of any exchange is to match buyers with sellers, but the price of an asset at which bidders are trying to make a deal can be different! Since the digital assets economy is just beginning, this difference can be very significant. This fact gives rise to the possibility of so-called arbitrage - to buy assets when they are cheaper and sell when they are more expensive. Let\u0027s see an example. The screenshots below of exchanges are further made at the same time. GDAX BTC order book: Gdax BTC BTC quoting by $7 313,88 price. For the same BTC on Wex.nz Wex BTC Same BTC but price already $7 373 Another exchange - Poloniex: Poloniex BTC BTC has a price of $7 323 No comments ;-) Join our shared campaign of creating new connectors and we will provide you with technical tools for arbitrage between exchanges (and, consequently, earnings on this strategy). Particularly important, we will provide an automated trading robot, which has already been performing arbitrage trading with Bitcoin for almost a year.
In our today\u0027s article, we will talk about where to go for free or for a relatively small amount of money to download historical data on the US market, as well as about a universal way to download, store, analyze and use in your own algorithms all types of market data. First, let\u0027s concern the main sources of market data on US securities with a brief description of them. In general, there are three types of sources: 1. Sources of historical data, such as exchanges, which provide trading history on their own sites (of course, we do not consider direct connections, which are of type 2). 2. Sources of market data, such as broker terminals, through which it is possible to download also some history, but the main interest is what is happening right now. 3. Multifunctional sources that combine the type 1 and type 2, and usually presented by specialized services. The first type of sources includes sites such as Google and Yahoo Finance: image002.gif The apparent advantage of these services is their full free, but on the other hand, it is impossible to download intraday market data, as well as impossible to get anything other than candles. By this we mean the data such as Level1, Order Log, Market Depth, etc. This practically eliminates the possibility of using the data for testing strategies involving the intraday trading. On the other hand, if your strategy assumes a medium-term trade, for example, based on the Turtle approach, or you practice portfolio investments without too frequent portfolio shake-up, then use of data from these sources to be very reasonable and appropriate. The sources of market data as already described above, are, primarily, broker terminals or other connections to the broker, which every practitioner trader has. For example: Fusion/Blackwood, Rithmic, Gain Capital, OEC Trader, Sterling, etc. image003.png Benefits from the use of this source can be seen almost immediately. First, it is free (of course excluding those fees that you pay to the broker). Second, it is large amount of data that can be obtained: some types of candles, ticks, Level1, DOM etc. On the downside, there are the lack of deep history and the need to collect the necessary data using cunning way, when it is nothing to do without specialized software. With this approach your capabilities for testing are greatly enhanced. There is a possibility to create not only intraday strategies, but also high-frequency algorithms based on historical regularities found. Multifunctional sources are mostly specialized services that provide a real-time market data as well as any requested history, for example IQFeed. image006.gif The main advantage of this source is its versatility and fullness of the data, i.e. at any time it is possible to get any desired data by the user’s request such as ticks, candles, order books etc. The downside of this approach is the payment for this service, the price of which starts from $50 per month for the basic version. If there is a desire to get a few more, it is necessary to connect the additional functions which, as you already understood, will cost money too. But like the previous option, you will need a special program to collect and store the data. Since, at the end of your subscription, you will lose all data. Plus, though the depth of history is more than at the previous method, but it is still limited. Especially for tick data. Now we can proceed to the most interesting, but how do we get the history optimally and do not spend a lot of money. In our opinion, the common approach is as follows: - to download the daily candles from a free source, and to test your strategy preliminary on these data; - to download intraday data through your broker, and to test the strategy in more detail; - the purchase of a subscription to a paid service, and downloading the data array of interest. In order to realize suchlike a specialized software will be necessary to download the required data from the required service for you first, and then it will continue to collect the data from your broker in a common format. Thus, the unity of data will not be lost and this data can be easily used for further analysis. For such tasks we have created the S#.Data (Hydra) program (to read the instruction manual and have a look at examples of use here). This is a free program available for download. Hydra provides a variety of functions, but its main task is to download and store the data. hydra_new.png Hydra supports downloading not only candles of any timeframe, but also ticks, order log, level 1, order books on a variety of instruments. The program can not only download but also store the data incoming from the broker, for example from OEC Trader, Sterling, etc. Hydra stores data in the CSV or BIN formats (super compact storage format – 7 bytes per 1 order book image or 2 bytes per tick). The data are located locally, like files, and they can be accessed from any programming language, that eventually allows the user to store and use a vast array of market data on a home computer, a server or in the cloud (AWS supported). Summing up the article, we hope that the techniques outlined in it will allow you to get the market data for adequate means and become a bit closer to the professional participants. They have long been doing just that. Good luck on the market!