Giter Club home page Giter Club logo

tradeinator's Introduction

Tradeinator

This is a project i have been wanting to work on for a while.

The aim of the project is to provide a modular approach to developing algorithmic trading systems.

The project utilises an event driven architecture and uses RabbitMQ as the message bus.

The use of an event driven architecture provides a modular approach to the system allowing me to add/remove/edit modules and strategies without having to stop and restart other systems

For stock indicators the following library is used: https://github.com/ooples/OoplesFinance.StockIndicators

Strategy Research

Most of the strategy research is done on TradingView using Pinescript and then transferred to C#.

Topics

Event topics should follow the general format of {action}.{symbol}

eg. bar.AAPL is the topic for a new Apple bar

Adding new symbols

To add new symbols without having to stop and restart the system a file watcher is implemented using the .net file system watcher the symbols.txt file in the stocks/crypto DataIngestion project is watched. The system has a file watcher registered to this file, when the file changes symbol subscriptions are added or removed

Improvements

  • strategy init message
  • change console programs to worker services?
  • add systemd service files to each project that can be easily copied
  • solution level config file or a project that contains the config files and a class to load them [DONE]

Configuration

All config files are located in the Tradeinator.Configuration project.

This provides a central place for all config files and reduces the need to duplicate them across projects

The configuration is loaded as an IConfiguration from Microsoft.Extensions.Configuration and loads everything from the appsettings.json file and .env file

Configuration files are copied to the build directory.

An example of using the config loader

using Tradeinator.Configuration;

// config is loaded
var config = new ConfigurationLoader();

// config can be accessed using indexing
config["Rabbit:Host"]; // will return the host from the appsettings.json file

// or with the .Get(string key) method
config.Get("Rabbit:Host"); // will return the same value as the index call

Tradeinator.Listener

Provides a simple example of registering to an topic and consuming data

Tradeinator.Backtester

Provides a framework for quickly backtesting strategies using a forked version of the SimpleBackTestLib library

Strategies inherit from the BacktestRunner abstract class and must have the BacktestStrategyMetadata attribute added for it to be discoverable. The meta data attribute defines some properties of the strategy such as it's name and budget.

When running the backtest the assembly is scanned for all classes that have the attribute applied. Options are then displayed allowing you to select which backtest to run (see image below)

Spectre.Console is used to pretty print options to the console

Improvements

  • update to use a sqlite database to load data from rather than reading from csv files
  • provide utility functionality to load data from csv into database
  • provide options to select a data source rather then passing as cli argument

Tradeinator.Dashboard

A blazor server web application built with the Microsofts Fluent UI.

Will provides a dashboard showing account balances, trades and more

Tradeinator.EventTester

A Terminal GUI program to connect to the exchange and easily send test events event tester demo image Built with the Terminal.Gui library

Tradeniator.Database

This class library contains the EntityFramework DbContext and related migrations for a MySQL database.

The project also contains a design time factory so the EF migration command can be run from the project directly

Database connection is defined in the Tradeinator.Configuration project

cd Tradeinator.Database/
dotnet ef database update

Tradeinator.DataIngestion.Shared

Contains the implementation of the file watching and subscription management

Tradeinator.DataIngestion.Crypto

This is the entry point for all crypto data into the system.

Data is fetched from alpaca through a web socket conenction. Currently websockets subscribe to a 1m bar granularity, this will be updated in future.

Symbols to subscribe to are registered in the projects symbols.txt file

Tradeinator.DataIngestion.Stocks

This is the entry point for all stock data into the system.

Data is fetched from alpaca through a web socket conenction. Currently websockets subscribe to a 1m bar granularity, this will be updated in future.

Symbols to subscribe to are registered in the projects symbols.txt file

Tradeinator.DataIngestion.Forex

This is the entry point for all forex data into the system.

Data is fetched from Oanda, currently only 30 minute bars are supported.

Symbols to subscribe to are registered in the projects symbols.txt file

Tradeinator.Shared

This project provides shared classes for the solution, such as the RabbitMQ exchange implementations and some generic models

Tradeniator.Strategy.Shared

This class library contains the meat of the strategies. It provides a base class called StrategyBase that all strategies must inherit from. Strategies are run by creating a new StrategyBuilder and adding the the required properties. When the Build method is called, the builder will fetch the strategies from the database and deserialise them into the provided strategy type

Creating a strategy

create a new project and add a reference to the Tradeniator.Strategy.Shared and Tradeniator.Shared projects then in your Program.cs file copy the following example. As reference the StrategyImplementingType type is the name of the class that inherits from StrategyBase and implements the required methods. This should be changed to the name of your class.

// A readable ID that denotes this group of strategies
// used for filtering your strategies in the dashboard and registering events
const string StrategySlug = "StrategyGroupName";

// load config from appsettings.json and .env files
var configLoader = new ConfigurationLoader();

var apiToken = configLoader.Get("OANDA_API_TOKEN");
var exchangeHost = configLoader.Get("Rabbit:Host");
var exchangeName = configLoader.Get("Rabbit:Exchange");
var connectionString = configLoader.Get("ConnectionStrings:DbConnection");

if (ValidateNotNull(apiToken))
{
    Console.WriteLine("[ERROR] Oanda api token was null or empty");
    return;
}

if (ValidateNotNull(exchangeHost, exchangeName))
{
    Console.WriteLine("[ERROR] exchange host or name was null");
    return;
}

if (ValidateNotNull(connectionString))
{
    Console.WriteLine("[ERROR] db connection string was null");
    return;
}

// serilog logger
await using var logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("general.log")
    .CreateLogger();


var tokenSource = new CancellationTokenSource();
Console.CancelKeyPress += (sender, eventArgs) =>
{
    logger.Information("Cancel requested");
    tokenSource.Cancel();
};


// setup exchange
using var exchange = new PublisherReceiverExchange(
    exchangeHost, exchangeName,
    "bar.AUD/CHF"
);


var strategies = new StrategyBuilder<StrategyImplementingType>(connectionString, logger)
    .WithSlug(StrategySlug) // the slug of the strategy
    .WithExchange(exchange) // will register a listener to consume change events
    .WithMessageNotificationCallback(OnSendMessageNotification) // register a callback for the send message notification event
    .WithDefaultStrategy(new StrategyImplementingType()) // register default strategy
    .Build();

// calls the Init method on all the strategies
// the init method will provide a configuration to the strategy so environment and appsettings variables can be loaded
await strategies.Init(); 

logger.Information("Initialising strategies");
logger.Information("initialised");


logger.Information("Exchange starting");
await exchange.StartConsuming(tokenSource.Token);
logger.Information("Exchange stopped");


return;


void OnSendMessageNotification(object? sender, SystemMessageEventArgs e)
{
    var message = e.Message;
    exchange.Publish(message, $"notification.{message.Symbol}");
}

bool ValidateNotNull(params string?[] values) => values.Any(string.IsNullOrEmpty);

Tradeinator.Notifications

This project implements a notification system using a discord bot, it listens to all events with the notification.* topic and publishes the events to discord.

A notification is the Tradeinator.Shared.SystemMessage class. When the SystemMessages priority is Critical then the notification will add an @everyone mention


Tradeinator.Logger

This project is not currently implemented

This project will subscribe to all order events (topic key: order.*) and log them to a database

tradeinator's People

Contributors

zed-bailey avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.