Topics
10 Jan 2025, 14:20
 69
 2
27 Dec 2024, 21:31
 60
 1
27 Dec 2024, 21:31
 88
 3
26 Dec 2024, 14:35
 88
 4
26 Dec 2024, 00:08
 3
 74
 0
26 Dec 2024, 00:08
 2
 76
 0
25 Dec 2024, 18:35
 66
 2
23 Dec 2024, 18:41
 101
 5
22 Dec 2024, 21:30
 133
 4
20 Dec 2024, 18:10
 0
 58
 0
Replies

algobeginner
14 Jan 2025, 09:29

Number of shares ordered. This

represents the number of shares

for equities or based on normal

convention the number of

contracts for options, futures,

convertible bonds, etc. Maximum

precision is 0.01 (Prior to FIX 4.2

this field was of type int) - 

 

as far as I know all indices start from 0.10 and It’s also minimum value


 


@algobeginner

algobeginner
12 Jan 2025, 23:23 ( Updated at: 12 Jan 2025, 23:43 )

Update - lot cleaner , need work bodylenght ( 9 )

import Foundation

import Combine

 

class FIXClientViewModel: ObservableObject {

    @Published var connectionStatus: String = "Disconnected"

    @Published var receivedMessage: String = ""

    

    private var client: FIXClient?

    private var config: Config?

    

    init() {

        loadConfig()

    }

    

    func loadConfig() {

        guard let configURL = Bundle.main.url(forResource: "config", withExtension: "json") else {

            print("Config file not found.")

            return

        }

        

        do {

            let data = try Data(contentsOf: configURL)

            let config = try JSONDecoder().decode(Config.self, from: data)

            self.config = config

            setupClient()

        } catch {

            print("Error loading config: \(error)")

        }

    }

    

    func setupClient() {

        guard let config = config else {

            return

        }

        

        client = FIXClient(host: config.Host, port: config.Port, ssl: config.SSL)

        

        client?.setConnectedCallback { [weak self] in

            self?.connectionStatus = "Connected"

        }

        

        client?.setDisconnectedCallback { [weak self] error in

            self?.connectionStatus = error != nil ? "Disconnected" : "Error"

        }

        

        client?.setMessageReceivedCallback { [weak self] message in

            self?.receivedMessage = message.getMessage()

        }

    }

    

    func connectToServer() {

        client?.startService()

    }

    

    struct MessageField {

        let tag: Int

        let value: String

        

    }

 

    func sendLogonMessage() {

        guard let config = config else {

            return

        }

        

        let timestamp = getCurrentUTCTimestamp()

 

        // Define the fields in the correct order for the Logon message (35=A)

        let messageFields: [MessageField] = [

            MessageField(tag: 8, value: config.BeginString),   // 8=FIX.4.4 (BeginString)

            MessageField(tag: 9, value: ""),                   // 9=BodyLength (will be calculated)

            MessageField(tag: 35, value: "A"),                 // 35=A (Logon message type)

            MessageField(tag: 49, value: config.SenderCompID), // 49=SenderCompID (ID of the trading party)

            MessageField(tag: 56, value: config.TargetCompID), // 56=CSERVER (ID of the target component)

            MessageField(tag: 34, value: String(1)),           // 34=1 (MsgSeqNum, sequence number)

            MessageField(tag: 52, value: timestamp),                  // 52=SendingTime (will be set dynamically)

            MessageField(tag: 57, value: "QUOTE"),             // 57=TRADE (TargetSubID)

            MessageField(tag: 50, value: "Quote"),             // 50=Quote (SenderSubID)

            MessageField(tag: 98, value: "0"),                 // 98=0 (EncryptMethod, no encryption)

            MessageField(tag: 108, value: config.HeartBeat),               // 108=30 (Heartbeat interval)

            MessageField(tag: 141, value: "Y"),                // 141=Y (ResetSeqNumFlag)

            MessageField(tag: 553, value: config.Username),    // 553=Username (user ID)

            MessageField(tag: 554, value: config.Password),    // 554=Password (user password)

            MessageField(tag: 10, value: "")                   // 10=Checksum (calculated later)

        ]

        // Create the FIX message object

        var logonMessage = FIXMessage()

 

        // Add fields to the FIX message in the defined order, excluding 9 and 10 for now

        for field in messageFields {

            logonMessage.setField(field.tag, field.value)

        }

 

        // Dynamically set the SendingTime (52) to the current UTC timestamp

        let currentTime = getCurrentUTCTimestamp()

        logonMessage.setField(52, currentTime)  // Set SendingTime (52)

 

        // Now, calculate the message body length (excluding the BodyLength itself, i.e., excluding tag 9)

        let messageString = logonMessage.getMessage()

 

        // Calculate the message length (excluding the BodyLength field itself)

        let messageLength = messageString.count + 1 // Include the Message Length field itself (9)

        let messageLengthString = String(messageLength)

 

        // Now, set the '9' field (BodyLength) in the second position

        logonMessage.setField(9, messageLengthString)  // Add BodyLength as second field

 

        // Calculate checksum (tag 10)

        let checksum = calculateChecksum(for: messageString)

 

        // Set the '10' field with the calculated checksum as the last field

        logonMessage.setField(10, checksum)  // Add checksum at the end of the message

        

        // Generate the fixed-format message string

        let fixedFormatMessage = logonMessage.getMessage()

 

        // Debugging: print the logon message in fixed format

        print("Logon Message (Fixed Format): \(fixedFormatMessage)")

 

        // Send the logon message

        client?.send(logonMessage)

    }

 

            }

    

    // Function to get the current UTC timestamp in the required format (yyyyMMdd-HH:mm:ss)

    func getCurrentUTCTimestamp() -> String {

        let dateFormatter = DateFormatter()

        dateFormatter.dateFormat = "yyyyMMdd-HH:mm:ss"

        dateFormatter.timeZone = TimeZone(abbreviation: "UTC")  // Set the timezone to UTC

        let date = Date()

        return dateFormatter.string(from: date)

        

        

    }

 

    // Example checksum calculation function (you will need to implement this based on your specific needs)

    func calculateChecksum(for message: String) -> String {

        let checksum = message.reduce(0) { $0 + Int($1.asciiValue ?? 0) }

        return String(checksum % 256)

    }

 

    

 

 

 

 

 

 

 

 


 


@algobeginner

algobeginner
11 Jan 2025, 21:22

Swift code in IDE 

import Cocoa

import Foundation

import Network

 

// Configuration for FIX API

struct FIXConfig {

    var Host: String

    var Port: Int

    var SSL: Bool

    var Username: String

    var Password: String

    var BeginString: String

    var SenderCompID: String

    var SenderSubID: String

    var TargetCompID: String

    var TargetSubID: String

    var HeartBeat: Int

}

 

// Get current timestamp in FIX-compatible format

func getCurrentTimestamp() -> String {

    let dateFormatter = DateFormatter()

    dateFormatter.dateFormat = "yyyyMMdd-HH:mm:ss"

    return dateFormatter.string(from: Date())

}

 

// Calculate the checksum for the message (FIX requires it for integrity)

func generateChecksum(for message: String) -> String {

    let messageBytes = [UInt8](message.utf8)

    let checksum = messageBytes.reduce(0, { $0 + Int($1) }) % 256

    return String(format: "%03d", checksum)

}

 

// Function to handle connection and sending logon message

func connectToServer(config: FIXConfig) -> NWConnection {

    let host = NWEndpoint.Host(config.Host)

    let port = NWEndpoint.Port(integerLiteral: UInt16(config.Port))

    

    let connection = NWConnection(host: host, port: port, using: .tcp)

    

    connection.stateUpdateHandler = { state in

        switch state {

        case .ready:

            print("Connection established. Sending Logon message...")

            sendLogonMessage(connection: connection, config: config)

        case .failed(let error):

            print("Connection failed with error: \(error)")

        default:

            break

        }

    }

    

    connection.start(queue: .global())

    

    return connection

}

 

// Function to send Logon Message

func sendLogonMessage(connection: NWConnection, config: FIXConfig) {

    var logonMessage = """

    8=\(config.BeginString)\u{1}35=A\u{1}49=\(config.SenderCompID)\u{1}56=\(config.TargetCompID)\u{1}34=1\u{1}52=\(getCurrentTimestamp())\u{1}108=\(config.HeartBeat)\u{1}

    """

    

    let checksum = generateChecksum(for: logonMessage)

    logonMessage.append("10=\(checksum)\u{1}")

    

    print("Sending logon message: \(logonMessage)")  // Log the message

    

    let data = Data(logonMessage.utf8)

    

    connection.send(content: data, completion: .contentProcessed({ error in

        if let error = error {

            print("Error sending logon message: \(error)")

        } else {

            print("Logon message sent successfully.")

            requestMarketData(connection: connection, config: config)

        }

    }))

    

    // Start listening for messages after sending logon

    listenForMessages(connection: connection)

}

 

// Function to send Market Data Request for EUR/USD

func requestMarketData(connection: NWConnection, config: FIXConfig) {

    let mdReqID = "EURUSD_MarketData"

    let subscriptionRequestType = "1" // Snapshot + Updates

    let marketDepth = "1" // Top of book

    let noMDEntryTypes = "1" // Number of MD Entry Types

    let mdEntryType = "0" // Bid

    let noRelatedSym = "1" // Number of related symbols

    let symbol = "1" // EUR/USD symbol

    let mdUpdateType = "0" // Full refresh

    

    var marketDataRequest = """

    8=\(config.BeginString)\u{1}35=V\u{1}49=\(config.SenderCompID)\u{1}56=\(config.TargetCompID)\u{1}34=2\u{1}52=\(getCurrentTimestamp())\u{1}262=\(mdReqID)\u{1}

    263=\(subscriptionRequestType)\u{1}264=\(marketDepth)\u{1}265=\(noMDEntryTypes)\u{1}269=\(mdEntryType)\u{1}146=\(noRelatedSym)\u{1}55=\(symbol)\u{1}

    265=\(mdUpdateType)\u{1}

    """

    

    let checksum = generateChecksum(for: marketDataRequest)

    marketDataRequest.append("10=\(checksum)\u{1}")

    

    print("Sending market data request: \(marketDataRequest)")  // Log the message

    

    let data = Data(marketDataRequest.utf8)

    

    connection.send(content: data, completion: .contentProcessed({ error in

        if let error = error {

            print("Error sending market data request: \(error)")

        } else {

            print("Market data request sent successfully.")

        }

    }))

}

 

// Listen for incoming messages and handle logon acknowledgment or market data responses

func listenForMessages(connection: NWConnection) {

    connection.receive(minimumIncompleteLength: 1, maximumLength: 1024) { (data, context, isComplete, error) in

        if let data = data {

            let receivedMessage = String(decoding: data, as: UTF8.self)

            print("Raw received message: \(receivedMessage)")  // Log the raw message

            

            // Print raw bytes

            print("Raw bytes: \(data.map { String(format: "%02x", $0) }.joined(separator: " "))")

 

            

            // Debug: Check if we're receiving an empty message

            if data.isEmpty {

                print("Received an empty message. Waiting for more data...")

            }

            

            // Handle the different message types (A = Logon, V = Market Data)

            let messageType = receivedMessage.split(separator: "\u{1}").first { $0.hasPrefix("35=") }?.split(separator: "=").last ?? ""

            

            if messageType == "A" {

                // Logon acknowledgment received

                print("Logon acknowledgment received!")

                // Now, you can send the market data request here if you haven't yet

            } else if messageType == "V" {

                // Market Data response (Type V)

                print("Received Market Data Update")

                processMarketDataUpdate(receivedMessage)

            } else {

                print("Received unhandled message: \(receivedMessage)")

            }

        }

        

        // Handle when the connection is complete or encounters an error

        if isComplete {

            connection.cancel()

            print("Connection closed.")

        } else if let error = error {

            print("Error receiving message: \(error)")

            connection.cancel()

        } else {

            // Continue listening for more messages

            listenForMessages(connection: connection)

        }

    }

}

 

 

 

// Example: Process Market Data Update

func processMarketDataUpdate(_ message: String) {

    // Print and process the market data response

    print("Processing Market Data Update: \(message)")

    

    // Example: You can extract the bid/ask data from the message.

    // You will need to adjust parsing according to your FIX message format.

    let messageParts = message.split(separator: "\u{1}") // Split by the ASCII delimiter

    for part in messageParts {

        print("Part: \(part)") // Print each part of the response message

    }

}

 

 

// macOS ViewController

class ViewController: NSViewController {

    

    let fixSessionManager = FIXSessionManager()

 

    override func viewDidLoad() {

        super.viewDidLoad()

        

        // Start FIX session after the view is loaded

        fixSessionManager.startFIXSession()

    }

}

 

config 

class FIXSessionManager {

    

    func startFIXSession() {

        let config = FIXConfig(

            Host: "demo-uk-eqx-02.p.ctrader.com",

            Port: 5201,

            SSL: false,

            Username: "1111111",

            Password: "password",

            BeginString: "FIX.4.4",

            SenderCompID: "demo.ctrader.1111111",

            SenderSubID: "QUOTE",

            TargetCompID: "cServer",

            TargetSubID: "QUOTE",

            HeartBeat: 30

        )

        

        let connection = connectToServer(config: config)

        listenForMessages(connection: connection)

    }

}
 

 

still no response from server , any idea how to get this working , I tried this PythonKit but its so buggy it won't load even after environment creation for Python and Hardened Runtime disabled  Library Validation .

 

Yes I tried, googling , AI , but no solution .

 


@algobeginner

algobeginner
06 Jan 2025, 00:09

RE: Price predictions in calgo bot ?

PanagiotisCharalampous said: 

Hi there,

This example uses the built in Linear Regression Forecast which is based on a formula.

Best regards,

Panagiotis

So to use of learned Linear Regression model for forecast should be  in separate app through API market data feed , or is there some library which allows to import trained model to perform this inside calgo bot ? 


@algobeginner

algobeginner
31 Dec 2024, 16:45 ( Updated at: 02 Jan 2025, 07:06 )

RE: RE: RE: CSV Export and Load

PanagiotisCharalampous said: 

algobeginner said: 

PanagiotisCharalampous said: 

Hi there,

Please share a screenshot of the exported data so that we can check.

Best regards,

Panagiotis

Hi there,

Did you try removing the header. I don't think it is necessary.

Best regards,

Panagiotis

Yes I did try and then it nothing happens . ( I mean the test doesn't start ) 

 

Also I have noticed if I try open External Process for CBot the Ctrader crash itself . 


@algobeginner

algobeginner
31 Dec 2024, 10:56 ( Updated at: 02 Jan 2025, 07:06 )

https://clickalgo.com/risk-reward-mac-free can be found here 


@algobeginner

algobeginner
31 Dec 2024, 00:00

do you get any warnings about obsolete   when you compile code on Mac ?


@algobeginner

algobeginner
30 Dec 2024, 10:31 ( Updated at: 30 Dec 2024, 10:41 )

RE: Price predictions in calgo bot ?

PanagiotisCharalampous said: 

Hi there,

Can you please explain which example you are referring to?

Best regards,

Panagiotis

it using indicator LinearRegressionForecast _ which I'm wonder if is trained model as name would suggest from Machine Learning ,or just some formula do calculations based on median's of source  ?

if this utilise trained model could we somehow import our own model from MLX into Bot to improve accuracy for specific pair   ? 

Ctrader heavy load CPU during optimisation but it have lot of spare computing power on GPU left so it could use it .

This example code :  → 
using cAlgo.API;

using cAlgo.API.Indicators;

using cAlgo.API.Internals;


 

namespace cAlgo.Robots

{

[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]

public class LinearRegressionForecastSample : Robot

{

private double _volumeInUnits;


 

private LinearRegressionForecast _linearRegressionForecast;


 

[Parameter("Volume (Lots)", DefaultValue = 0.01)]

public double VolumeInLots { get; set; }


 

[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]

public double StopLossInPips { get; set; }


 

[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]

public double TakeProfitInPips { get; set; }


 

[Parameter("Label", DefaultValue = "LinearRegressionForecastSample")]

public string Label { get; set; }


 

[Parameter("Source", Group = "Linear Regression Forecast")]

public DataSeries Source { get; set; }


 

[Parameter("Periods", DefaultValue = 9, Group = "Linear Regression Forecast", MinValue = 0)]

public int Periods { get; set; }



 

public Position[] BotPositions

{

get

{

return Positions.FindAll(Label);

}

}


 

protected override void OnStart()

{

_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);


 

_linearRegressionForecast = Indicators.LinearRegressionForecast(Source, Periods);

}


 

protected override void OnBarClosed()

{

if (Bars.ClosePrices.Last(0) > _linearRegressionForecast.Result.Last(0) && Bars.ClosePrices.Last(1) <= _linearRegressionForecast.Result.Last(1))

{

ClosePositions(TradeType.Sell);


 

ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);

}

else if (Bars.ClosePrices.Last(0) < _linearRegressionForecast.Result.Last(0) && Bars.ClosePrices.Last(1) >= _linearRegressionForecast.Result.Last(1))

{

ClosePositions(TradeType.Buy);


 

ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);

}

}


 

private void ClosePositions(TradeType tradeType)

{

foreach (var position in BotPositions)

{

if (position.TradeType != tradeType) continue;


 

ClosePosition(position);

}

}

}

}


@algobeginner

algobeginner
28 Dec 2024, 20:12

RE: Optimisation Mac vs Windows

PanagiotisCharalampous said: 

Hi there,

It seems you are using the genetic algorithm for optimization. In this case passes will be different even between subsequent optimization on the same machine.

Best regards,

Panagiotis

Yes it’s genetic , is grid more precise ?


@algobeginner

algobeginner
28 Dec 2024, 10:48

RE: Stop loss retry

firemyst said: 

How do you know it's not an issue with your code that the SL and TP aren't being set?

Why don't you post a sample of the code that reproduces the issue so people can have a look?

 { protected override void OnStart()

 { Positions.Opened += Positions_Opened; } private void Positions_Opened(PositionOpenedEventArgs obj) { 

if(obj.Position.StopLoss == null) 

}
 

 this seem to be answer a little bit obsolete, if this could be directly checked upon execution but that probably down the async 😌


@algobeginner

algobeginner
28 Dec 2024, 10:23

RE: Stop loss retry

firemyst said: 

How do you know it's not an issue with your code that the SL and TP aren't being set?

Why don't you post a sample of the code that reproduces the issue so people can have a look?

Thanks for advice , but I doubt the code is issue as it occurs only on certain dates across different trading brokers .

came cross this on bar logics , basic three white soldiers , sma .

if it’s necessary I post codes but it’s stock version with optimised parameters . 
 

the purpose of the question is if there is method to verify if during market order the stop loss can’t be set to prevent from open .


@algobeginner

algobeginner
27 Dec 2024, 14:30

RE: CSV Export and Load

PanagiotisCharalampous said: 

Hi there,

Please share a screenshot of the exported data so that we can check.

Best regards,

Panagiotis


@algobeginner

algobeginner
25 Dec 2024, 23:06

Mac

@algobeginner

algobeginner
25 Dec 2024, 23:05 ( Updated at: 25 Dec 2024, 23:07 )

Mac

@algobeginner

algobeginner
25 Dec 2024, 23:05

Mac

@algobeginner

algobeginner
25 Dec 2024, 18:35

I wonder if there is method to to run a optimisation  for year or all available data , and get things like best fitness and parameters for each month or day as result instead of pass numbers ? 
 

I see option save Optimisations but all this does is save all passes with numbers and 4 files . 


@algobeginner

algobeginner
24 Dec 2024, 16:17

How about use your own historical data to emulate this factor ?


@algobeginner

algobeginner
24 Dec 2024, 11:19

RE: IDE for CTrader

PanagiotisCharalampous said: 

Hi there,

The source code for cTrader is not available since cTrader is not an open source project. 

Best regards,

Panagiotis

What IDE would you recommend for beginner to see all possible combinations of var and strings ? 

especially I'm interested to discover Bars Reverses ,  to reduce computing time and identify breaks more often without use of indicators .

Would this works ? 

Aggregation:

Average(): Computes the average of a sequence of numeric values.
Sum(): Computes the sum of a sequence of numeric values.
Max(): Returns the maximum value in a sequence.
Min(): Returns the minimum value in a sequence.
Filtering:

Where(): Filters a sequence of values based on a predicate.
Ordering:

OrderBy(): Sorts the elements of a sequence in ascending order.
OrderByDescending(): Sorts the elements of a sequence in descending order.

 


@algobeginner

algobeginner
24 Dec 2024, 11:19

RE: IDE for CTrader

PanagiotisCharalampous said: 

Hi there,

The source code for cTrader is not available since cTrader is not an open source project. 

Best regards,

Panagiotis

What IDE would you recommend for beginner to see all possible combinations of var and strings ? 

especially I'm interested to discover Bars Reverses ,  to reduce computing time and identify breaks more often without use of indicators .

Would this works ? 

Aggregation:

Average(): Computes the average of a sequence of numeric values.
Sum(): Computes the sum of a sequence of numeric values.
Max(): Returns the maximum value in a sequence.
Min(): Returns the minimum value in a sequence.
Filtering:

Where(): Filters a sequence of values based on a predicate.
Ordering:

OrderBy(): Sorts the elements of a sequence in ascending order.
OrderByDescending(): Sorts the elements of a sequence in descending order.

 


@algobeginner